1package certutil
2
3import (
4	"bytes"
5	"crypto"
6	"crypto/ecdsa"
7	"crypto/elliptic"
8	"crypto/rand"
9	"crypto/rsa"
10	"crypto/sha1"
11	"crypto/x509"
12	"crypto/x509/pkix"
13	"encoding/asn1"
14	"encoding/pem"
15	"errors"
16	"fmt"
17	"io"
18	"io/ioutil"
19	"math/big"
20	"net"
21	"net/url"
22	"strconv"
23	"strings"
24	"time"
25
26	"github.com/hashicorp/errwrap"
27	"github.com/hashicorp/vault/sdk/helper/errutil"
28	"github.com/hashicorp/vault/sdk/helper/jsonutil"
29	"github.com/mitchellh/mapstructure"
30	"golang.org/x/crypto/cryptobyte"
31	cbasn1 "golang.org/x/crypto/cryptobyte/asn1"
32)
33
34// GetHexFormatted returns the byte buffer formatted in hex with
35// the specified separator between bytes.
36func GetHexFormatted(buf []byte, sep string) string {
37	var ret bytes.Buffer
38	for _, cur := range buf {
39		if ret.Len() > 0 {
40			fmt.Fprintf(&ret, sep)
41		}
42		fmt.Fprintf(&ret, "%02x", cur)
43	}
44	return ret.String()
45}
46
47// ParseHexFormatted returns the raw bytes from a formatted hex string
48func ParseHexFormatted(in, sep string) []byte {
49	var ret bytes.Buffer
50	var err error
51	var inBits int64
52	inBytes := strings.Split(in, sep)
53	for _, inByte := range inBytes {
54		if inBits, err = strconv.ParseInt(inByte, 16, 8); err != nil {
55			return nil
56		}
57		ret.WriteByte(byte(inBits))
58	}
59	return ret.Bytes()
60}
61
62// GetSubjKeyID returns the subject key ID, e.g. the SHA1 sum
63// of the marshaled public key
64func GetSubjKeyID(privateKey crypto.Signer) ([]byte, error) {
65	if privateKey == nil {
66		return nil, errutil.InternalError{Err: "passed-in private key is nil"}
67	}
68
69	marshaledKey, err := x509.MarshalPKIXPublicKey(privateKey.Public())
70	if err != nil {
71		return nil, errutil.InternalError{Err: fmt.Sprintf("error marshalling public key: %s", err)}
72	}
73
74	subjKeyID := sha1.Sum(marshaledKey)
75
76	return subjKeyID[:], nil
77}
78
79// ParsePKIMap takes a map (for instance, the Secret.Data
80// returned from the PKI backend) and returns a ParsedCertBundle.
81func ParsePKIMap(data map[string]interface{}) (*ParsedCertBundle, error) {
82	result := &CertBundle{}
83	err := mapstructure.Decode(data, result)
84	if err != nil {
85		return nil, errutil.UserError{Err: err.Error()}
86	}
87
88	return result.ToParsedCertBundle()
89}
90
91// ParsePKIJSON takes a JSON-encoded string and returns a ParsedCertBundle.
92//
93// This can be either the output of an
94// issue call from the PKI backend or just its data member; or,
95// JSON not coming from the PKI backend.
96func ParsePKIJSON(input []byte) (*ParsedCertBundle, error) {
97	result := &CertBundle{}
98	err := jsonutil.DecodeJSON(input, &result)
99
100	if err == nil {
101		return result.ToParsedCertBundle()
102	}
103
104	var secret Secret
105	err = jsonutil.DecodeJSON(input, &secret)
106
107	if err == nil {
108		return ParsePKIMap(secret.Data)
109	}
110
111	return nil, errutil.UserError{Err: "unable to parse out of either secret data or a secret object"}
112}
113
114// ParsePEMBundle takes a string of concatenated PEM-format certificate
115// and private key values and decodes/parses them, checking validity along
116// the way. The first certificate must be the subject certificate and issuing
117// certificates may follow.  There must be at most one private key.
118func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) {
119	if len(pemBundle) == 0 {
120		return nil, errutil.UserError{Err: "empty pem bundle"}
121	}
122
123	pemBytes := []byte(pemBundle)
124	var pemBlock *pem.Block
125	parsedBundle := &ParsedCertBundle{}
126	var certPath []*CertBlock
127
128	for len(pemBytes) > 0 {
129		pemBlock, pemBytes = pem.Decode(pemBytes)
130		if pemBlock == nil {
131			return nil, errutil.UserError{Err: "no data found in PEM block"}
132		}
133
134		if signer, err := x509.ParseECPrivateKey(pemBlock.Bytes); err == nil {
135			if parsedBundle.PrivateKeyType != UnknownPrivateKey {
136				return nil, errutil.UserError{Err: "more than one private key given; provide only one private key in the bundle"}
137			}
138			parsedBundle.PrivateKeyFormat = ECBlock
139			parsedBundle.PrivateKeyType = ECPrivateKey
140			parsedBundle.PrivateKeyBytes = pemBlock.Bytes
141			parsedBundle.PrivateKey = signer
142
143		} else if signer, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err == nil {
144			if parsedBundle.PrivateKeyType != UnknownPrivateKey {
145				return nil, errutil.UserError{Err: "more than one private key given; provide only one private key in the bundle"}
146			}
147			parsedBundle.PrivateKeyType = RSAPrivateKey
148			parsedBundle.PrivateKeyFormat = PKCS1Block
149			parsedBundle.PrivateKeyBytes = pemBlock.Bytes
150			parsedBundle.PrivateKey = signer
151		} else if signer, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err == nil {
152			parsedBundle.PrivateKeyFormat = PKCS8Block
153
154			if parsedBundle.PrivateKeyType != UnknownPrivateKey {
155				return nil, errutil.UserError{Err: "More than one private key given; provide only one private key in the bundle"}
156			}
157			switch signer := signer.(type) {
158			case *rsa.PrivateKey:
159				parsedBundle.PrivateKey = signer
160				parsedBundle.PrivateKeyType = RSAPrivateKey
161				parsedBundle.PrivateKeyBytes = pemBlock.Bytes
162			case *ecdsa.PrivateKey:
163				parsedBundle.PrivateKey = signer
164				parsedBundle.PrivateKeyType = ECPrivateKey
165				parsedBundle.PrivateKeyBytes = pemBlock.Bytes
166			}
167		} else if certificates, err := x509.ParseCertificates(pemBlock.Bytes); err == nil {
168			certPath = append(certPath, &CertBlock{
169				Certificate: certificates[0],
170				Bytes:       pemBlock.Bytes,
171			})
172		}
173	}
174
175	for i, certBlock := range certPath {
176		if i == 0 {
177			parsedBundle.Certificate = certBlock.Certificate
178			parsedBundle.CertificateBytes = certBlock.Bytes
179		} else {
180			parsedBundle.CAChain = append(parsedBundle.CAChain, certBlock)
181		}
182	}
183
184	if err := parsedBundle.Verify(); err != nil {
185		return nil, errutil.UserError{Err: fmt.Sprintf("verification of parsed bundle failed: %s", err)}
186	}
187
188	return parsedBundle, nil
189}
190
191// GeneratePrivateKey generates a private key with the specified type and key bits
192func GeneratePrivateKey(keyType string, keyBits int, container ParsedPrivateKeyContainer) error {
193	var err error
194	var privateKeyType PrivateKeyType
195	var privateKeyBytes []byte
196	var privateKey crypto.Signer
197
198	switch keyType {
199	case "rsa":
200		privateKeyType = RSAPrivateKey
201		privateKey, err = rsa.GenerateKey(rand.Reader, keyBits)
202		if err != nil {
203			return errutil.InternalError{Err: fmt.Sprintf("error generating RSA private key: %v", err)}
204		}
205		privateKeyBytes = x509.MarshalPKCS1PrivateKey(privateKey.(*rsa.PrivateKey))
206	case "ec":
207		privateKeyType = ECPrivateKey
208		var curve elliptic.Curve
209		switch keyBits {
210		case 224:
211			curve = elliptic.P224()
212		case 256:
213			curve = elliptic.P256()
214		case 384:
215			curve = elliptic.P384()
216		case 521:
217			curve = elliptic.P521()
218		default:
219			return errutil.UserError{Err: fmt.Sprintf("unsupported bit length for EC key: %d", keyBits)}
220		}
221		privateKey, err = ecdsa.GenerateKey(curve, rand.Reader)
222		if err != nil {
223			return errutil.InternalError{Err: fmt.Sprintf("error generating EC private key: %v", err)}
224		}
225		privateKeyBytes, err = x509.MarshalECPrivateKey(privateKey.(*ecdsa.PrivateKey))
226		if err != nil {
227			return errutil.InternalError{Err: fmt.Sprintf("error marshalling EC private key: %v", err)}
228		}
229	default:
230		return errutil.UserError{Err: fmt.Sprintf("unknown key type: %s", keyType)}
231	}
232
233	container.SetParsedPrivateKey(privateKey, privateKeyType, privateKeyBytes)
234	return nil
235}
236
237// GenerateSerialNumber generates a serial number suitable for a certificate
238func GenerateSerialNumber() (*big.Int, error) {
239	serial, err := rand.Int(rand.Reader, (&big.Int{}).Exp(big.NewInt(2), big.NewInt(159), nil))
240	if err != nil {
241		return nil, errutil.InternalError{Err: fmt.Sprintf("error generating serial number: %v", err)}
242	}
243	return serial, nil
244}
245
246// ComparePublicKeys compares two public keys and returns true if they match
247func ComparePublicKeys(key1Iface, key2Iface crypto.PublicKey) (bool, error) {
248	switch key1Iface.(type) {
249	case *rsa.PublicKey:
250		key1 := key1Iface.(*rsa.PublicKey)
251		key2, ok := key2Iface.(*rsa.PublicKey)
252		if !ok {
253			return false, fmt.Errorf("key types do not match: %T and %T", key1Iface, key2Iface)
254		}
255		if key1.N.Cmp(key2.N) != 0 ||
256			key1.E != key2.E {
257			return false, nil
258		}
259		return true, nil
260
261	case *ecdsa.PublicKey:
262		key1 := key1Iface.(*ecdsa.PublicKey)
263		key2, ok := key2Iface.(*ecdsa.PublicKey)
264		if !ok {
265			return false, fmt.Errorf("key types do not match: %T and %T", key1Iface, key2Iface)
266		}
267		if key1.X.Cmp(key2.X) != 0 ||
268			key1.Y.Cmp(key2.Y) != 0 {
269			return false, nil
270		}
271		key1Params := key1.Params()
272		key2Params := key2.Params()
273		if key1Params.P.Cmp(key2Params.P) != 0 ||
274			key1Params.N.Cmp(key2Params.N) != 0 ||
275			key1Params.B.Cmp(key2Params.B) != 0 ||
276			key1Params.Gx.Cmp(key2Params.Gx) != 0 ||
277			key1Params.Gy.Cmp(key2Params.Gy) != 0 ||
278			key1Params.BitSize != key2Params.BitSize {
279			return false, nil
280		}
281		return true, nil
282
283	default:
284		return false, fmt.Errorf("cannot compare key with type %T", key1Iface)
285	}
286}
287
288// ParsePublicKeyPEM is used to parse RSA and ECDSA public keys from PEMs
289func ParsePublicKeyPEM(data []byte) (interface{}, error) {
290	block, data := pem.Decode(data)
291	if block != nil {
292		var rawKey interface{}
293		var err error
294		if rawKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
295			if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
296				rawKey = cert.PublicKey
297			} else {
298				return nil, err
299			}
300		}
301
302		if rsaPublicKey, ok := rawKey.(*rsa.PublicKey); ok {
303			return rsaPublicKey, nil
304		}
305		if ecPublicKey, ok := rawKey.(*ecdsa.PublicKey); ok {
306			return ecPublicKey, nil
307		}
308	}
309
310	return nil, errors.New("data does not contain any valid RSA or ECDSA public keys")
311}
312
313// addPolicyIdentifiers adds certificate policies extension
314//
315func AddPolicyIdentifiers(data *CreationBundle, certTemplate *x509.Certificate) {
316	for _, oidstr := range data.Params.PolicyIdentifiers {
317		oid, err := StringToOid(oidstr)
318		if err == nil {
319			certTemplate.PolicyIdentifiers = append(certTemplate.PolicyIdentifiers, oid)
320		}
321	}
322}
323
324// addExtKeyUsageOids adds custom extended key usage OIDs to certificate
325func AddExtKeyUsageOids(data *CreationBundle, certTemplate *x509.Certificate) {
326	for _, oidstr := range data.Params.ExtKeyUsageOIDs {
327		oid, err := StringToOid(oidstr)
328		if err == nil {
329			certTemplate.UnknownExtKeyUsage = append(certTemplate.UnknownExtKeyUsage, oid)
330		}
331	}
332}
333
334func HandleOtherCSRSANs(in *x509.CertificateRequest, sans map[string][]string) error {
335	certTemplate := &x509.Certificate{
336		DNSNames:       in.DNSNames,
337		IPAddresses:    in.IPAddresses,
338		EmailAddresses: in.EmailAddresses,
339		URIs:           in.URIs,
340	}
341	if err := HandleOtherSANs(certTemplate, sans); err != nil {
342		return err
343	}
344	if len(certTemplate.ExtraExtensions) > 0 {
345		for _, v := range certTemplate.ExtraExtensions {
346			in.ExtraExtensions = append(in.ExtraExtensions, v)
347		}
348	}
349	return nil
350}
351
352func HandleOtherSANs(in *x509.Certificate, sans map[string][]string) error {
353	// If other SANs is empty we return which causes normal Go stdlib parsing
354	// of the other SAN types
355	if len(sans) == 0 {
356		return nil
357	}
358
359	var rawValues []asn1.RawValue
360
361	// We need to generate an IMPLICIT sequence for compatibility with OpenSSL
362	// -- it's an open question what the default for RFC 5280 actually is, see
363	// https://github.com/openssl/openssl/issues/5091 -- so we have to use
364	// cryptobyte because using the asn1 package's marshaling always produces
365	// an EXPLICIT sequence. Note that asn1 is way too magical according to
366	// agl, and cryptobyte is modeled after the CBB/CBS bits that agl put into
367	// boringssl.
368	for oid, vals := range sans {
369		for _, val := range vals {
370			var b cryptobyte.Builder
371			oidStr, err := StringToOid(oid)
372			if err != nil {
373				return err
374			}
375			b.AddASN1ObjectIdentifier(oidStr)
376			b.AddASN1(cbasn1.Tag(0).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) {
377				b.AddASN1(cbasn1.UTF8String, func(b *cryptobyte.Builder) {
378					b.AddBytes([]byte(val))
379				})
380			})
381			m, err := b.Bytes()
382			if err != nil {
383				return err
384			}
385			rawValues = append(rawValues, asn1.RawValue{Tag: 0, Class: 2, IsCompound: true, Bytes: m})
386		}
387	}
388
389	// If other SANs is empty we return which causes normal Go stdlib parsing
390	// of the other SAN types
391	if len(rawValues) == 0 {
392		return nil
393	}
394
395	// Append any existing SANs, sans marshalling
396	rawValues = append(rawValues, marshalSANs(in.DNSNames, in.EmailAddresses, in.IPAddresses, in.URIs)...)
397
398	// Marshal and add to ExtraExtensions
399	ext := pkix.Extension{
400		// This is the defined OID for subjectAltName
401		Id: asn1.ObjectIdentifier{2, 5, 29, 17},
402	}
403	var err error
404	ext.Value, err = asn1.Marshal(rawValues)
405	if err != nil {
406		return err
407	}
408	in.ExtraExtensions = append(in.ExtraExtensions, ext)
409
410	return nil
411}
412
413// Note: Taken from the Go source code since it's not public, and used in the
414// modified function below (which also uses these consts upstream)
415const (
416	nameTypeEmail = 1
417	nameTypeDNS   = 2
418	nameTypeURI   = 6
419	nameTypeIP    = 7
420)
421
422// Note: Taken from the Go source code since it's not public, plus changed to not marshal
423// marshalSANs marshals a list of addresses into a the contents of an X.509
424// SubjectAlternativeName extension.
425func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL) []asn1.RawValue {
426	var rawValues []asn1.RawValue
427	for _, name := range dnsNames {
428		rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)})
429	}
430	for _, email := range emailAddresses {
431		rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)})
432	}
433	for _, rawIP := range ipAddresses {
434		// If possible, we always want to encode IPv4 addresses in 4 bytes.
435		ip := rawIP.To4()
436		if ip == nil {
437			ip = rawIP
438		}
439		rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: ip})
440	}
441	for _, uri := range uris {
442		rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uri.String())})
443	}
444	return rawValues
445}
446
447func StringToOid(in string) (asn1.ObjectIdentifier, error) {
448	split := strings.Split(in, ".")
449	ret := make(asn1.ObjectIdentifier, 0, len(split))
450	for _, v := range split {
451		i, err := strconv.Atoi(v)
452		if err != nil {
453			return nil, err
454		}
455		ret = append(ret, i)
456	}
457	return asn1.ObjectIdentifier(ret), nil
458}
459
460func ValidateKeyTypeLength(keyType string, keyBits int) error {
461	switch keyType {
462	case "rsa":
463		switch keyBits {
464		case 2048:
465		case 4096:
466		case 8192:
467		default:
468			return fmt.Errorf("unsupported bit length for RSA key: %d", keyBits)
469		}
470	case "ec":
471		switch keyBits {
472		case 224:
473		case 256:
474		case 384:
475		case 521:
476		default:
477			return fmt.Errorf("unsupported bit length for EC key: %d", keyBits)
478		}
479	case "any":
480	default:
481		return fmt.Errorf("unknown key type %s", keyType)
482	}
483
484	return nil
485}
486
487// Performs the heavy lifting of creating a certificate. Returns
488// a fully-filled-in ParsedCertBundle.
489func CreateCertificate(data *CreationBundle) (*ParsedCertBundle, error) {
490	var err error
491	result := &ParsedCertBundle{}
492
493	serialNumber, err := GenerateSerialNumber()
494	if err != nil {
495		return nil, err
496	}
497
498	if err := GeneratePrivateKey(data.Params.KeyType,
499		data.Params.KeyBits,
500		result); err != nil {
501		return nil, err
502	}
503
504	subjKeyID, err := GetSubjKeyID(result.PrivateKey)
505	if err != nil {
506		return nil, errutil.InternalError{Err: fmt.Sprintf("error getting subject key ID: %s", err)}
507	}
508
509	certTemplate := &x509.Certificate{
510		SerialNumber:   serialNumber,
511		NotBefore:      time.Now().Add(-30 * time.Second),
512		NotAfter:       data.Params.NotAfter,
513		IsCA:           false,
514		SubjectKeyId:   subjKeyID,
515		Subject:        data.Params.Subject,
516		DNSNames:       data.Params.DNSNames,
517		EmailAddresses: data.Params.EmailAddresses,
518		IPAddresses:    data.Params.IPAddresses,
519		URIs:           data.Params.URIs,
520	}
521	if data.Params.NotBeforeDuration > 0 {
522		certTemplate.NotBefore = time.Now().Add(-1 * data.Params.NotBeforeDuration)
523	}
524
525	if err := HandleOtherSANs(certTemplate, data.Params.OtherSANs); err != nil {
526		return nil, errutil.InternalError{Err: errwrap.Wrapf("error marshaling other SANs: {{err}}", err).Error()}
527	}
528
529	// Add this before calling addKeyUsages
530	if data.SigningBundle == nil {
531		certTemplate.IsCA = true
532	} else if data.Params.BasicConstraintsValidForNonCA {
533		certTemplate.BasicConstraintsValid = true
534		certTemplate.IsCA = false
535	}
536
537	// This will only be filled in from the generation paths
538	if len(data.Params.PermittedDNSDomains) > 0 {
539		certTemplate.PermittedDNSDomains = data.Params.PermittedDNSDomains
540		certTemplate.PermittedDNSDomainsCritical = true
541	}
542
543	AddPolicyIdentifiers(data, certTemplate)
544
545	AddKeyUsages(data, certTemplate)
546
547	AddExtKeyUsageOids(data, certTemplate)
548
549	certTemplate.IssuingCertificateURL = data.Params.URLs.IssuingCertificates
550	certTemplate.CRLDistributionPoints = data.Params.URLs.CRLDistributionPoints
551	certTemplate.OCSPServer = data.Params.URLs.OCSPServers
552
553	var certBytes []byte
554	if data.SigningBundle != nil {
555		switch data.SigningBundle.PrivateKeyType {
556		case RSAPrivateKey:
557			certTemplate.SignatureAlgorithm = x509.SHA256WithRSA
558		case ECPrivateKey:
559			certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA256
560		}
561
562		caCert := data.SigningBundle.Certificate
563		certTemplate.AuthorityKeyId = caCert.SubjectKeyId
564
565		certBytes, err = x509.CreateCertificate(rand.Reader, certTemplate, caCert, result.PrivateKey.Public(), data.SigningBundle.PrivateKey)
566	} else {
567		// Creating a self-signed root
568		if data.Params.MaxPathLength == 0 {
569			certTemplate.MaxPathLen = 0
570			certTemplate.MaxPathLenZero = true
571		} else {
572			certTemplate.MaxPathLen = data.Params.MaxPathLength
573		}
574
575		switch data.Params.KeyType {
576		case "rsa":
577			certTemplate.SignatureAlgorithm = x509.SHA256WithRSA
578		case "ec":
579			certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA256
580		}
581
582		certTemplate.AuthorityKeyId = subjKeyID
583		certTemplate.BasicConstraintsValid = true
584		certBytes, err = x509.CreateCertificate(rand.Reader, certTemplate, certTemplate, result.PrivateKey.Public(), result.PrivateKey)
585	}
586
587	if err != nil {
588		return nil, errutil.InternalError{Err: fmt.Sprintf("unable to create certificate: %s", err)}
589	}
590
591	result.CertificateBytes = certBytes
592	result.Certificate, err = x509.ParseCertificate(certBytes)
593	if err != nil {
594		return nil, errutil.InternalError{Err: fmt.Sprintf("unable to parse created certificate: %s", err)}
595	}
596
597	if data.SigningBundle != nil {
598		if len(data.SigningBundle.Certificate.AuthorityKeyId) > 0 &&
599			!bytes.Equal(data.SigningBundle.Certificate.AuthorityKeyId, data.SigningBundle.Certificate.SubjectKeyId) {
600
601			result.CAChain = []*CertBlock{
602				&CertBlock{
603					Certificate: data.SigningBundle.Certificate,
604					Bytes:       data.SigningBundle.CertificateBytes,
605				},
606			}
607			result.CAChain = append(result.CAChain, data.SigningBundle.CAChain...)
608		}
609	}
610
611	return result, nil
612}
613
614var oidExtensionBasicConstraints = []int{2, 5, 29, 19}
615
616// Creates a CSR. This is currently only meant for use when
617// generating an intermediate certificate.
618func CreateCSR(data *CreationBundle, addBasicConstraints bool) (*ParsedCSRBundle, error) {
619	var err error
620	result := &ParsedCSRBundle{}
621
622	if err := GeneratePrivateKey(data.Params.KeyType,
623		data.Params.KeyBits,
624		result); err != nil {
625		return nil, err
626	}
627
628	// Like many root CAs, other information is ignored
629	csrTemplate := &x509.CertificateRequest{
630		Subject:        data.Params.Subject,
631		DNSNames:       data.Params.DNSNames,
632		EmailAddresses: data.Params.EmailAddresses,
633		IPAddresses:    data.Params.IPAddresses,
634		URIs:           data.Params.URIs,
635	}
636
637	if err := HandleOtherCSRSANs(csrTemplate, data.Params.OtherSANs); err != nil {
638		return nil, errutil.InternalError{Err: errwrap.Wrapf("error marshaling other SANs: {{err}}", err).Error()}
639	}
640
641	if addBasicConstraints {
642		type basicConstraints struct {
643			IsCA       bool `asn1:"optional"`
644			MaxPathLen int  `asn1:"optional,default:-1"`
645		}
646		val, err := asn1.Marshal(basicConstraints{IsCA: true, MaxPathLen: -1})
647		if err != nil {
648			return nil, errutil.InternalError{Err: errwrap.Wrapf("error marshaling basic constraints: {{err}}", err).Error()}
649		}
650		ext := pkix.Extension{
651			Id:       oidExtensionBasicConstraints,
652			Value:    val,
653			Critical: true,
654		}
655		csrTemplate.ExtraExtensions = append(csrTemplate.ExtraExtensions, ext)
656	}
657
658	switch data.Params.KeyType {
659	case "rsa":
660		csrTemplate.SignatureAlgorithm = x509.SHA256WithRSA
661	case "ec":
662		csrTemplate.SignatureAlgorithm = x509.ECDSAWithSHA256
663	}
664
665	csr, err := x509.CreateCertificateRequest(rand.Reader, csrTemplate, result.PrivateKey)
666	if err != nil {
667		return nil, errutil.InternalError{Err: fmt.Sprintf("unable to create certificate: %s", err)}
668	}
669
670	result.CSRBytes = csr
671	result.CSR, err = x509.ParseCertificateRequest(csr)
672	if err != nil {
673		return nil, errutil.InternalError{Err: fmt.Sprintf("unable to parse created certificate: %v", err)}
674	}
675
676	return result, nil
677}
678
679// Performs the heavy lifting of generating a certificate from a CSR.
680// Returns a ParsedCertBundle sans private keys.
681func SignCertificate(data *CreationBundle) (*ParsedCertBundle, error) {
682	switch {
683	case data == nil:
684		return nil, errutil.UserError{Err: "nil data bundle given to signCertificate"}
685	case data.Params == nil:
686		return nil, errutil.UserError{Err: "nil parameters given to signCertificate"}
687	case data.SigningBundle == nil:
688		return nil, errutil.UserError{Err: "nil signing bundle given to signCertificate"}
689	case data.CSR == nil:
690		return nil, errutil.UserError{Err: "nil csr given to signCertificate"}
691	}
692
693	err := data.CSR.CheckSignature()
694	if err != nil {
695		return nil, errutil.UserError{Err: "request signature invalid"}
696	}
697
698	result := &ParsedCertBundle{}
699
700	serialNumber, err := GenerateSerialNumber()
701	if err != nil {
702		return nil, err
703	}
704
705	marshaledKey, err := x509.MarshalPKIXPublicKey(data.CSR.PublicKey)
706	if err != nil {
707		return nil, errutil.InternalError{Err: fmt.Sprintf("error marshalling public key: %s", err)}
708	}
709	subjKeyID := sha1.Sum(marshaledKey)
710
711	caCert := data.SigningBundle.Certificate
712
713	certTemplate := &x509.Certificate{
714		SerialNumber:   serialNumber,
715		Subject:        data.Params.Subject,
716		NotBefore:      time.Now().Add(-30 * time.Second),
717		NotAfter:       data.Params.NotAfter,
718		SubjectKeyId:   subjKeyID[:],
719		AuthorityKeyId: caCert.SubjectKeyId,
720	}
721	if data.Params.NotBeforeDuration > 0 {
722		certTemplate.NotBefore = time.Now().Add(-1 * data.Params.NotBeforeDuration)
723	}
724
725	switch data.SigningBundle.PrivateKeyType {
726	case RSAPrivateKey:
727		certTemplate.SignatureAlgorithm = x509.SHA256WithRSA
728	case ECPrivateKey:
729		certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA256
730	}
731
732	if data.Params.UseCSRValues {
733		certTemplate.Subject = data.CSR.Subject
734		certTemplate.Subject.ExtraNames = certTemplate.Subject.Names
735
736		certTemplate.DNSNames = data.CSR.DNSNames
737		certTemplate.EmailAddresses = data.CSR.EmailAddresses
738		certTemplate.IPAddresses = data.CSR.IPAddresses
739		certTemplate.URIs = data.CSR.URIs
740
741		for _, name := range data.CSR.Extensions {
742			if !name.Id.Equal(oidExtensionBasicConstraints) {
743				certTemplate.ExtraExtensions = append(certTemplate.ExtraExtensions, name)
744			}
745		}
746
747	} else {
748		certTemplate.DNSNames = data.Params.DNSNames
749		certTemplate.EmailAddresses = data.Params.EmailAddresses
750		certTemplate.IPAddresses = data.Params.IPAddresses
751		certTemplate.URIs = data.Params.URIs
752	}
753
754	if err := HandleOtherSANs(certTemplate, data.Params.OtherSANs); err != nil {
755		return nil, errutil.InternalError{Err: errwrap.Wrapf("error marshaling other SANs: {{err}}", err).Error()}
756	}
757
758	AddPolicyIdentifiers(data, certTemplate)
759
760	AddKeyUsages(data, certTemplate)
761
762	AddExtKeyUsageOids(data, certTemplate)
763
764	var certBytes []byte
765
766	certTemplate.IssuingCertificateURL = data.Params.URLs.IssuingCertificates
767	certTemplate.CRLDistributionPoints = data.Params.URLs.CRLDistributionPoints
768	certTemplate.OCSPServer = data.SigningBundle.URLs.OCSPServers
769
770	if data.Params.IsCA {
771		certTemplate.BasicConstraintsValid = true
772		certTemplate.IsCA = true
773
774		if data.SigningBundle.Certificate.MaxPathLen == 0 &&
775			data.SigningBundle.Certificate.MaxPathLenZero {
776			return nil, errutil.UserError{Err: "signing certificate has a max path length of zero, and cannot issue further CA certificates"}
777		}
778
779		certTemplate.MaxPathLen = data.Params.MaxPathLength
780		if certTemplate.MaxPathLen == 0 {
781			certTemplate.MaxPathLenZero = true
782		}
783	} else if data.Params.BasicConstraintsValidForNonCA {
784		certTemplate.BasicConstraintsValid = true
785		certTemplate.IsCA = false
786	}
787
788	if len(data.Params.PermittedDNSDomains) > 0 {
789		certTemplate.PermittedDNSDomains = data.Params.PermittedDNSDomains
790		certTemplate.PermittedDNSDomainsCritical = true
791	}
792
793	certBytes, err = x509.CreateCertificate(rand.Reader, certTemplate, caCert, data.CSR.PublicKey, data.SigningBundle.PrivateKey)
794
795	if err != nil {
796		return nil, errutil.InternalError{Err: fmt.Sprintf("unable to create certificate: %s", err)}
797	}
798
799	result.CertificateBytes = certBytes
800	result.Certificate, err = x509.ParseCertificate(certBytes)
801	if err != nil {
802		return nil, errutil.InternalError{Err: fmt.Sprintf("unable to parse created certificate: %s", err)}
803	}
804
805	result.CAChain = data.SigningBundle.GetCAChain()
806
807	return result, nil
808}
809
810func NewCertPool(reader io.Reader) (*x509.CertPool, error) {
811	pemBlock, err := ioutil.ReadAll(reader)
812	if err != nil {
813		return nil, err
814	}
815	certs, err := parseCertsPEM(pemBlock)
816	if err != nil {
817		return nil, fmt.Errorf("error reading certs: %s", err)
818	}
819	pool := x509.NewCertPool()
820	for _, cert := range certs {
821		pool.AddCert(cert)
822	}
823	return pool, nil
824}
825
826// parseCertsPEM returns the x509.Certificates contained in the given PEM-encoded byte array
827// Returns an error if a certificate could not be parsed, or if the data does not contain any certificates
828func parseCertsPEM(pemCerts []byte) ([]*x509.Certificate, error) {
829	ok := false
830	certs := []*x509.Certificate{}
831	for len(pemCerts) > 0 {
832		var block *pem.Block
833		block, pemCerts = pem.Decode(pemCerts)
834		if block == nil {
835			break
836		}
837		// Only use PEM "CERTIFICATE" blocks without extra headers
838		if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
839			continue
840		}
841
842		cert, err := x509.ParseCertificate(block.Bytes)
843		if err != nil {
844			return certs, err
845		}
846
847		certs = append(certs, cert)
848		ok = true
849	}
850
851	if !ok {
852		return certs, errors.New("data does not contain any valid RSA or ECDSA certificates")
853	}
854	return certs, nil
855}
856