예제 #1
1
// 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
}
예제 #2
0
파일: pki.go 프로젝트: hujun-open/manpass
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")

}
예제 #3
0
파일: pki.go 프로젝트: hujun-open/manpass
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")
}
예제 #4
0
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)
}
예제 #6
0
func certSignature(cert tls.Certificate) (string, error) {
	x509Certs, err := x509.ParseCertificates(cert.Certificate[0])
	if err != nil {
		return "", err
	}
	return x509CertSignature(x509Certs[0]), nil
}
예제 #7
0
파일: pkcs7.go 프로젝트: hildjj/boulder
// 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

}
예제 #8
0
파일: io.go 프로젝트: catalyzeio/cli
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
	}
}
예제 #9
0
파일: tls.go 프로젝트: shenshouer/ngrok
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
}
예제 #10
0
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",
	}
}
예제 #11
0
파일: helpers.go 프로젝트: geligaoli/cfssl
// 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
}
예제 #12
0
파일: pkcs7.go 프로젝트: jig/pkcs7
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
}
예제 #13
0
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
}
예제 #14
0
파일: tls.go 프로젝트: koolshare/ngrok-1.7
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
}
예제 #15
0
// 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

}
예제 #16
0
// 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
}
예제 #17
0
파일: hash.go 프로젝트: JonathanLogan/mute
// 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
}
예제 #18
0
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]
}
예제 #19
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)
	}
}
예제 #20
0
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)
}
예제 #21
0
// 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
}
예제 #22
0
/*
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
}
예제 #23
0
파일: x509ez.go 프로젝트: polvi/cad
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
}
예제 #24
0
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)
}
예제 #25
0
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
}
예제 #26
0
// 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)
	}
}
예제 #28
0
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
}
예제 #29
0
// 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
}
예제 #30
0
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]
}