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