podman

Форк
0
653 строки · 16.2 Кб
1
package sprig
2

3
import (
4
	"bytes"
5
	"crypto"
6
	"crypto/aes"
7
	"crypto/cipher"
8
	"crypto/dsa"
9
	"crypto/ecdsa"
10
	"crypto/ed25519"
11
	"crypto/elliptic"
12
	"crypto/hmac"
13
	"crypto/rand"
14
	"crypto/rsa"
15
	"crypto/sha1"
16
	"crypto/sha256"
17
	"crypto/x509"
18
	"crypto/x509/pkix"
19
	"encoding/asn1"
20
	"encoding/base64"
21
	"encoding/binary"
22
	"encoding/hex"
23
	"encoding/pem"
24
	"errors"
25
	"fmt"
26
	"hash/adler32"
27
	"io"
28
	"math/big"
29
	"net"
30
	"time"
31

32
	"strings"
33

34
	"github.com/google/uuid"
35
	bcrypt_lib "golang.org/x/crypto/bcrypt"
36
	"golang.org/x/crypto/scrypt"
37
)
38

39
func sha256sum(input string) string {
40
	hash := sha256.Sum256([]byte(input))
41
	return hex.EncodeToString(hash[:])
42
}
43

44
func sha1sum(input string) string {
45
	hash := sha1.Sum([]byte(input))
46
	return hex.EncodeToString(hash[:])
47
}
48

49
func adler32sum(input string) string {
50
	hash := adler32.Checksum([]byte(input))
51
	return fmt.Sprintf("%d", hash)
52
}
53

54
func bcrypt(input string) string {
55
	hash, err := bcrypt_lib.GenerateFromPassword([]byte(input), bcrypt_lib.DefaultCost)
56
	if err != nil {
57
		return fmt.Sprintf("failed to encrypt string with bcrypt: %s", err)
58
	}
59

60
	return string(hash)
61
}
62

63
func htpasswd(username string, password string) string {
64
	if strings.Contains(username, ":") {
65
		return fmt.Sprintf("invalid username: %s", username)
66
	}
67
	return fmt.Sprintf("%s:%s", username, bcrypt(password))
68
}
69

70
func randBytes(count int) (string, error) {
71
	buf := make([]byte, count)
72
	if _, err := rand.Read(buf); err != nil {
73
		return "", err
74
	}
75
	return base64.StdEncoding.EncodeToString(buf), nil
76
}
77

78
// uuidv4 provides a safe and secure UUID v4 implementation
79
func uuidv4() string {
80
	return uuid.New().String()
81
}
82

83
var masterPasswordSeed = "com.lyndir.masterpassword"
84

85
var passwordTypeTemplates = map[string][][]byte{
86
	"maximum": {[]byte("anoxxxxxxxxxxxxxxxxx"), []byte("axxxxxxxxxxxxxxxxxno")},
87
	"long": {[]byte("CvcvnoCvcvCvcv"), []byte("CvcvCvcvnoCvcv"), []byte("CvcvCvcvCvcvno"), []byte("CvccnoCvcvCvcv"), []byte("CvccCvcvnoCvcv"),
88
		[]byte("CvccCvcvCvcvno"), []byte("CvcvnoCvccCvcv"), []byte("CvcvCvccnoCvcv"), []byte("CvcvCvccCvcvno"), []byte("CvcvnoCvcvCvcc"),
89
		[]byte("CvcvCvcvnoCvcc"), []byte("CvcvCvcvCvccno"), []byte("CvccnoCvccCvcv"), []byte("CvccCvccnoCvcv"), []byte("CvccCvccCvcvno"),
90
		[]byte("CvcvnoCvccCvcc"), []byte("CvcvCvccnoCvcc"), []byte("CvcvCvccCvccno"), []byte("CvccnoCvcvCvcc"), []byte("CvccCvcvnoCvcc"),
91
		[]byte("CvccCvcvCvccno")},
92
	"medium": {[]byte("CvcnoCvc"), []byte("CvcCvcno")},
93
	"short":  {[]byte("Cvcn")},
94
	"basic":  {[]byte("aaanaaan"), []byte("aannaaan"), []byte("aaannaaa")},
95
	"pin":    {[]byte("nnnn")},
96
}
97

98
var templateCharacters = map[byte]string{
99
	'V': "AEIOU",
100
	'C': "BCDFGHJKLMNPQRSTVWXYZ",
101
	'v': "aeiou",
102
	'c': "bcdfghjklmnpqrstvwxyz",
103
	'A': "AEIOUBCDFGHJKLMNPQRSTVWXYZ",
104
	'a': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz",
105
	'n': "0123456789",
106
	'o': "@&%?,=[]_:-+*$#!'^~;()/.",
107
	'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()",
108
}
109

110
func derivePassword(counter uint32, passwordType, password, user, site string) string {
111
	var templates = passwordTypeTemplates[passwordType]
112
	if templates == nil {
113
		return fmt.Sprintf("cannot find password template %s", passwordType)
114
	}
115

116
	var buffer bytes.Buffer
117
	buffer.WriteString(masterPasswordSeed)
118
	binary.Write(&buffer, binary.BigEndian, uint32(len(user)))
119
	buffer.WriteString(user)
120

121
	salt := buffer.Bytes()
122
	key, err := scrypt.Key([]byte(password), salt, 32768, 8, 2, 64)
123
	if err != nil {
124
		return fmt.Sprintf("failed to derive password: %s", err)
125
	}
126

127
	buffer.Truncate(len(masterPasswordSeed))
128
	binary.Write(&buffer, binary.BigEndian, uint32(len(site)))
129
	buffer.WriteString(site)
130
	binary.Write(&buffer, binary.BigEndian, counter)
131

132
	var hmacv = hmac.New(sha256.New, key)
133
	hmacv.Write(buffer.Bytes())
134
	var seed = hmacv.Sum(nil)
135
	var temp = templates[int(seed[0])%len(templates)]
136

137
	buffer.Truncate(0)
138
	for i, element := range temp {
139
		passChars := templateCharacters[element]
140
		passChar := passChars[int(seed[i+1])%len(passChars)]
141
		buffer.WriteByte(passChar)
142
	}
143

144
	return buffer.String()
145
}
146

147
func generatePrivateKey(typ string) string {
148
	var priv interface{}
149
	var err error
150
	switch typ {
151
	case "", "rsa":
152
		// good enough for government work
153
		priv, err = rsa.GenerateKey(rand.Reader, 4096)
154
	case "dsa":
155
		key := new(dsa.PrivateKey)
156
		// again, good enough for government work
157
		if err = dsa.GenerateParameters(&key.Parameters, rand.Reader, dsa.L2048N256); err != nil {
158
			return fmt.Sprintf("failed to generate dsa params: %s", err)
159
		}
160
		err = dsa.GenerateKey(key, rand.Reader)
161
		priv = key
162
	case "ecdsa":
163
		// again, good enough for government work
164
		priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
165
	case "ed25519":
166
		_, priv, err = ed25519.GenerateKey(rand.Reader)
167
	default:
168
		return "Unknown type " + typ
169
	}
170
	if err != nil {
171
		return fmt.Sprintf("failed to generate private key: %s", err)
172
	}
173

174
	return string(pem.EncodeToMemory(pemBlockForKey(priv)))
175
}
176

177
// DSAKeyFormat stores the format for DSA keys.
178
// Used by pemBlockForKey
179
type DSAKeyFormat struct {
180
	Version       int
181
	P, Q, G, Y, X *big.Int
182
}
183

184
func pemBlockForKey(priv interface{}) *pem.Block {
185
	switch k := priv.(type) {
186
	case *rsa.PrivateKey:
187
		return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
188
	case *dsa.PrivateKey:
189
		val := DSAKeyFormat{
190
			P: k.P, Q: k.Q, G: k.G,
191
			Y: k.Y, X: k.X,
192
		}
193
		bytes, _ := asn1.Marshal(val)
194
		return &pem.Block{Type: "DSA PRIVATE KEY", Bytes: bytes}
195
	case *ecdsa.PrivateKey:
196
		b, _ := x509.MarshalECPrivateKey(k)
197
		return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
198
	default:
199
		// attempt PKCS#8 format for all other keys
200
		b, err := x509.MarshalPKCS8PrivateKey(k)
201
		if err != nil {
202
			return nil
203
		}
204
		return &pem.Block{Type: "PRIVATE KEY", Bytes: b}
205
	}
206
}
207

208
func parsePrivateKeyPEM(pemBlock string) (crypto.PrivateKey, error) {
209
	block, _ := pem.Decode([]byte(pemBlock))
210
	if block == nil {
211
		return nil, errors.New("no PEM data in input")
212
	}
213

214
	if block.Type == "PRIVATE KEY" {
215
		priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)
216
		if err != nil {
217
			return nil, fmt.Errorf("decoding PEM as PKCS#8: %s", err)
218
		}
219
		return priv, nil
220
	} else if !strings.HasSuffix(block.Type, " PRIVATE KEY") {
221
		return nil, fmt.Errorf("no private key data in PEM block of type %s", block.Type)
222
	}
223

224
	switch block.Type[:len(block.Type)-12] { // strip " PRIVATE KEY"
225
	case "RSA":
226
		priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
227
		if err != nil {
228
			return nil, fmt.Errorf("parsing RSA private key from PEM: %s", err)
229
		}
230
		return priv, nil
231
	case "EC":
232
		priv, err := x509.ParseECPrivateKey(block.Bytes)
233
		if err != nil {
234
			return nil, fmt.Errorf("parsing EC private key from PEM: %s", err)
235
		}
236
		return priv, nil
237
	case "DSA":
238
		var k DSAKeyFormat
239
		_, err := asn1.Unmarshal(block.Bytes, &k)
240
		if err != nil {
241
			return nil, fmt.Errorf("parsing DSA private key from PEM: %s", err)
242
		}
243
		priv := &dsa.PrivateKey{
244
			PublicKey: dsa.PublicKey{
245
				Parameters: dsa.Parameters{
246
					P: k.P, Q: k.Q, G: k.G,
247
				},
248
				Y: k.Y,
249
			},
250
			X: k.X,
251
		}
252
		return priv, nil
253
	default:
254
		return nil, fmt.Errorf("invalid private key type %s", block.Type)
255
	}
256
}
257

258
func getPublicKey(priv crypto.PrivateKey) (crypto.PublicKey, error) {
259
	switch k := priv.(type) {
260
	case interface{ Public() crypto.PublicKey }:
261
		return k.Public(), nil
262
	case *dsa.PrivateKey:
263
		return &k.PublicKey, nil
264
	default:
265
		return nil, fmt.Errorf("unable to get public key for type %T", priv)
266
	}
267
}
268

269
type certificate struct {
270
	Cert string
271
	Key  string
272
}
273

274
func buildCustomCertificate(b64cert string, b64key string) (certificate, error) {
275
	crt := certificate{}
276

277
	cert, err := base64.StdEncoding.DecodeString(b64cert)
278
	if err != nil {
279
		return crt, errors.New("unable to decode base64 certificate")
280
	}
281

282
	key, err := base64.StdEncoding.DecodeString(b64key)
283
	if err != nil {
284
		return crt, errors.New("unable to decode base64 private key")
285
	}
286

287
	decodedCert, _ := pem.Decode(cert)
288
	if decodedCert == nil {
289
		return crt, errors.New("unable to decode certificate")
290
	}
291
	_, err = x509.ParseCertificate(decodedCert.Bytes)
292
	if err != nil {
293
		return crt, fmt.Errorf(
294
			"error parsing certificate: decodedCert.Bytes: %s",
295
			err,
296
		)
297
	}
298

299
	_, err = parsePrivateKeyPEM(string(key))
300
	if err != nil {
301
		return crt, fmt.Errorf(
302
			"error parsing private key: %s",
303
			err,
304
		)
305
	}
306

307
	crt.Cert = string(cert)
308
	crt.Key = string(key)
309

310
	return crt, nil
311
}
312

313
func generateCertificateAuthority(
314
	cn string,
315
	daysValid int,
316
) (certificate, error) {
317
	priv, err := rsa.GenerateKey(rand.Reader, 2048)
318
	if err != nil {
319
		return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
320
	}
321

322
	return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv)
323
}
324

325
func generateCertificateAuthorityWithPEMKey(
326
	cn string,
327
	daysValid int,
328
	privPEM string,
329
) (certificate, error) {
330
	priv, err := parsePrivateKeyPEM(privPEM)
331
	if err != nil {
332
		return certificate{}, fmt.Errorf("parsing private key: %s", err)
333
	}
334
	return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv)
335
}
336

337
func generateCertificateAuthorityWithKeyInternal(
338
	cn string,
339
	daysValid int,
340
	priv crypto.PrivateKey,
341
) (certificate, error) {
342
	ca := certificate{}
343

344
	template, err := getBaseCertTemplate(cn, nil, nil, daysValid)
345
	if err != nil {
346
		return ca, err
347
	}
348
	// Override KeyUsage and IsCA
349
	template.KeyUsage = x509.KeyUsageKeyEncipherment |
350
		x509.KeyUsageDigitalSignature |
351
		x509.KeyUsageCertSign
352
	template.IsCA = true
353

354
	ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv)
355

356
	return ca, err
357
}
358

359
func generateSelfSignedCertificate(
360
	cn string,
361
	ips []interface{},
362
	alternateDNS []interface{},
363
	daysValid int,
364
) (certificate, error) {
365
	priv, err := rsa.GenerateKey(rand.Reader, 2048)
366
	if err != nil {
367
		return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
368
	}
369
	return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv)
370
}
371

372
func generateSelfSignedCertificateWithPEMKey(
373
	cn string,
374
	ips []interface{},
375
	alternateDNS []interface{},
376
	daysValid int,
377
	privPEM string,
378
) (certificate, error) {
379
	priv, err := parsePrivateKeyPEM(privPEM)
380
	if err != nil {
381
		return certificate{}, fmt.Errorf("parsing private key: %s", err)
382
	}
383
	return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv)
384
}
385

386
func generateSelfSignedCertificateWithKeyInternal(
387
	cn string,
388
	ips []interface{},
389
	alternateDNS []interface{},
390
	daysValid int,
391
	priv crypto.PrivateKey,
392
) (certificate, error) {
393
	cert := certificate{}
394

395
	template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
396
	if err != nil {
397
		return cert, err
398
	}
399

400
	cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv)
401

402
	return cert, err
403
}
404

405
func generateSignedCertificate(
406
	cn string,
407
	ips []interface{},
408
	alternateDNS []interface{},
409
	daysValid int,
410
	ca certificate,
411
) (certificate, error) {
412
	priv, err := rsa.GenerateKey(rand.Reader, 2048)
413
	if err != nil {
414
		return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
415
	}
416
	return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv)
417
}
418

419
func generateSignedCertificateWithPEMKey(
420
	cn string,
421
	ips []interface{},
422
	alternateDNS []interface{},
423
	daysValid int,
424
	ca certificate,
425
	privPEM string,
426
) (certificate, error) {
427
	priv, err := parsePrivateKeyPEM(privPEM)
428
	if err != nil {
429
		return certificate{}, fmt.Errorf("parsing private key: %s", err)
430
	}
431
	return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv)
432
}
433

434
func generateSignedCertificateWithKeyInternal(
435
	cn string,
436
	ips []interface{},
437
	alternateDNS []interface{},
438
	daysValid int,
439
	ca certificate,
440
	priv crypto.PrivateKey,
441
) (certificate, error) {
442
	cert := certificate{}
443

444
	decodedSignerCert, _ := pem.Decode([]byte(ca.Cert))
445
	if decodedSignerCert == nil {
446
		return cert, errors.New("unable to decode certificate")
447
	}
448
	signerCert, err := x509.ParseCertificate(decodedSignerCert.Bytes)
449
	if err != nil {
450
		return cert, fmt.Errorf(
451
			"error parsing certificate: decodedSignerCert.Bytes: %s",
452
			err,
453
		)
454
	}
455
	signerKey, err := parsePrivateKeyPEM(ca.Key)
456
	if err != nil {
457
		return cert, fmt.Errorf(
458
			"error parsing private key: %s",
459
			err,
460
		)
461
	}
462

463
	template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
464
	if err != nil {
465
		return cert, err
466
	}
467

468
	cert.Cert, cert.Key, err = getCertAndKey(
469
		template,
470
		priv,
471
		signerCert,
472
		signerKey,
473
	)
474

475
	return cert, err
476
}
477

478
func getCertAndKey(
479
	template *x509.Certificate,
480
	signeeKey crypto.PrivateKey,
481
	parent *x509.Certificate,
482
	signingKey crypto.PrivateKey,
483
) (string, string, error) {
484
	signeePubKey, err := getPublicKey(signeeKey)
485
	if err != nil {
486
		return "", "", fmt.Errorf("error retrieving public key from signee key: %s", err)
487
	}
488
	derBytes, err := x509.CreateCertificate(
489
		rand.Reader,
490
		template,
491
		parent,
492
		signeePubKey,
493
		signingKey,
494
	)
495
	if err != nil {
496
		return "", "", fmt.Errorf("error creating certificate: %s", err)
497
	}
498

499
	certBuffer := bytes.Buffer{}
500
	if err := pem.Encode(
501
		&certBuffer,
502
		&pem.Block{Type: "CERTIFICATE", Bytes: derBytes},
503
	); err != nil {
504
		return "", "", fmt.Errorf("error pem-encoding certificate: %s", err)
505
	}
506

507
	keyBuffer := bytes.Buffer{}
508
	if err := pem.Encode(
509
		&keyBuffer,
510
		pemBlockForKey(signeeKey),
511
	); err != nil {
512
		return "", "", fmt.Errorf("error pem-encoding key: %s", err)
513
	}
514

515
	return certBuffer.String(), keyBuffer.String(), nil
516
}
517

518
func getBaseCertTemplate(
519
	cn string,
520
	ips []interface{},
521
	alternateDNS []interface{},
522
	daysValid int,
523
) (*x509.Certificate, error) {
524
	ipAddresses, err := getNetIPs(ips)
525
	if err != nil {
526
		return nil, err
527
	}
528
	dnsNames, err := getAlternateDNSStrs(alternateDNS)
529
	if err != nil {
530
		return nil, err
531
	}
532
	serialNumberUpperBound := new(big.Int).Lsh(big.NewInt(1), 128)
533
	serialNumber, err := rand.Int(rand.Reader, serialNumberUpperBound)
534
	if err != nil {
535
		return nil, err
536
	}
537
	return &x509.Certificate{
538
		SerialNumber: serialNumber,
539
		Subject: pkix.Name{
540
			CommonName: cn,
541
		},
542
		IPAddresses: ipAddresses,
543
		DNSNames:    dnsNames,
544
		NotBefore:   time.Now(),
545
		NotAfter:    time.Now().Add(time.Hour * 24 * time.Duration(daysValid)),
546
		KeyUsage:    x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
547
		ExtKeyUsage: []x509.ExtKeyUsage{
548
			x509.ExtKeyUsageServerAuth,
549
			x509.ExtKeyUsageClientAuth,
550
		},
551
		BasicConstraintsValid: true,
552
	}, nil
553
}
554

555
func getNetIPs(ips []interface{}) ([]net.IP, error) {
556
	if ips == nil {
557
		return []net.IP{}, nil
558
	}
559
	var ipStr string
560
	var ok bool
561
	var netIP net.IP
562
	netIPs := make([]net.IP, len(ips))
563
	for i, ip := range ips {
564
		ipStr, ok = ip.(string)
565
		if !ok {
566
			return nil, fmt.Errorf("error parsing ip: %v is not a string", ip)
567
		}
568
		netIP = net.ParseIP(ipStr)
569
		if netIP == nil {
570
			return nil, fmt.Errorf("error parsing ip: %s", ipStr)
571
		}
572
		netIPs[i] = netIP
573
	}
574
	return netIPs, nil
575
}
576

577
func getAlternateDNSStrs(alternateDNS []interface{}) ([]string, error) {
578
	if alternateDNS == nil {
579
		return []string{}, nil
580
	}
581
	var dnsStr string
582
	var ok bool
583
	alternateDNSStrs := make([]string, len(alternateDNS))
584
	for i, dns := range alternateDNS {
585
		dnsStr, ok = dns.(string)
586
		if !ok {
587
			return nil, fmt.Errorf(
588
				"error processing alternate dns name: %v is not a string",
589
				dns,
590
			)
591
		}
592
		alternateDNSStrs[i] = dnsStr
593
	}
594
	return alternateDNSStrs, nil
595
}
596

597
func encryptAES(password string, plaintext string) (string, error) {
598
	if plaintext == "" {
599
		return "", nil
600
	}
601

602
	key := make([]byte, 32)
603
	copy(key, []byte(password))
604
	block, err := aes.NewCipher(key)
605
	if err != nil {
606
		return "", err
607
	}
608

609
	content := []byte(plaintext)
610
	blockSize := block.BlockSize()
611
	padding := blockSize - len(content)%blockSize
612
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
613
	content = append(content, padtext...)
614

615
	ciphertext := make([]byte, aes.BlockSize+len(content))
616

617
	iv := ciphertext[:aes.BlockSize]
618
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
619
		return "", err
620
	}
621

622
	mode := cipher.NewCBCEncrypter(block, iv)
623
	mode.CryptBlocks(ciphertext[aes.BlockSize:], content)
624

625
	return base64.StdEncoding.EncodeToString(ciphertext), nil
626
}
627

628
func decryptAES(password string, crypt64 string) (string, error) {
629
	if crypt64 == "" {
630
		return "", nil
631
	}
632

633
	key := make([]byte, 32)
634
	copy(key, []byte(password))
635

636
	crypt, err := base64.StdEncoding.DecodeString(crypt64)
637
	if err != nil {
638
		return "", err
639
	}
640

641
	block, err := aes.NewCipher(key)
642
	if err != nil {
643
		return "", err
644
	}
645

646
	iv := crypt[:aes.BlockSize]
647
	crypt = crypt[aes.BlockSize:]
648
	decrypted := make([]byte, len(crypt))
649
	mode := cipher.NewCBCDecrypter(block, iv)
650
	mode.CryptBlocks(decrypted, crypt)
651

652
	return string(decrypted[:len(decrypted)-int(decrypted[len(decrypted)-1])]), nil
653
}
654

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.