summaryrefslogtreecommitdiff
path: root/vendor/github.com/Masterminds/sprig/v3/crypto.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/Masterminds/sprig/v3/crypto.go')
-rw-r--r--vendor/github.com/Masterminds/sprig/v3/crypto.go653
1 files changed, 0 insertions, 653 deletions
diff --git a/vendor/github.com/Masterminds/sprig/v3/crypto.go b/vendor/github.com/Masterminds/sprig/v3/crypto.go
deleted file mode 100644
index 13a5cd559..000000000
--- a/vendor/github.com/Masterminds/sprig/v3/crypto.go
+++ /dev/null
@@ -1,653 +0,0 @@
-package sprig
-
-import (
- "bytes"
- "crypto"
- "crypto/aes"
- "crypto/cipher"
- "crypto/dsa"
- "crypto/ecdsa"
- "crypto/ed25519"
- "crypto/elliptic"
- "crypto/hmac"
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha1"
- "crypto/sha256"
- "crypto/x509"
- "crypto/x509/pkix"
- "encoding/asn1"
- "encoding/base64"
- "encoding/binary"
- "encoding/hex"
- "encoding/pem"
- "errors"
- "fmt"
- "hash/adler32"
- "io"
- "math/big"
- "net"
- "time"
-
- "strings"
-
- "github.com/google/uuid"
- bcrypt_lib "golang.org/x/crypto/bcrypt"
- "golang.org/x/crypto/scrypt"
-)
-
-func sha256sum(input string) string {
- hash := sha256.Sum256([]byte(input))
- return hex.EncodeToString(hash[:])
-}
-
-func sha1sum(input string) string {
- hash := sha1.Sum([]byte(input))
- return hex.EncodeToString(hash[:])
-}
-
-func adler32sum(input string) string {
- hash := adler32.Checksum([]byte(input))
- return fmt.Sprintf("%d", hash)
-}
-
-func bcrypt(input string) string {
- hash, err := bcrypt_lib.GenerateFromPassword([]byte(input), bcrypt_lib.DefaultCost)
- if err != nil {
- return fmt.Sprintf("failed to encrypt string with bcrypt: %s", err)
- }
-
- return string(hash)
-}
-
-func htpasswd(username string, password string) string {
- if strings.Contains(username, ":") {
- return fmt.Sprintf("invalid username: %s", username)
- }
- return fmt.Sprintf("%s:%s", username, bcrypt(password))
-}
-
-func randBytes(count int) (string, error) {
- buf := make([]byte, count)
- if _, err := rand.Read(buf); err != nil {
- return "", err
- }
- return base64.StdEncoding.EncodeToString(buf), nil
-}
-
-// uuidv4 provides a safe and secure UUID v4 implementation
-func uuidv4() string {
- return uuid.New().String()
-}
-
-var masterPasswordSeed = "com.lyndir.masterpassword"
-
-var passwordTypeTemplates = map[string][][]byte{
- "maximum": {[]byte("anoxxxxxxxxxxxxxxxxx"), []byte("axxxxxxxxxxxxxxxxxno")},
- "long": {[]byte("CvcvnoCvcvCvcv"), []byte("CvcvCvcvnoCvcv"), []byte("CvcvCvcvCvcvno"), []byte("CvccnoCvcvCvcv"), []byte("CvccCvcvnoCvcv"),
- []byte("CvccCvcvCvcvno"), []byte("CvcvnoCvccCvcv"), []byte("CvcvCvccnoCvcv"), []byte("CvcvCvccCvcvno"), []byte("CvcvnoCvcvCvcc"),
- []byte("CvcvCvcvnoCvcc"), []byte("CvcvCvcvCvccno"), []byte("CvccnoCvccCvcv"), []byte("CvccCvccnoCvcv"), []byte("CvccCvccCvcvno"),
- []byte("CvcvnoCvccCvcc"), []byte("CvcvCvccnoCvcc"), []byte("CvcvCvccCvccno"), []byte("CvccnoCvcvCvcc"), []byte("CvccCvcvnoCvcc"),
- []byte("CvccCvcvCvccno")},
- "medium": {[]byte("CvcnoCvc"), []byte("CvcCvcno")},
- "short": {[]byte("Cvcn")},
- "basic": {[]byte("aaanaaan"), []byte("aannaaan"), []byte("aaannaaa")},
- "pin": {[]byte("nnnn")},
-}
-
-var templateCharacters = map[byte]string{
- 'V': "AEIOU",
- 'C': "BCDFGHJKLMNPQRSTVWXYZ",
- 'v': "aeiou",
- 'c': "bcdfghjklmnpqrstvwxyz",
- 'A': "AEIOUBCDFGHJKLMNPQRSTVWXYZ",
- 'a': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz",
- 'n': "0123456789",
- 'o': "@&%?,=[]_:-+*$#!'^~;()/.",
- 'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()",
-}
-
-func derivePassword(counter uint32, passwordType, password, user, site string) string {
- var templates = passwordTypeTemplates[passwordType]
- if templates == nil {
- return fmt.Sprintf("cannot find password template %s", passwordType)
- }
-
- var buffer bytes.Buffer
- buffer.WriteString(masterPasswordSeed)
- binary.Write(&buffer, binary.BigEndian, uint32(len(user)))
- buffer.WriteString(user)
-
- salt := buffer.Bytes()
- key, err := scrypt.Key([]byte(password), salt, 32768, 8, 2, 64)
- if err != nil {
- return fmt.Sprintf("failed to derive password: %s", err)
- }
-
- buffer.Truncate(len(masterPasswordSeed))
- binary.Write(&buffer, binary.BigEndian, uint32(len(site)))
- buffer.WriteString(site)
- binary.Write(&buffer, binary.BigEndian, counter)
-
- var hmacv = hmac.New(sha256.New, key)
- hmacv.Write(buffer.Bytes())
- var seed = hmacv.Sum(nil)
- var temp = templates[int(seed[0])%len(templates)]
-
- buffer.Truncate(0)
- for i, element := range temp {
- passChars := templateCharacters[element]
- passChar := passChars[int(seed[i+1])%len(passChars)]
- buffer.WriteByte(passChar)
- }
-
- return buffer.String()
-}
-
-func generatePrivateKey(typ string) string {
- var priv interface{}
- var err error
- switch typ {
- case "", "rsa":
- // good enough for government work
- priv, err = rsa.GenerateKey(rand.Reader, 4096)
- case "dsa":
- key := new(dsa.PrivateKey)
- // again, good enough for government work
- if err = dsa.GenerateParameters(&key.Parameters, rand.Reader, dsa.L2048N256); err != nil {
- return fmt.Sprintf("failed to generate dsa params: %s", err)
- }
- err = dsa.GenerateKey(key, rand.Reader)
- priv = key
- case "ecdsa":
- // again, good enough for government work
- priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
- case "ed25519":
- _, priv, err = ed25519.GenerateKey(rand.Reader)
- default:
- return "Unknown type " + typ
- }
- if err != nil {
- return fmt.Sprintf("failed to generate private key: %s", err)
- }
-
- return string(pem.EncodeToMemory(pemBlockForKey(priv)))
-}
-
-// DSAKeyFormat stores the format for DSA keys.
-// Used by pemBlockForKey
-type DSAKeyFormat struct {
- Version int
- P, Q, G, Y, X *big.Int
-}
-
-func pemBlockForKey(priv interface{}) *pem.Block {
- switch k := priv.(type) {
- case *rsa.PrivateKey:
- return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
- case *dsa.PrivateKey:
- val := DSAKeyFormat{
- P: k.P, Q: k.Q, G: k.G,
- Y: k.Y, X: k.X,
- }
- bytes, _ := asn1.Marshal(val)
- return &pem.Block{Type: "DSA PRIVATE KEY", Bytes: bytes}
- case *ecdsa.PrivateKey:
- b, _ := x509.MarshalECPrivateKey(k)
- return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
- default:
- // attempt PKCS#8 format for all other keys
- b, err := x509.MarshalPKCS8PrivateKey(k)
- if err != nil {
- return nil
- }
- return &pem.Block{Type: "PRIVATE KEY", Bytes: b}
- }
-}
-
-func parsePrivateKeyPEM(pemBlock string) (crypto.PrivateKey, error) {
- block, _ := pem.Decode([]byte(pemBlock))
- if block == nil {
- return nil, errors.New("no PEM data in input")
- }
-
- if block.Type == "PRIVATE KEY" {
- priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)
- if err != nil {
- return nil, fmt.Errorf("decoding PEM as PKCS#8: %s", err)
- }
- return priv, nil
- } else if !strings.HasSuffix(block.Type, " PRIVATE KEY") {
- return nil, fmt.Errorf("no private key data in PEM block of type %s", block.Type)
- }
-
- switch block.Type[:len(block.Type)-12] { // strip " PRIVATE KEY"
- case "RSA":
- priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- return nil, fmt.Errorf("parsing RSA private key from PEM: %s", err)
- }
- return priv, nil
- case "EC":
- priv, err := x509.ParseECPrivateKey(block.Bytes)
- if err != nil {
- return nil, fmt.Errorf("parsing EC private key from PEM: %s", err)
- }
- return priv, nil
- case "DSA":
- var k DSAKeyFormat
- _, err := asn1.Unmarshal(block.Bytes, &k)
- if err != nil {
- return nil, fmt.Errorf("parsing DSA private key from PEM: %s", err)
- }
- priv := &dsa.PrivateKey{
- PublicKey: dsa.PublicKey{
- Parameters: dsa.Parameters{
- P: k.P, Q: k.Q, G: k.G,
- },
- Y: k.Y,
- },
- X: k.X,
- }
- return priv, nil
- default:
- return nil, fmt.Errorf("invalid private key type %s", block.Type)
- }
-}
-
-func getPublicKey(priv crypto.PrivateKey) (crypto.PublicKey, error) {
- switch k := priv.(type) {
- case interface{ Public() crypto.PublicKey }:
- return k.Public(), nil
- case *dsa.PrivateKey:
- return &k.PublicKey, nil
- default:
- return nil, fmt.Errorf("unable to get public key for type %T", priv)
- }
-}
-
-type certificate struct {
- Cert string
- Key string
-}
-
-func buildCustomCertificate(b64cert string, b64key string) (certificate, error) {
- crt := certificate{}
-
- cert, err := base64.StdEncoding.DecodeString(b64cert)
- if err != nil {
- return crt, errors.New("unable to decode base64 certificate")
- }
-
- key, err := base64.StdEncoding.DecodeString(b64key)
- if err != nil {
- return crt, errors.New("unable to decode base64 private key")
- }
-
- decodedCert, _ := pem.Decode(cert)
- if decodedCert == nil {
- return crt, errors.New("unable to decode certificate")
- }
- _, err = x509.ParseCertificate(decodedCert.Bytes)
- if err != nil {
- return crt, fmt.Errorf(
- "error parsing certificate: decodedCert.Bytes: %s",
- err,
- )
- }
-
- _, err = parsePrivateKeyPEM(string(key))
- if err != nil {
- return crt, fmt.Errorf(
- "error parsing private key: %s",
- err,
- )
- }
-
- crt.Cert = string(cert)
- crt.Key = string(key)
-
- return crt, nil
-}
-
-func generateCertificateAuthority(
- cn string,
- daysValid int,
-) (certificate, error) {
- priv, err := rsa.GenerateKey(rand.Reader, 2048)
- if err != nil {
- return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
- }
-
- return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv)
-}
-
-func generateCertificateAuthorityWithPEMKey(
- cn string,
- daysValid int,
- privPEM string,
-) (certificate, error) {
- priv, err := parsePrivateKeyPEM(privPEM)
- if err != nil {
- return certificate{}, fmt.Errorf("parsing private key: %s", err)
- }
- return generateCertificateAuthorityWithKeyInternal(cn, daysValid, priv)
-}
-
-func generateCertificateAuthorityWithKeyInternal(
- cn string,
- daysValid int,
- priv crypto.PrivateKey,
-) (certificate, error) {
- ca := certificate{}
-
- template, err := getBaseCertTemplate(cn, nil, nil, daysValid)
- if err != nil {
- return ca, err
- }
- // Override KeyUsage and IsCA
- template.KeyUsage = x509.KeyUsageKeyEncipherment |
- x509.KeyUsageDigitalSignature |
- x509.KeyUsageCertSign
- template.IsCA = true
-
- ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv)
-
- return ca, err
-}
-
-func generateSelfSignedCertificate(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
-) (certificate, error) {
- priv, err := rsa.GenerateKey(rand.Reader, 2048)
- if err != nil {
- return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
- }
- return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv)
-}
-
-func generateSelfSignedCertificateWithPEMKey(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
- privPEM string,
-) (certificate, error) {
- priv, err := parsePrivateKeyPEM(privPEM)
- if err != nil {
- return certificate{}, fmt.Errorf("parsing private key: %s", err)
- }
- return generateSelfSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, priv)
-}
-
-func generateSelfSignedCertificateWithKeyInternal(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
- priv crypto.PrivateKey,
-) (certificate, error) {
- cert := certificate{}
-
- template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
- if err != nil {
- return cert, err
- }
-
- cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv)
-
- return cert, err
-}
-
-func generateSignedCertificate(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
- ca certificate,
-) (certificate, error) {
- priv, err := rsa.GenerateKey(rand.Reader, 2048)
- if err != nil {
- return certificate{}, fmt.Errorf("error generating rsa key: %s", err)
- }
- return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv)
-}
-
-func generateSignedCertificateWithPEMKey(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
- ca certificate,
- privPEM string,
-) (certificate, error) {
- priv, err := parsePrivateKeyPEM(privPEM)
- if err != nil {
- return certificate{}, fmt.Errorf("parsing private key: %s", err)
- }
- return generateSignedCertificateWithKeyInternal(cn, ips, alternateDNS, daysValid, ca, priv)
-}
-
-func generateSignedCertificateWithKeyInternal(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
- ca certificate,
- priv crypto.PrivateKey,
-) (certificate, error) {
- cert := certificate{}
-
- decodedSignerCert, _ := pem.Decode([]byte(ca.Cert))
- if decodedSignerCert == nil {
- return cert, errors.New("unable to decode certificate")
- }
- signerCert, err := x509.ParseCertificate(decodedSignerCert.Bytes)
- if err != nil {
- return cert, fmt.Errorf(
- "error parsing certificate: decodedSignerCert.Bytes: %s",
- err,
- )
- }
- signerKey, err := parsePrivateKeyPEM(ca.Key)
- if err != nil {
- return cert, fmt.Errorf(
- "error parsing private key: %s",
- err,
- )
- }
-
- template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
- if err != nil {
- return cert, err
- }
-
- cert.Cert, cert.Key, err = getCertAndKey(
- template,
- priv,
- signerCert,
- signerKey,
- )
-
- return cert, err
-}
-
-func getCertAndKey(
- template *x509.Certificate,
- signeeKey crypto.PrivateKey,
- parent *x509.Certificate,
- signingKey crypto.PrivateKey,
-) (string, string, error) {
- signeePubKey, err := getPublicKey(signeeKey)
- if err != nil {
- return "", "", fmt.Errorf("error retrieving public key from signee key: %s", err)
- }
- derBytes, err := x509.CreateCertificate(
- rand.Reader,
- template,
- parent,
- signeePubKey,
- signingKey,
- )
- if err != nil {
- return "", "", fmt.Errorf("error creating certificate: %s", err)
- }
-
- certBuffer := bytes.Buffer{}
- if err := pem.Encode(
- &certBuffer,
- &pem.Block{Type: "CERTIFICATE", Bytes: derBytes},
- ); err != nil {
- return "", "", fmt.Errorf("error pem-encoding certificate: %s", err)
- }
-
- keyBuffer := bytes.Buffer{}
- if err := pem.Encode(
- &keyBuffer,
- pemBlockForKey(signeeKey),
- ); err != nil {
- return "", "", fmt.Errorf("error pem-encoding key: %s", err)
- }
-
- return certBuffer.String(), keyBuffer.String(), nil
-}
-
-func getBaseCertTemplate(
- cn string,
- ips []interface{},
- alternateDNS []interface{},
- daysValid int,
-) (*x509.Certificate, error) {
- ipAddresses, err := getNetIPs(ips)
- if err != nil {
- return nil, err
- }
- dnsNames, err := getAlternateDNSStrs(alternateDNS)
- if err != nil {
- return nil, err
- }
- serialNumberUpperBound := new(big.Int).Lsh(big.NewInt(1), 128)
- serialNumber, err := rand.Int(rand.Reader, serialNumberUpperBound)
- if err != nil {
- return nil, err
- }
- return &x509.Certificate{
- SerialNumber: serialNumber,
- Subject: pkix.Name{
- CommonName: cn,
- },
- IPAddresses: ipAddresses,
- DNSNames: dnsNames,
- NotBefore: time.Now(),
- NotAfter: time.Now().Add(time.Hour * 24 * time.Duration(daysValid)),
- KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
- ExtKeyUsage: []x509.ExtKeyUsage{
- x509.ExtKeyUsageServerAuth,
- x509.ExtKeyUsageClientAuth,
- },
- BasicConstraintsValid: true,
- }, nil
-}
-
-func getNetIPs(ips []interface{}) ([]net.IP, error) {
- if ips == nil {
- return []net.IP{}, nil
- }
- var ipStr string
- var ok bool
- var netIP net.IP
- netIPs := make([]net.IP, len(ips))
- for i, ip := range ips {
- ipStr, ok = ip.(string)
- if !ok {
- return nil, fmt.Errorf("error parsing ip: %v is not a string", ip)
- }
- netIP = net.ParseIP(ipStr)
- if netIP == nil {
- return nil, fmt.Errorf("error parsing ip: %s", ipStr)
- }
- netIPs[i] = netIP
- }
- return netIPs, nil
-}
-
-func getAlternateDNSStrs(alternateDNS []interface{}) ([]string, error) {
- if alternateDNS == nil {
- return []string{}, nil
- }
- var dnsStr string
- var ok bool
- alternateDNSStrs := make([]string, len(alternateDNS))
- for i, dns := range alternateDNS {
- dnsStr, ok = dns.(string)
- if !ok {
- return nil, fmt.Errorf(
- "error processing alternate dns name: %v is not a string",
- dns,
- )
- }
- alternateDNSStrs[i] = dnsStr
- }
- return alternateDNSStrs, nil
-}
-
-func encryptAES(password string, plaintext string) (string, error) {
- if plaintext == "" {
- return "", nil
- }
-
- key := make([]byte, 32)
- copy(key, []byte(password))
- block, err := aes.NewCipher(key)
- if err != nil {
- return "", err
- }
-
- content := []byte(plaintext)
- blockSize := block.BlockSize()
- padding := blockSize - len(content)%blockSize
- padtext := bytes.Repeat([]byte{byte(padding)}, padding)
- content = append(content, padtext...)
-
- ciphertext := make([]byte, aes.BlockSize+len(content))
-
- iv := ciphertext[:aes.BlockSize]
- if _, err := io.ReadFull(rand.Reader, iv); err != nil {
- return "", err
- }
-
- mode := cipher.NewCBCEncrypter(block, iv)
- mode.CryptBlocks(ciphertext[aes.BlockSize:], content)
-
- return base64.StdEncoding.EncodeToString(ciphertext), nil
-}
-
-func decryptAES(password string, crypt64 string) (string, error) {
- if crypt64 == "" {
- return "", nil
- }
-
- key := make([]byte, 32)
- copy(key, []byte(password))
-
- crypt, err := base64.StdEncoding.DecodeString(crypt64)
- if err != nil {
- return "", err
- }
-
- block, err := aes.NewCipher(key)
- if err != nil {
- return "", err
- }
-
- iv := crypt[:aes.BlockSize]
- crypt = crypt[aes.BlockSize:]
- decrypted := make([]byte, len(crypt))
- mode := cipher.NewCBCDecrypter(block, iv)
- mode.CryptBlocks(decrypted, crypt)
-
- return string(decrypted[:len(decrypted)-int(decrypted[len(decrypted)-1])]), nil
-}