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