// ParseCertificatesDER parses a DER encoding of a certificate object and possibly private key, // either PKCS #7, PKCS #12, or raw x509. func ParseCertificatesDER(certsDER []byte, password string) (certs []*x509.Certificate, key crypto.Signer, err error) { certsDER = bytes.TrimSpace(certsDER) pkcs7data, err := pkcs7.ParsePKCS7(certsDER) if err != nil { var pkcs12data interface{} certs = make([]*x509.Certificate, 1) pkcs12data, certs[0], err = pkcs12.Decode(certsDER, password) if err != nil { certs, err = x509.ParseCertificates(certsDER) if err != nil { return nil, nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) } } else { key = pkcs12data.(crypto.Signer) } } else { if pkcs7data.ContentInfo != "SignedData" { return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.DecodeFailed, errors.New("can only extract certificates from signed data content info")) } certs = pkcs7data.Content.SignedData.Certificates } if certs == nil { return nil, key, cferr.New(cferr.CertificateError, cferr.DecodeFailed) } return certs, key, nil }
func LoadCertKeyFromEncPkg(encpkg []byte, passwd string) (*CertKey, error) { blk, _ := pem.Decode(encpkg) if blk == nil { return nil, errors.New("Invalid PEM data") } if blk.Type != pkgTypeStr { return nil, errors.New("PEM type is not " + pkgTypeStr) } decrypted_pem, err := x509.DecryptPEMBlock(blk, []byte(passwd)) if err != nil { return nil, err } key_pem, rest := pem.Decode(decrypted_pem) if blk == nil { return nil, errors.New("decrypted content is not PEM") } cert_pem, _ := pem.Decode(rest) if blk == nil { return nil, errors.New("Can't find the cert PEM") } if _, ok := supportedKeyTypes[key_pem.Type]; !ok { return nil, errors.New("Unsupported Key types") } if cert_pem.Type != "CERTIFICATE" { return nil, errors.New("Can't find certificate in decrypted PEM data") } var ck CertKey switch key_pem.Type { case "RSA PRIVATE KEY": rsack := new(RSACertKey) priv_key, err := x509.ParsePKCS1PrivateKey(key_pem.Bytes) if err != nil { return nil, err } rsack.key = priv_key cert, err := x509.ParseCertificates(cert_pem.Bytes) if err != nil { return nil, err } rsack.cert = *cert[0] ck = rsack return &ck, nil case "EC PRIVATE KEY": ecck := new(ECCertKey) priv_key, err := x509.ParseECPrivateKey(key_pem.Bytes) if err != nil { return nil, err } ecck.key = priv_key cert, err := x509.ParseCertificates(cert_pem.Bytes) if err != nil { return nil, err } ecck.cert = *cert[0] ck = ecck return &ck, nil } return nil, errors.New("Unussal error, you shouldn't see this") }
func LoadManpassCA(uname string, passwd []byte) (*CertKey, error) { //generate a new EE cert/key with specified uname's CA //return encrypted CA cert, EE cert and encrypted EE key in a string confdir := common.GetConfDir(uname) fi, err := os.Stat(confdir) if err != nil { return nil, err } if !fi.IsDir() { return nil, fmt.Errorf("%s is not a directory", confdir) } encacs, err := ioutil.ReadFile(filepath.Join(confdir, "ca.cert")) if err != nil { return nil, err } cacert_der, err := passcrypto.DecryptMeBase32(string(encacs), passwd) if err != nil { return nil, err } encaks, err := ioutil.ReadFile(filepath.Join(confdir, "ca.key")) if err != nil { return nil, err } blk, _ := pem.Decode(encaks) cakey_der, err := x509.DecryptPEMBlock(blk, passwd) var ck CertKey switch blk.Type { case "RSA PRIVATE KEY": ca := new(RSACertKey) cakey, err := x509.ParsePKCS1PrivateKey(cakey_der) if err != nil { return nil, err } ca.key = cakey cert, err := x509.ParseCertificates(cacert_der) if err != nil { return nil, err } ca.cert = *cert[0] ck = ca return &ck, nil case "EC PRIVATE KEY": ecck := new(ECCertKey) priv_key, err := x509.ParseECPrivateKey(cakey_der) if err != nil { return nil, err } ecck.key = priv_key cert, err := x509.ParseCertificates(cacert_der) if err != nil { return nil, err } ecck.cert = *cert[0] ck = ecck return &ck, nil } return nil, errors.New("Unussal error, you shouldn't see this") }
func parseCertificate(certificateBytes []byte, privateKeyBytes []byte) *x509.Certificate { certificate, err := tls.X509KeyPair(certificateBytes, privateKeyBytes) Expect(err).NotTo(HaveOccurred()) certificates, err := x509.ParseCertificates(certificate.Certificate[0]) Expect(err).NotTo(HaveOccurred()) return certificates[0] }
func TestDialTLS(t *testing.T) { s := newTLSServer(t) defer s.Close() certs := x509.NewCertPool() for _, c := range s.TLS.Certificates { roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1]) if err != nil { t.Fatalf("error parsing server's root cert: %v", err) } for _, root := range roots { certs.AddCert(root) } } u, _ := url.Parse(s.URL) d := cstDialer d.NetDial = func(network, addr string) (net.Conn, error) { return net.Dial(network, u.Host) } d.TLSClientConfig = &tls.Config{RootCAs: certs} ws, _, err := d.Dial("wss://example.com/", nil) if err != nil { t.Fatalf("Dial: %v", err) } defer ws.Close() sendRecv(t, ws) }
func certSignature(cert tls.Certificate) (string, error) { x509Certs, err := x509.ParseCertificates(cert.Certificate[0]) if err != nil { return "", err } return x509CertSignature(x509Certs[0]), nil }
// ParsePKCS7 attempts to parse the DER encoded bytes of a // PKCS7 structure func ParsePKCS7(raw []byte) (msg *PKCS7, err error) { var pkcs7 initPKCS7 _, err = asn1.Unmarshal(raw, &pkcs7) if err != nil { return nil, err } msg = new(PKCS7) msg.Raw = pkcs7.Raw msg.Version = pkcs7.Content.SignedData.Version if len(pkcs7.Content.SignedData.Certificates.Bytes) == 0 { msg.Certificates = nil } else { msg.Certificates, err = x509.ParseCertificates(pkcs7.Content.SignedData.Certificates.Bytes) if err != nil { return nil, err } } if len(pkcs7.Content.SignedData.Crls.Bytes) == 0 { msg.Crl = nil } else { msg.Crl, err = x509.ParseDERCRL(pkcs7.Content.SignedData.Crls.Bytes) if err != nil { return nil, err } } return msg, nil }
func DecodeCertificates(data []byte) ([]*x509.Certificate, error) { if IsPEM(data) { var certs []*x509.Certificate for len(data) > 0 { var block *pem.Block block, data = pem.Decode(data) if block == nil { return nil, errors.New("Invalid certificate.") } if block.Type != certBlockType { return nil, errors.New("Invalid certificate.") } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { return nil, errors.New("Invalid certificate.") } certs = append(certs, cert) } return certs, nil } else { certs, err := x509.ParseCertificates(data) if err != nil { return nil, errors.New("Invalid certificate.") } return certs, nil } }
func LoadTLSConfig(rootCertPaths []string) (*tls.Config, error) { pool := x509.NewCertPool() for _, certPath := range rootCertPaths { // rootCrt, err := assets.Asset(certPath) rootCrt, err := ioutil.ReadFile(certPath) if err != nil { return nil, err } pemBlock, _ := pem.Decode(rootCrt) if pemBlock == nil { return nil, fmt.Errorf("Bad PEM data") } certs, err := x509.ParseCertificates(pemBlock.Bytes) if err != nil { return nil, err } pool.AddCert(certs[0]) } return &tls.Config{RootCAs: pool}, nil }
func init() { pool := x509.NewCertPool() ngrokRootCrt, err := assets.ReadAsset("assets/client/tls/ngrokroot.crt") if err != nil { panic(err) } snakeoilCaCrt, err := assets.ReadAsset("assets/client/tls/snakeoilca.crt") if err != nil { panic(err) } for _, b := range [][]byte{ngrokRootCrt, snakeoilCaCrt} { pemBlock, _ := pem.Decode(b) if pemBlock == nil { panic("Bad PEM data") } certs, err := x509.ParseCertificates(pemBlock.Bytes) if err != nil { panic(err) } pool.AddCert(certs[0]) } tlsConfig = &tls.Config{ RootCAs: pool, ServerName: "tls.ngrok.com", } }
// ParseCertificatesDER parses a DER encoding of a certificate object and possibly private key, // either PKCS #7, PKCS #12, or raw x509. func ParseCertificatesDER(certsDER []byte, password string) ([]*x509.Certificate, crypto.Signer, error) { var certs []*x509.Certificate var key crypto.Signer certsDER = bytes.TrimSpace(certsDER) pkcs7data, err := pkcs7.ParsePKCS7(certsDER) if err != nil { pkcs12data, err := pkcs12.ParsePKCS12(certsDER, []byte(password)) if err != nil { certs, err = x509.ParseCertificates(certsDER) if err != nil { return nil, nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) } } else { key = pkcs12data.PrivateKey certs = pkcs12data.Certificates } } else { if pkcs7data.ContentInfo != "SignedData" { return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.DecodeFailed, errors.New("can only extract certificates from signed data content info")) } certs = pkcs7data.Content.SignedData.Certificates } if certs == nil { return nil, key, cferr.New(cferr.CertificateError, cferr.DecodeFailed) } return certs, key, nil }
func parseSignedData(data []byte) (*PKCS7, error) { var sd signedData asn1.Unmarshal(data, &sd) certs, err := x509.ParseCertificates(sd.Certificates.Bytes) if err != nil { return nil, err } // fmt.Printf("--> Signed Data Version %d\n", sd.Version) var compound asn1.RawValue var content unsignedData if _, err := asn1.Unmarshal(sd.ContentInfo.Content.Bytes, &compound); err != nil { return nil, err } // Compound octet string if compound.IsCompound { if _, err = asn1.Unmarshal(compound.Bytes, &content); err != nil { return nil, err } } else { // assuming this is tag 04 content = compound.Bytes } return &PKCS7{ Content: content, Certificates: certs, CRLs: sd.CRLs, Signers: sd.SignerInfos, raw: sd}, nil }
func generateCert(serverName string, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) { priv, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { return nil, nil, err } serial := randBigInt() keyId := randBytes() template := x509.Certificate{ Subject: pkix.Name{ CommonName: serverName, }, SerialNumber: serial, SubjectKeyId: keyId, AuthorityKeyId: caCert.AuthorityKeyId, NotBefore: time.Now().Add(-5 * time.Minute).UTC(), NotAfter: time.Now().AddDate(2, 0, 0).UTC(), } derBytes, err := x509.CreateCertificate(rand.Reader, &template, caCert, &priv.PublicKey, caKey) if err != nil { return nil, nil, err } certs, err := x509.ParseCertificates(derBytes) if err != nil { return nil, nil, err } if len(certs) != 1 { return nil, nil, errors.New("Failed to generate a parsable certificate") } return certs[0], priv, nil }
func LoadTLSConfig(rootCertPaths []string) (*tls.Config, error) { pool := x509.NewCertPool() for _, certPath := range rootCertPaths { rootCrt, err := assets.Asset(certPath) if err != nil { return nil, err } pemBlock, _ := pem.Decode(rootCrt) if pemBlock == nil { return nil, fmt.Errorf("Bad PEM data") } certs, err := x509.ParseCertificates(pemBlock.Bytes) if err != nil { return nil, err } pool.AddCert(certs[0]) } //https://github.com/golang/go/issues/9364 //log.Info("MinVersion:", tls.VersionSSL30) return &tls.Config{RootCAs: pool, MinVersion: tls.VersionSSL30, InsecureSkipVerify: true}, nil }
// ParsePKCS7 attempts to parse the DER encoded bytes of a // PKCS7 structure func ParsePKCS7(raw []byte) (msg *PKCS7, err error) { var pkcs7 initPKCS7 _, err = asn1.Unmarshal(raw, &pkcs7) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } msg = new(PKCS7) msg.Raw = pkcs7.Raw msg.ContentInfo = pkcs7.ContentType.String() switch { case msg.ContentInfo == ObjIDData: msg.ContentInfo = "Data" _, err = asn1.Unmarshal(pkcs7.Content.Bytes, &msg.Content.Data) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } case msg.ContentInfo == ObjIDSignedData: msg.ContentInfo = "SignedData" var signedData signedData _, err = asn1.Unmarshal(pkcs7.Content.Bytes, &signedData) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } if len(signedData.Certificates.Bytes) != 0 { msg.Content.SignedData.Certificates, err = x509.ParseCertificates(signedData.Certificates.Bytes) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } } if len(signedData.Crls.Bytes) != 0 { msg.Content.SignedData.Crl, err = x509.ParseDERCRL(signedData.Crls.Bytes) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } } msg.Content.SignedData.Version = signedData.Version msg.Content.SignedData.Raw = pkcs7.Content.Bytes case msg.ContentInfo == ObjIDEncryptedData: msg.ContentInfo = "EncryptedData" var encryptedData EncryptedData _, err = asn1.Unmarshal(pkcs7.Content.Bytes, &encryptedData) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } if encryptedData.Version != 0 { return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Only support for PKCS #7 encryptedData version 0")) } msg.Content.EncryptedData = encryptedData default: return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Attempt to parse PKCS# 7 Content not of type data, signed data or encrypted data")) } return msg, nil }
// Decode extracts a certificate and private key from pfxData. This function // assumes that there is only one certificate and only one private key in the // pfxData. func Decode(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, err error) { encodedPassword, err := bmpString(password) if err != nil { return nil, nil, err } bags, encodedPassword, err := getSafeContents(pfxData, encodedPassword) if err != nil { return nil, nil, err } if len(bags) != 2 { err = errors.New("pkcs12: expected exactly two safe bags in the PFX PDU") return } for _, bag := range bags { switch { case bag.Id.Equal(oidCertBag): if certificate != nil { err = errors.New("pkcs12: expected exactly one certificate bag") } certsData, err := decodeCertBag(bag.Value.Bytes) if err != nil { return nil, nil, err } certs, err := x509.ParseCertificates(certsData) if err != nil { return nil, nil, err } if len(certs) != 1 { err = errors.New("pkcs12: expected exactly one certificate in the certBag") return nil, nil, err } certificate = certs[0] case bag.Id.Equal(oidPKCS8ShroundedKeyBag): if privateKey != nil { err = errors.New("pkcs12: expected exactly one key bag") } if privateKey, err = decodePkcs8ShroudedKeyBag(bag.Value.Bytes, encodedPassword); err != nil { return nil, nil, err } } } if certificate == nil { return nil, nil, errors.New("pkcs12: certificate missing") } if privateKey == nil { return nil, nil, errors.New("pkcs12: private key missing") } return }
// Hash returns the hash of cert, or error if cert is not a valid pem-encoded x509 cert func Hash(cert []byte) ([]byte, error) { block, _ := pem.Decode(cert) _, err := x509.ParseCertificates(block.Bytes) if err != nil { return nil, err } x := sha512.Sum512(block.Bytes) return x[:], nil }
func PEMDecode(pemBytes []byte) x509.Certificate { block, _ := pem.Decode(pemBytes) certs, err := x509.ParseCertificates(block.Bytes) check(err) if len(certs) != 1 { check(errors.New(fmt.Sprintf("Cannot parse CA certificate from database. Received: %#v which parsed to %#v\n", pemBytes, certs))) } return *certs[0] }
func main() { flag.Parse() var contents []byte var err error if *file == "" { contents, err = ioutil.ReadAll(os.Stdin) } else { contents, err = ioutil.ReadFile(*file) } if err != nil { log.Fatal(err) } block, _ := pem.Decode(contents) if block == nil { log.Fatal("Not a PEM block.") } var keybytes []byte switch block.Type { case "PUBLIC KEY", "RSA PUBLIC KEY": keybytes = block.Bytes case "CERTIFICATE": certs, err := x509.ParseCertificates(block.Bytes) if err != nil { log.Fatal(err) } if len(certs) < 1 { log.Fatal("No certificates.") } keybytes = certs[0].RawSubjectPublicKeyInfo default: log.Fatalf("Unknown block type: %q.", block.Type) } hasher := sha256.New() hasher.Write(keybytes) fmt.Printf("sha256/%v\n", base64.StdEncoding.EncodeToString(hasher.Sum(nil))) if *verbose { var spki PublicKeyInfo if _, err := asn1.Unmarshal(keybytes, &spki); err != nil { log.Fatal(err) } fmt.Printf("AlgID: %v\n", spki.Algorithm.Algorithm) var pubkey RSAPublicKey if _, err := asn1.Unmarshal(spki.PublicKey.Bytes, &pubkey); err != nil { log.Fatal(err) } fmt.Printf("N: %v\n", pubkey.N) fmt.Printf("E: %v\n", pubkey.E) } }
func (raw rawCertificates) Parse() ([]*x509.Certificate, error) { if len(raw.Raw) == 0 { return nil, nil } var val asn1.RawValue if _, err := asn1.Unmarshal(raw.Raw, &val); err != nil { return nil, err } return x509.ParseCertificates(val.Bytes) }
// Decode extracts a certificate and private key from pfxData. // This function assumes that there is only one certificate and only one private key in the pfxData. func Decode(pfxData, utf8Password []byte) (privateKey interface{}, certificate *x509.Certificate, err error) { p, err := bmpString(utf8Password) defer func() { // clear out BMP version of the password before we return for i := 0; i < len(p); i++ { p[i] = 0 } }() if err != nil { return nil, nil, err } bags, p, err := getSafeContents(pfxData, p) if err != nil { return nil, nil, err } if len(bags) != 2 { err = errors.New("expected exactly two safe bags in the PFX PDU") return } for _, bag := range bags { switch { case bag.ID.Equal(oidCertBagType): certsData, err := decodeCertBag(bag.Value.Bytes) if err != nil { return nil, nil, err } certs, err := x509.ParseCertificates(certsData) if err != nil { return nil, nil, err } if len(certs) != 1 { err = errors.New("expected exactly one certificate in the certBag") return nil, nil, err } certificate = certs[0] case bag.ID.Equal(oidPkcs8ShroudedKeyBagType): if privateKey, err = decodePkcs8ShroudedKeyBag(bag.Value.Bytes, p); err != nil { return nil, nil, err } } } if certificate == nil { return nil, nil, errors.New("certificate missing") } if privateKey == nil { return nil, nil, errors.New("private key missing") } return }
/* ValidateRoot iterates over every root key included in the TUF data and attempts to validate the certificate by first checking for an exact match on the certificate store, and subsequently trying to find a valid chain on the trustedCAStore. When this is being used with a notary repository, the dnsName parameter should be the GUN associated with the repository. Example TUF Content for root role: "roles" : { "root" : { "threshold" : 1, "keyids" : [ "e6da5c303d572712a086e669ecd4df7b785adfc844e0c9a7b1f21a7dfc477a38" ] }, ... } Example TUF Content for root key: "e6da5c303d572712a086e669ecd4df7b785adfc844e0c9a7b1f21a7dfc477a38" : { "keytype" : "RSA", "keyval" : { "private" : "", "public" : "Base64-encoded, PEM encoded x509 Certificate" } } */ func (km *KeyStoreManager) ValidateRoot(root *data.Signed, dnsName string) error { rootSigned := &data.Root{} err := json.Unmarshal(root.Signed, rootSigned) if err != nil { return err } certs := make(map[string]*data.PublicKey) for _, keyID := range rootSigned.Roles["root"].KeyIDs { // TODO(dlaw): currently assuming only one cert contained in // public key entry. Need to fix when we want to pass in chains. k, _ := pem.Decode([]byte(rootSigned.Keys[keyID].Public())) decodedCerts, err := x509.ParseCertificates(k.Bytes) if err != nil { logrus.Debugf("error while parsing root certificate with keyID: %s, %v", keyID, err) continue } // TODO(diogo): Assuming that first certificate is the leaf-cert. Need to // iterate over all decodedCerts and find a non-CA one (should be the last). leafCert := decodedCerts[0] leafID, err := trustmanager.FingerprintCert(leafCert) if err != nil { logrus.Debugf("error while fingerprinting root certificate with keyID: %s, %v", keyID, err) continue } // Check to see if there is an exact match of this certificate. // Checking the CommonName is not required since ID is calculated over // Cert.Raw. It's included to prevent breaking logic with changes of how the // ID gets computed. _, err = km.trustedCertificateStore.GetCertificateByKeyID(leafID) if err == nil && leafCert.Subject.CommonName == dnsName { certs[keyID] = rootSigned.Keys[keyID] } // Check to see if this leafCertificate has a chain to one of the Root CAs // of our CA Store. certList := []*x509.Certificate{leafCert} err = trustmanager.Verify(km.trustedCAStore, dnsName, certList) if err == nil { certs[keyID] = rootSigned.Keys[keyID] } } if len(certs) < 1 { return errors.New("could not validate the path to a trusted root") } _, err = signed.VerifyRoot(root, 0, certs, 1) return err }
func PemToCerts(in io.Reader) ([]*x509.Certificate, error) { d, err := ioutil.ReadAll(in) if err != nil { return nil, err } block, _ := pem.Decode(d) certs, err := x509.ParseCertificates(block.Bytes) if err != nil { return nil, err } return certs, nil }
func appendCertsFromFile(pool *x509.CertPool, filename string) *x509.CertPool { data, err := ioutil.ReadFile(filename) if err != nil { tracerx.Printf("Error reading cert file %q: %v", filename, err) return pool } // Firstly, try parsing as binary certificate if certs, err := x509.ParseCertificates(data); err == nil { return appendCerts(pool, certs) } // If not binary certs, try PEM data return appendCertsFromPEMData(pool, data) }
func signCertificate(template *x509.Certificate, requestKey crypto.PublicKey, issuer *x509.Certificate, issuerKey crypto.PrivateKey) (*x509.Certificate, error) { derBytes, err := x509.CreateCertificate(rand.Reader, template, issuer, requestKey, issuerKey) if err != nil { return nil, err } certs, err := x509.ParseCertificates(derBytes) if err != nil { return nil, err } if len(certs) != 1 { return nil, errors.New("Expected a single certificate") } return certs[0], nil }
// X509KeyPair parses a public/private key pair from a pair of PEM encoded // data. It is slightly modified version of tls.X509Proxy where Leaf // assignment is made to make proxy certificate works. func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert tls.Certificate, err error) { var certDERBlock *pem.Block for { certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) if certDERBlock == nil { break } // parse certificates certs, err2 := x509.ParseCertificates(certDERBlock.Bytes) if err2 == nil { // assign the Leaf cert.Leaf = certs[0] } if certDERBlock.Type == "CERTIFICATE" { cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) } } if len(cert.Certificate) == 0 { err = errors.New("crypto/tls: failed to parse certificate PEM data") return } keyDERBlock, _ := pem.Decode(keyPEMBlock) if keyDERBlock == nil { err = errors.New("crypto/tls: failed to parse key PEM data") return } // OpenSSL 0.9.8 generates PKCS#1 private keys by default, while // OpenSSL 1.0.0 generates PKCS#8 keys. We try both. var key *rsa.PrivateKey if key, err = x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes); err != nil { var privKey interface{} if privKey, err = x509.ParsePKCS8PrivateKey(keyDERBlock.Bytes); err != nil { err = errors.New("crypto/tls: failed to parse key: " + err.Error()) return } var ok bool if key, ok = privKey.(*rsa.PrivateKey); !ok { err = errors.New("crypto/tls: found non-RSA private key in PKCS#8 wrapping") return } } cert.PrivateKey = key return }
func main() { flag.Parse() // Generate CA caCert, caKey, err := generateCertificate(certificateConfig{ isCA: true, hosts: []string{""}, keyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, extKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, }) if err != nil { log.Fatal(err) } err = writeCert("ca", caCert, caKey) if err != nil { log.Fatal(err) } caParsedCertificates, err := x509.ParseCertificates(caCert) if err != nil { log.Fatal(err) } // Generate Server Certificates hosts := make([]string, 0) for _, h := range strings.Split(host, ",") { if h == "" { continue } hosts = append(hosts, h) } hosts = append(hosts, serverSubjectAlternateNames...) serverCert, serverKey, err := generateCertificate(certificateConfig{ caCert: caParsedCertificates[0], caKey: caKey, hosts: hosts, keyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, extKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, }) if err != nil { log.Fatal(err) } err = writeCert("server", serverCert, serverKey) if err != nil { log.Fatal(err) } }
func buildCert(decorator templateDecorator) (*x509.Certificate, *rsa.PrivateKey, error) { priv, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { return nil, nil, err } serial := randBigInt() keyId := randBytes() template := x509.Certificate{ Version: 3, Subject: pkix.Name{ Country: []string{"US"}, Province: []string{"CA"}, Locality: []string{"SF"}, Organization: []string{"Cheeseman"}, }, SerialNumber: serial, NotBefore: time.Now().Add(-5 * time.Minute).UTC(), NotAfter: time.Now().Add(5 * time.Minute).UTC(), SubjectKeyId: keyId, } cert, parentCert, parentKey, err := decorator(&template) if err != nil { return nil, nil, err } if parentKey == nil { parentKey = priv } derBytes, err := x509.CreateCertificate(rand.Reader, cert, parentCert, &priv.PublicKey, parentKey) if err != nil { return nil, nil, err } certs, err := x509.ParseCertificates(derBytes) if err != nil { return nil, nil, err } if len(certs) != 1 { return nil, nil, newError("Failed to generate a parsable certificate") } return certs[0], priv, nil }
// validCert parses a cert chain provided as der argument and verifies the leaf, der[0], // corresponds to the private key, as well as the domain match and expiration dates. // It doesn't do any revocation checking. // // The returned value is the verified leaf cert. func validCert(domain string, der [][]byte, key crypto.Signer) (leaf *x509.Certificate, err error) { // parse public part(s) var n int for _, b := range der { n += len(b) } pub := make([]byte, n) n = 0 for _, b := range der { n += copy(pub[n:], b) } x509Cert, err := x509.ParseCertificates(pub) if len(x509Cert) == 0 { return nil, errors.New("acme/autocert: no public key found") } // verify the leaf is not expired and matches the domain name leaf = x509Cert[0] now := timeNow() if now.Before(leaf.NotBefore) { return nil, errors.New("acme/autocert: certificate is not valid yet") } if now.After(leaf.NotAfter) { return nil, errors.New("acme/autocert: expired certificate") } if err := leaf.VerifyHostname(domain); err != nil { return nil, err } // ensure the leaf corresponds to the private key switch pub := leaf.PublicKey.(type) { case *rsa.PublicKey: prv, ok := key.(*rsa.PrivateKey) if !ok { return nil, errors.New("acme/autocert: private key type does not match public key type") } if pub.N.Cmp(prv.N) != 0 { return nil, errors.New("acme/autocert: private key does not match public key") } case *ecdsa.PublicKey: prv, ok := key.(*ecdsa.PrivateKey) if !ok { return nil, errors.New("acme/autocert: private key type does not match public key type") } if pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 { return nil, errors.New("acme/autocert: private key does not match public key") } default: return nil, errors.New("acme/autocert: unknown public key algorithm") } return leaf, nil }
func init() { serverConf = makeTLSConfig("./config/development_cert.pem", "./config/development_key.pem") certBytes, err := ioutil.ReadFile("./config/development_ca_cert.pem") if err != nil { log.Fatal(err) } cblock, _ := pem.Decode(certBytes) certs, err := x509.ParseCertificates(cblock.Bytes) if err != nil { log.Fatalf("x509.ParseCertificates: %s", err) } rootCA = certs[0] }