Beispiel #1
0
func init() {
	// Setup the updateURL if the environment variable is set
	envApi := os.Getenv("CORE_UPDATE_URL")
	if envApi != "" {
		envUrl, err := url.Parse(envApi)
		if err != nil {
			fmt.Printf("Error: couldn't parse CORE_UPDATE_URL: %s", err.Error())
			os.Exit(-1)
		}
		updateURL = *envUrl
	}
	pool := x509.NewCertPool()

	coreosInetPemBlock, _ := pem.Decode([]byte(certs.CoreOS_Internet_Authority_pem))
	if coreosInetPemBlock == nil {
		panic("Error: No PEM data found in CoreOS_Internet_Auth")
	}

	coreosNetPemBlock, _ := pem.Decode([]byte(certs.CoreOS_Internet_Authority_pem))
	if coreosNetPemBlock == nil {
		panic("Error: No PEM data found in CoreOS_Network_Auth")
	}

	coreosInetAuthCert, err := x509.ParseCertificate(coreosInetPemBlock.Bytes)
	if err != nil {
		panic(err.Error())
	}
	coreosNetAuthCert, err := x509.ParseCertificate(coreosNetPemBlock.Bytes)
	if err != nil {
		panic(err.Error())
	}
	pool.AddCert(coreosNetAuthCert)
	pool.AddCert(coreosInetAuthCert)
	tlsTransport.TLSClientConfig = &tls.Config{RootCAs: pool}
}
Beispiel #2
0
func VerifyDerCert(der_cert []byte, der_signing_cert []byte) (bool, error) {
	roots := x509.NewCertPool()
	opts := x509.VerifyOptions{
		Roots: roots,
	}

	// Verify key
	policy_cert, err := x509.ParseCertificate(der_signing_cert)
	if err != nil {
		return false, errors.New("Signing ParseCertificate fails")
	}
	roots.AddCert(policy_cert)
	fmt.Printf("Root cert: %x\n", der_signing_cert)

	// Verify key
	cert, err := x509.ParseCertificate(der_cert)
	if err != nil {
		return false, errors.New("Cert ParseCertificate fails")
	}

	roots.AddCert(policy_cert)
	opts.Roots = roots
	chains, err := cert.Verify(opts)
	if err != nil {
		return false, errors.New("Verify fails")
	}
	if chains != nil {
		return true, nil
	} else {
		return false, nil
	}

}
func TestCreateCertificateCahin(t *testing.T) {
	ca, caPriv := createCA()
	caPub := key.PublicKey(caPriv)
	caBytes := Sign(ca, ca, caPub, caPriv)
	interCa, interCaPriv := createInterCA()
	interCaPub := key.PublicKey(interCaPriv)
	interCaBytes := Sign(interCa, ca, interCaPub, caPriv)
	client, clientPriv := createClient()
	clientPub := key.PublicKey(clientPriv)
	clientBytes := Sign(client, interCa, clientPub, interCaPriv)

	clientCert, _ := x509.ParseCertificate(clientBytes)
	ouIssuer := getPkixValue(clientCert.Issuer.Names, OU)
	if ouIssuer != "WebInterCA" {
		t.Fatalf("Wrong issuer ou wanted: WebInterCA, got: %v\n", ouIssuer)
	}
	interCert, _ := x509.ParseCertificate(interCaBytes)
	ouIssuer = getPkixValue(interCert.Issuer.Names, OU)
	if ouIssuer != "WebCA" {
		t.Fatalf("Wrong issuer ou wanted: WebCA, got: %v\n", ouIssuer)
	}
	caCert, _ := x509.ParseCertificate(caBytes)
	ouIssuer = getPkixValue(caCert.Issuer.Names, OU)
	if ouIssuer != "WebCA" {
		t.Fatalf("Wrong issuer ou wanted: WebCA, got: %v\n", ouIssuer)
	}
}
Beispiel #4
0
func TestOCSP(t *testing.T) {
	b, err := acmeutils.LoadCertificates([]byte(testOCSPCerts))
	if err != nil {
		t.Fatalf("cannot load certificates")
	}

	c0, err := x509.ParseCertificate(b[0])
	if err != nil {
		t.Fatalf("cannot parse certificate")
	}

	c1, err := x509.ParseCertificate(b[1])
	if err != nil {
		t.Fatalf("cannot parse certificate")
	}

	cl := Client{}

	res, err := cl.CheckOCSP(c0, c1, context.TODO())
	if err != nil {
		t.Fatalf("ocsp error: %v", err)
	}

	if res.Status != ocsp.Revoked {
		t.Fatalf("ocsp status should be revoked (1) but is %v", res.Status)
	}
}
Beispiel #5
0
func readFiles(c *cli.Context) (issuer, responder, target *x509.Certificate, template ocsp.Response, pkcs11 PKCS11Config, err error) {
	// Issuer certificate
	issuerFileName := c.GlobalString("issuer")
	issuerBytes, err := ioutil.ReadFile(issuerFileName)
	if err != nil {
		return
	}

	issuer, err = x509.ParseCertificate(issuerBytes)
	if err != nil {
		return
	}

	// Responder certificate
	responderFileName := c.GlobalString("responder")
	responderBytes, err := ioutil.ReadFile(responderFileName)
	if err != nil {
		return
	}

	responder, err = x509.ParseCertificate(responderBytes)
	if err != nil {
		return
	}

	// Target certificate
	targetFileName := c.GlobalString("target")
	targetBytes, err := ioutil.ReadFile(targetFileName)
	if err != nil {
		return
	}

	target, err = x509.ParseCertificate(targetBytes)
	if err != nil {
		return
	}

	// OCSP template
	templateFileName := c.GlobalString("template")
	templateBytes, err := ioutil.ReadFile(templateFileName)
	if err != nil {
		return
	}

	err = json.Unmarshal(templateBytes, &template)
	if err != nil {
		return
	}

	// PKCS#11 config
	pkcs11FileName := c.GlobalString("pkcs11")
	pkcs11Bytes, err := ioutil.ReadFile(pkcs11FileName)
	if err != nil {
		return
	}

	err = json.Unmarshal(pkcs11Bytes, &pkcs11)
	return
}
Beispiel #6
0
func parseAndVerifyCertChain(x5c []string, roots *x509.CertPool) (leafKey libtrust.PublicKey, err error) {
	if len(x5c) == 0 {
		return nil, errors.New("empty x509 certificate chain")
	}

	// Ensure the first element is encoded correctly.
	leafCertDer, err := base64.StdEncoding.DecodeString(x5c[0])
	if err != nil {
		return nil, fmt.Errorf("unable to decode leaf certificate: %s", err)
	}

	// And that it is a valid x509 certificate.
	leafCert, err := x509.ParseCertificate(leafCertDer)
	if err != nil {
		return nil, fmt.Errorf("unable to parse leaf certificate: %s", err)
	}

	// The rest of the certificate chain are intermediate certificates.
	intermediates := x509.NewCertPool()
	for i := 1; i < len(x5c); i++ {
		intermediateCertDer, err := base64.StdEncoding.DecodeString(x5c[i])
		if err != nil {
			return nil, fmt.Errorf("unable to decode intermediate certificate: %s", err)
		}

		intermediateCert, err := x509.ParseCertificate(intermediateCertDer)
		if err != nil {
			return nil, fmt.Errorf("unable to parse intermediate certificate: %s", err)
		}

		intermediates.AddCert(intermediateCert)
	}

	verifyOpts := x509.VerifyOptions{
		Intermediates: intermediates,
		Roots:         roots,
		KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
	}

	// TODO: this call returns certificate chains which we ignore for now, but
	// we should check them for revocations if we have the ability later.
	if _, err = leafCert.Verify(verifyOpts); err != nil {
		return nil, fmt.Errorf("unable to verify certificate chain: %s", err)
	}

	// Get the public key from the leaf certificate.
	leafCryptoKey, ok := leafCert.PublicKey.(crypto.PublicKey)
	if !ok {
		return nil, errors.New("unable to get leaf cert public key value")
	}

	leafKey, err = libtrust.FromCryptoPublicKey(leafCryptoKey)
	if err != nil {
		return nil, fmt.Errorf("unable to make libtrust public key from leaf certificate: %s", err)
	}

	return
}
// Verify x509 certificate chain
func (x5c X5C) verifyCertChain() (leaf *x509.Certificate, validCN bool, err error) {
	if len(x5c) == 0 || len(x5c) > 10 {
		// OpenSSL's default maximum chain length is 10
		return nil, false, fmt.Errorf("Invalid certchain length of %d\n", len(x5c))
	}

	// Parse leaf certificate
	leafCertDer, err := base64.StdEncoding.DecodeString(x5c[0])
	if err != nil {
		return nil, false, err
	}
	leafCert, err := x509.ParseCertificate(leafCertDer)
	if err != nil {
		return nil, false, err
	}

	// Verify CN
	if leafCert.Subject.CommonName == safetynetCN {
		validCN = true
	}

	// Parse and add intermediate certificates
	intermediates := x509.NewCertPool()
	for i := 1; i < len(x5c); i++ {
		intermediateCertDer, err := base64.StdEncoding.DecodeString(x5c[i])
		if err != nil {
			return leafCert, false, err
		}

		intermediateCert, err := x509.ParseCertificate(intermediateCertDer)
		if err != nil {
			return leafCert, false, err
		}
		intermediates.AddCert(intermediateCert)
	}

	// Parse and verify root cert
	roots := x509.NewCertPool()
	ok := roots.AppendCertsFromPEM([]byte(geotrustCert))
	if !ok {
		return leafCert, false, fmt.Errorf("Failed to append GEOTRUST cert\n")
	}

	// Verify leaf certificate
	storeCtx := x509.VerifyOptions{
		Intermediates: intermediates,
		Roots:         roots,
		KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
	}
	_, err = leafCert.Verify(storeCtx)
	if err != nil {
		return leafCert, false, err
	}

	return leafCert, validCN, nil
}
Beispiel #8
0
func readPem(p string) (*x509.Certificate, error) {
	block, e := pem.Decode([]byte(p))
	if block != nil {
		return x509.ParseCertificate(block.Bytes)
	}
	if e != nil {
		return x509.ParseCertificate(e)
	}
	return nil, errors.New("x509 format error")
}
Beispiel #9
0
func main() {
	// input config file contains initial_keyserver_auth and keyserver_addr
	// this file will be provided by keyserver admin
	if len(os.Args) != 5 {
		fmt.Printf("usage: %s cacert cert id inputcfg\n", os.Args[0])
		return
	}
	caCertFile := os.Args[1]
	certFile := os.Args[2]
	cfgF := os.Args[4]
	id, err := strconv.ParseUint(os.Args[3], 10, 64)
	if err != nil {
		log.Fatalf("Failed to convert %v to uint: %v", os.Args[3], err)
	}
	caCertPem, err := ioutil.ReadFile(caCertFile)
	if err != nil {
		log.Fatalf("Failed to read from %v: %v", caCertFile, err)
	}
	caCertBlock, _ := pem.Decode(caCertPem)
	if caCertBlock == nil {
		log.Fatalf("Failed to parse PEM: %v", string(caCertPem))
	}
	caCert, err := x509.ParseCertificate(caCertBlock.Bytes)
	if err != nil {
		log.Fatalf("Failed to parse X.509 cert: %v", err)
	}

	certPEM, err := ioutil.ReadFile(certFile)
	if err != nil {
		log.Fatalf("Failed to read from %v: %v", certFile, err)
	}

	certBlock, _ := pem.Decode(certPEM)
	if certBlock == nil {
		log.Fatalf("Failed to parse PEM: %v", string(certPEM))
	}
	cert, err := x509.ParseCertificate(certBlock.Bytes)
	if err != nil {
		log.Fatalf("Failed to parse X.509 cert: %v", err)
	}

	configReader, err := os.Open(cfgF)
	if err != nil {
		log.Fatalf("Failed to open input configuration file %v: %v", cfgF, err)
	}
	cfg := &proto.VerifierConfig{}
	err = jsonpb.Unmarshal(configReader, cfg)
	if err != nil {
		log.Fatalf("Failed to parse input configuration file %v: %v", cfgF, err)
	}

	make_config(caCert, cert, uint64(id), cfg)
}
Beispiel #10
0
func (m *Meta) loadCertFromPEM(path string) ([]*x509.Certificate, error) {
	pemCerts, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	certs := make([]*x509.Certificate, 0, 5)
	for len(pemCerts) > 0 {
		var block *pem.Block
		block, pemCerts = pem.Decode(pemCerts)
		if block == nil {
			break
		}
		if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
			continue
		}

		cert, err := x509.ParseCertificate(block.Bytes)
		if err != nil {
			return nil, err
		}

		certs = append(certs, cert)
	}

	return certs, nil
}
Beispiel #11
0
func DetermineKeyIDFromPublicKey(pubk crypto.PublicKey) (string, error) {
	// Trick crypto/x509 into creating a certificate so we can grab the
	// subjectPublicKeyInfo by giving it a fake private key generating an invalid
	// signature. ParseCertificate doesn't verify the signature so this will
	// work.
	//
	// Yes, this is very hacky, but avoids having to duplicate code in crypto/x509.

	determineKeyIDFromKeyIntl(pubk, psuedoPrivateKey{})

	cc := &x509.Certificate{
		SerialNumber: big.NewInt(1),
	}
	cb, err := x509.CreateCertificate(rand.Reader, cc, cc, pubk, &psuedoPrivateKey{pubk})
	if err != nil {
		return "", err
	}

	c, err := x509.ParseCertificate(cb)
	if err != nil {
		return "", err
	}

	return determineKeyIDFromCert(c), nil
}
Beispiel #12
0
func NewSignedCertificate(cfg CertConfig, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) {
	serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
	if err != nil {
		return nil, err
	}

	certTmpl := x509.Certificate{
		Subject: pkix.Name{
			CommonName:   cfg.CommonName,
			Organization: caCert.Subject.Organization,
		},
		DNSNames:     cfg.AltNames.DNSNames,
		IPAddresses:  cfg.AltNames.IPs,
		SerialNumber: serial,
		NotBefore:    caCert.NotBefore,
		NotAfter:     time.Now().Add(Duration365d).UTC(),
		KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
	}
	certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey)
	if err != nil {
		return nil, err
	}
	return x509.ParseCertificate(certDERBytes)
}
Beispiel #13
0
func checkRouteCertificate(r diagnosticReporter, route routes.Route) {
	r.Debug("AGL0330", fmt.Sprintf("Checking certificate for route '%s'...", route.ObjectMeta.Name))
	block, _ := pem.Decode([]byte(route.Spec.TLS.Certificate))
	//verify hostname
	if block != nil {
		cert, err := x509.ParseCertificate(block.Bytes)
		if err != nil {
			r.Error("AGL0335", err, fmt.Sprintf("Unable to parse the certificate for route '%s': %s", route.ObjectMeta.Name, err))
			return
		}
		r.Debug("AGL0340", fmt.Sprintf("Cert CommonName: '%s' Cert DNSNames: '%s'", cert.Subject.CommonName, cert.DNSNames))
		if err := cert.VerifyHostname(route.Spec.Host); err != nil {
			r.Error("AGL0345", err, fmt.Sprintf("Route '%[1]s' certficate does not include route host '%[2]s'"+routeCertMissingHostName, route.ObjectMeta.Name, route.Spec.Host))
		}
	} else {
		r.Error("AGL0350", errors.New("Unable to decode the TLS Certificate"), "Unable to decode the TLS Certificate")
	}

	//verify key matches cert
	r.Debug("AGL0355", fmt.Sprintf("Checking certificate matches key for route '%s'", route.ObjectMeta.Name))
	_, err := tls.X509KeyPair([]byte(route.Spec.TLS.Certificate), []byte(route.Spec.TLS.Key))
	if err != nil {
		r.Error("AGL0365", err, fmt.Sprintf("Route '%s' key and certificate do not match: %s.  The router will be unable to pass traffic using this route.", route.ObjectMeta.Name, err))
	}
}
func TestRevoke(t *testing.T) {
	cadb, storageAuthority, caConfig := setup(t)
	ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile)
	test.AssertNotError(t, err, "Failed to create CA")
	if err != nil {
		return
	}
	ca.SA = storageAuthority
	ca.MaxKeySize = 4096

	csrDER, _ := hex.DecodeString(CNandSANCSRhex)
	csr, _ := x509.ParseCertificateRequest(csrDER)
	certObj, err := ca.IssueCertificate(*csr, 1, FarFuture)
	test.AssertNotError(t, err, "Failed to sign certificate")
	if err != nil {
		return
	}
	cert, err := x509.ParseCertificate(certObj.DER)
	test.AssertNotError(t, err, "Certificate failed to parse")
	serialString := core.SerialToString(cert.SerialNumber)
	err = ca.RevokeCertificate(serialString, 0)
	test.AssertNotError(t, err, "Revocation failed")

	status, err := storageAuthority.GetCertificateStatus(serialString)
	test.AssertNotError(t, err, "Failed to get cert status")

	test.AssertEquals(t, status.Status, core.OCSPStatusRevoked)
	test.Assert(t, time.Now().Sub(status.OCSPLastUpdated) > time.Second,
		fmt.Sprintf("OCSP LastUpdated was wrong: %v", status.OCSPLastUpdated))
}
Beispiel #15
0
// parsePEMBundle parses a certificate bundle from top to bottom and returns
// a slice of x509 certificates. This function will error if no certificates are found.
func parsePEMBundle(bundle []byte) ([]*x509.Certificate, error) {
	var certificates []*x509.Certificate

	remaining := bundle
	for len(remaining) != 0 {
		certBlock, rem := pem.Decode(remaining)
		// Thanks golang for having me do this :[
		remaining = rem
		if certBlock == nil {
			return nil, errors.New("Could not decode certificate.")
		}

		cert, err := x509.ParseCertificate(certBlock.Bytes)
		if err != nil {
			return nil, err
		}

		certificates = append(certificates, cert)
	}

	if len(certificates) == 0 {
		return nil, errors.New("No certificates were found while parsing the bundle.")
	}

	return certificates, nil
}
Beispiel #16
0
// getIssuerCertificate requests the issuer certificate and caches it for
// subsequent requests.
func (c *Client) getIssuerCertificate(url string) ([]byte, error) {
	logf("[INFO] acme: Requesting issuer cert from %s", url)
	if c.issuerCert != nil {
		return c.issuerCert, nil
	}

	resp, err := httpGet(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	issuerBytes, err := ioutil.ReadAll(limitReader(resp.Body, 1024*1024))
	if err != nil {
		return nil, err
	}

	_, err = x509.ParseCertificate(issuerBytes)
	if err != nil {
		return nil, err
	}

	c.issuerCert = issuerBytes
	return issuerBytes, err
}
Beispiel #17
0
func (repo CloudControllerBuildpackBitsRepository) downloadBuildpack(url string, cb func(*os.File, error)) {
	fileutils.TempFile("buildpack-download", func(tempfile *os.File, err error) {
		if err != nil {
			cb(nil, err)
			return
		}

		var certPool *x509.CertPool
		if len(repo.TrustedCerts) > 0 {
			certPool = x509.NewCertPool()
			for _, tlsCert := range repo.TrustedCerts {
				cert, _ := x509.ParseCertificate(tlsCert.Certificate[0])
				certPool.AddCert(cert)
			}
		}

		client := &http.Client{
			Transport: &http.Transport{
				TLSClientConfig: &tls.Config{RootCAs: certPool},
				Proxy:           http.ProxyFromEnvironment,
			},
		}

		response, err := client.Get(url)
		if err != nil {
			cb(nil, err)
			return
		}

		io.Copy(tempfile, response.Body)
		tempfile.Seek(0, 0)
		cb(tempfile, nil)
	})
}
Beispiel #18
0
// ReadCertificate reads a transaction certificate from the TCA.
//
func (tcap *TCAP) ReadCertificate(ctx context.Context, req *pb.TCertReadReq) (*pb.Cert, error) {
	Trace.Println("grpc TCAP:ReadCertificate")

	id := req.Id.Id
	raw, err := tcap.tca.eca.readCertificate(id, x509.KeyUsageDigitalSignature)
	if err != nil {
		return nil, err
	}
	cert, err := x509.ParseCertificate(raw)
	if err != nil {
		return nil, err
	}

	sig := req.Sig
	req.Sig = nil

	r, s := big.NewInt(0), big.NewInt(0)
	r.UnmarshalText(sig.R)
	s.UnmarshalText(sig.S)

	hash := sha3.New384()
	raw, _ = proto.Marshal(req)
	hash.Write(raw)
	if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false {
		return nil, errors.New("signature does not verify")
	}

	raw, err = tcap.tca.readCertificate1(id, req.Ts.Seconds)
	if err != nil {
		return nil, err
	}

	return &pb.Cert{raw}, nil
}
Beispiel #19
0
// This is used to detertmine whether to cull certificates.
func CertificateGenerallyValid(c *storage.Certificate) bool {
	// This function is very conservative because if we return false
	// the certificate will get deleted. Revocation and expiry are
	// good reasons to delete. We already know the certificate is
	// unreferenced.

	if c.Revoked {
		log.Debugf("%v not generally valid because it is revoked", c)
		return false
	}

	if len(c.Certificates) == 0 {
		// If we have no actual certificates, give the benefit of the doubt.
		// Maybe the certificate is undownloaded.
		log.Debugf("%v has no actual certificates, assuming valid", c)
		return true
	}

	cc, err := x509.ParseCertificate(c.Certificates[0])
	if err != nil {
		log.Debugf("%v cannot be parsed, assuming valid", c)
		return false
	}

	if !InternalClock.Now().Before(cc.NotAfter) {
		log.Debugf("%v not generally valid because it is expired", c)
		return false
	}

	return true
}
Beispiel #20
0
// LoadCertBundle loads a PEM bundle of certificates from disk
func LoadCertBundle(filename string) ([]*x509.Certificate, error) {
	bundleBytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	var bundle []*x509.Certificate
	var block *pem.Block
	rest := bundleBytes
	for {
		block, rest = pem.Decode(rest)
		if block == nil {
			break
		}
		if block.Type != "CERTIFICATE" {
			return nil, fmt.Errorf("Block has invalid type: %s", block.Type)
		}
		cert, err := x509.ParseCertificate(block.Bytes)
		if err != nil {
			return nil, err
		}
		bundle = append(bundle, cert)
	}

	if len(bundle) == 0 {
		return nil, fmt.Errorf("Bundle doesn't contain any certificates")
	}

	return bundle, nil
}
func TestDeduplication(t *testing.T) {
	cadb, storageAuthority, caConfig := setup(t)
	ca, err := NewCertificateAuthorityImpl(cadb, caConfig, caCertFile)
	test.AssertNotError(t, err, "Failed to create CA")
	ca.SA = storageAuthority
	ca.MaxKeySize = 4096

	// Test that the CA collapses duplicate names
	csrDER, _ := hex.DecodeString(DupeNameCSRhex)
	csr, _ := x509.ParseCertificateRequest(csrDER)
	cert, err := ca.IssueCertificate(*csr, 1, FarFuture)
	test.AssertNotError(t, err, "Failed to gracefully handle a CSR with duplicate names")
	if err != nil {
		return
	}

	parsedCert, err := x509.ParseCertificate(cert.DER)
	test.AssertNotError(t, err, "Error parsing certificate produced by CA")
	if err != nil {
		return
	}

	correctName := "a.not-example.com"
	correctNames := len(parsedCert.DNSNames) == 1 &&
		parsedCert.DNSNames[0] == correctName &&
		parsedCert.Subject.CommonName == correctName
	test.Assert(t, correctNames, "Incorrect set of names in deduplicated certificate")
}
Beispiel #22
0
// AddCertFromPEM adds a certificate to the store from a PEM blob
func (s X509MemStore) AddCertFromPEM(pemCerts []byte) error {
	ok := false
	for len(pemCerts) > 0 {
		var block *pem.Block
		block, pemCerts = pem.Decode(pemCerts)
		if block == nil {
			return errors.New("no PEM data found")
		}
		if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
			continue
		}

		cert, err := x509.ParseCertificate(block.Bytes)
		if err != nil {
			return errors.New("error while parsing PEM certificate")
		}

		s.AddCert(cert)
		ok = true
	}

	if !ok {
		return errors.New("no certificates found in PEM data")
	}
	return nil
}
Beispiel #23
0
// sendPurge should only be called as a Goroutine as it will block until the purge
// request is successful
func (updater *OCSPUpdater) sendPurge(der []byte) {
	cert, err := x509.ParseCertificate(der)
	if err != nil {
		updater.log.AuditErr(fmt.Errorf("Failed to parse certificate for cache purge: %s", err))
		return
	}

	req, err := ocsp.CreateRequest(cert, updater.issuer, nil)
	if err != nil {
		updater.log.AuditErr(fmt.Errorf("Failed to create OCSP request for cache purge: %s", err))
		return
	}

	// Create a GET style OCSP url for each endpoint in cert.OCSPServer (still waiting
	// on word from Akamai on how to properly purge cached POST requests, for now just
	// do GET)
	urls := []string{}
	for _, ocspServer := range cert.OCSPServer {
		urls = append(
			urls,
			path.Join(ocspServer, url.QueryEscape(base64.StdEncoding.EncodeToString(req))),
		)
	}

	err = updater.ccu.Purge(urls)
	if err != nil {
		updater.log.AuditErr(fmt.Errorf("Failed to purge OCSP response from CDN: %s", err))
	}
}
Beispiel #24
0
// fetchRemoteCertificate retrieves a single URL pointing to a certificate
// and attempts to first parse it as a DER-encoded certificate; if
// this fails, it attempts to decode it as a PEM-encoded certificate.
func fetchRemoteCertificate(certURL string) (fi *fetchedIntermediate, err error) {
	log.Debugf("fetching remote certificate: %s", certURL)
	var resp *http.Response
	resp, err = http.Get(certURL)
	if err != nil {
		log.Debugf("failed HTTP get: %v", err)
		return
	}

	defer resp.Body.Close()
	var certData []byte
	certData, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Debugf("failed to read response body: %v", err)
		return
	}

	log.Debugf("attempting to parse certificate as DER")
	crt, err := x509.ParseCertificate(certData)
	if err != nil {
		log.Debugf("attempting to parse certificate as PEM")
		crt, err = helpers.ParseCertificatePEM(certData)
		if err != nil {
			log.Debugf("failed to parse certificate: %v", err)
			return
		}
	}

	log.Debugf("certificate fetch succeeds")
	fi = &fetchedIntermediate{Cert: crt, Name: constructCertFileName(crt)}
	return
}
Beispiel #25
0
func ParsePEMEncodedCACert(pemdata []byte) (*x509.Certificate, error) {
	decoded, _ := pem.Decode(pemdata)
	if decoded == nil {
		return nil, errors.New("no PEM data found")
	}
	return x509.ParseCertificate(decoded.Bytes)
}
Beispiel #26
0
// GenerateCertificate generates an X509 Certificate from a template, given a GUN
func GenerateCertificate(rootKey data.PrivateKey, gun string) (*x509.Certificate, error) {

	switch rootKey.(type) {
	case *data.RSAPrivateKey, *data.ECDSAPrivateKey:
		// go doesn't fall through
	default:
		return nil, fmt.Errorf("only bare RSA or ECDSA keys (not x509 variants) are currently supported. Found: %s", rootKey.Algorithm())
	}

	template, err := trustmanager.NewCertificate(gun)
	if err != nil {
		return nil, fmt.Errorf("failed to create the certificate template for: %s (%v)", gun, err)
	}

	derBytes, err := x509.CreateCertificate(rand.Reader, template, template, rootKey.CryptoSigner().Public(), rootKey.CryptoSigner())
	if err != nil {
		return nil, fmt.Errorf("failed to create the certificate for: %s (%v)", gun, err)
	}

	// Encode the new certificate into PEM
	cert, err := x509.ParseCertificate(derBytes)
	if err != nil {
		return nil, fmt.Errorf("failed to parse the certificate for key: %s (%v)", gun, err)
	}

	return cert, nil
}
Beispiel #27
0
// ParseOneCertificateFromPEM attempts to parse one PEM encoded certificate object,
// either a raw x509 certificate or a PKCS #7 structure possibly containing
// multiple certificates, from the top of certsPEM, which itself may
// contain multiple PEM encoded certificate objects.
func ParseOneCertificateFromPEM(certsPEM []byte) ([]*x509.Certificate, []byte, error) {

	block, rest := pem.Decode(certsPEM)
	if block == nil {
		return nil, rest, nil
	}

	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		pkcs7data, err := pkcs7.ParsePKCS7(block.Bytes)
		if err != nil {
			return nil, rest, err
		}
		if pkcs7data.ContentInfo != "SignedData" {
			return nil, rest, errors.New("only PKCS #7 Signed Data Content Info supported for certificate parsing")
		}
		certs := pkcs7data.Content.SignedData.Certificates
		if certs == nil {
			return nil, rest, errors.New("PKCS #7 structure contains no certificates")
		}
		return certs, rest, nil
	}
	var certs = []*x509.Certificate{cert}
	return certs, rest, nil
}
Beispiel #28
0
func (s *Server) processEntry(logID int64, tx *sql.Tx, txpr *prepareds, hnQueue *[]hostnameQueueItem, observed *[]observationQueueItem, e *ctclient.Entry, logIndex int64) error {
	cert, err := x509.ParseCertificate(e.LeafCertificate)
	if err != nil {
		return fmt.Errorf("Failed to parse X.509 certificate: %v", err)
	}

	h := sha256.New()
	h.Write(e.LeafCertificate)
	certHash := h.Sum(nil)

	var certID int64
	var ncertID int64
	err = txpr.InsertCertificate.QueryRow(certHash, cert.NotBefore, cert.NotAfter).Scan(&certID, &ncertID)
	if err != nil {
		return err
	}

	wasInserted := certID == ncertID

	if wasInserted {
		hostnames := getCertificateHostnames(cert)
		for hostname := range hostnames {
			*hnQueue = append(*hnQueue, hostnameQueueItem{certID, hostname})
		}
	}

	*observed = append(*observed, observationQueueItem{
		CertificateID: certID,
		LogIndex:      logIndex,
	})

	log.Debugf("log %d: entry %d", logID, logIndex)
	return nil
}
Beispiel #29
0
func CertsFromPEM(pemCerts []byte) ([]*x509.Certificate, error) {
	ok := false
	certs := []*x509.Certificate{}
	for len(pemCerts) > 0 {
		var block *pem.Block
		block, pemCerts = pem.Decode(pemCerts)
		if block == nil {
			break
		}
		if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
			continue
		}

		cert, err := x509.ParseCertificate(block.Bytes)
		if err != nil {
			return certs, err
		}

		certs = append(certs, cert)
		ok = true
	}

	if !ok {
		return certs, errors.New("Could not read any certificates")
	}
	return certs, nil
}
Beispiel #30
0
// validateCertificatePEM checks if a certificate PEM is valid and
// optionally verifies the certificate using the options.
func validateCertificatePEM(certPEM string, options *x509.VerifyOptions) (*x509.Certificate, error) {
	var data *pem.Block
	for remaining := []byte(certPEM); len(remaining) > 0; {
		block, rest := pem.Decode(remaining)
		if block == nil {
			return nil, fmt.Errorf("error decoding certificate data")
		}
		if block.Type == "CERTIFICATE" {
			data = block
			break
		}
		remaining = rest
	}

	if data == nil || len(data.Bytes) < 1 {
		return nil, fmt.Errorf("invalid/empty certificate data")
	}

	cert, err := x509.ParseCertificate(data.Bytes)
	if err != nil {
		return nil, fmt.Errorf("error parsing certificate: %s", err.Error())
	}

	if options != nil {
		_, err = cert.Verify(*options)
		if err != nil {
			return cert, fmt.Errorf("error verifying certificate: %s", err.Error())
		}
	}

	return cert, nil
}