github.com/avenga/couper@v1.12.2/internal/tls/certificate.go (about) 1 package tls 2 3 import ( 4 "crypto" 5 "crypto/ecdsa" 6 "crypto/ed25519" 7 "crypto/rsa" 8 "crypto/tls" 9 "crypto/x509" 10 "encoding/pem" 11 "strings" 12 13 "github.com/avenga/couper/errors" 14 ) 15 16 // ParseCertificate reads a certificate from the given bytes. 17 // Either as PEM format where chained ones are considered or just plain DER format. 18 func ParseCertificate(cert, key []byte) (certificate tls.Certificate, err error) { 19 certBytes := cert[:] 20 // try PEM format 21 var keyDERBlock *pem.Block 22 for { 23 var certDERBlock *pem.Block 24 certDERBlock, certBytes = pem.Decode(certBytes) 25 if certDERBlock == nil { 26 if len(certificate.Certificate) > 0 { 27 certificate.Leaf, err = x509.ParseCertificate(certificate.Certificate[0]) 28 if err != nil { 29 return certificate, err 30 } 31 32 // Option to combine both into one file. 33 if keyDERBlock != nil { 34 certificate.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) 35 if err != nil { 36 return certificate, err 37 } 38 } 39 } 40 break 41 } 42 if certDERBlock.Type == "CERTIFICATE" { 43 certificate.Certificate = append(certificate.Certificate, certDERBlock.Bytes) 44 } else if strings.HasSuffix(certDERBlock.Type, " PRIVATE KEY") { 45 keyDERBlock = certDERBlock 46 } 47 } 48 49 // assume DER format 50 if len(certificate.Certificate) == 0 { 51 var x509Certificate *x509.Certificate 52 x509Certificate, err = x509.ParseCertificate(cert) 53 if err != nil { 54 return certificate, err 55 } 56 57 certificate = tls.Certificate{ 58 Certificate: [][]byte{cert}, 59 Leaf: x509Certificate, 60 } 61 } 62 63 if certificate.PrivateKey == nil && len(key) > 0 { 64 keyBytes := key[:] 65 keyDERBlock, _ = pem.Decode(key) 66 if keyDERBlock != nil { 67 keyBytes = keyDERBlock.Bytes 68 } 69 certificate.PrivateKey, err = parsePrivateKey(keyBytes) 70 } 71 72 return certificate, err 73 } 74 75 // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates 76 // PKCS #1 private keys by default, while OpenSSL 1.0.0 generates PKCS #8 keys. 77 // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. 78 func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { 79 if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { 80 return key, nil 81 } 82 if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { 83 switch key := key.(type) { 84 case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey: 85 return key, nil 86 default: 87 return nil, errors.Configuration.Message("tls: found unknown private key type in PKCS#8 wrapping") 88 } 89 } 90 if key, err := x509.ParseECPrivateKey(der); err == nil { 91 return key, nil 92 } 93 94 return nil, errors.Configuration.Message("tls: failed to parse private key") 95 }