github.com/hashicorp/vault/sdk@v0.11.0/helper/certutil/helpers.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package certutil 5 6 import ( 7 "bytes" 8 "crypto" 9 "crypto/dsa" 10 "crypto/ecdsa" 11 "crypto/ed25519" 12 "crypto/elliptic" 13 "crypto/rand" 14 "crypto/rsa" 15 "crypto/sha1" 16 "crypto/tls" 17 "crypto/x509" 18 "crypto/x509/pkix" 19 "encoding/asn1" 20 "encoding/binary" 21 "encoding/hex" 22 "encoding/pem" 23 "errors" 24 "fmt" 25 "io" 26 "io/ioutil" 27 "math/big" 28 "net" 29 "net/url" 30 "strconv" 31 "strings" 32 "time" 33 34 "github.com/hashicorp/errwrap" 35 "github.com/hashicorp/vault/sdk/helper/errutil" 36 "github.com/hashicorp/vault/sdk/helper/jsonutil" 37 "github.com/mitchellh/mapstructure" 38 "golang.org/x/crypto/cryptobyte" 39 cbasn1 "golang.org/x/crypto/cryptobyte/asn1" 40 ) 41 42 const rsaMinimumSecureKeySize = 2048 43 44 // Mapping of key types to default key lengths 45 var defaultAlgorithmKeyBits = map[string]int{ 46 "rsa": 2048, 47 "ec": 256, 48 } 49 50 // Mapping of NIST P-Curve's key length to expected signature bits. 51 var expectedNISTPCurveHashBits = map[int]int{ 52 224: 256, 53 256: 256, 54 384: 384, 55 521: 512, 56 } 57 58 // Mapping of constant names<->constant values for SignatureAlgorithm 59 var SignatureAlgorithmNames = map[string]x509.SignatureAlgorithm{ 60 "sha256withrsa": x509.SHA256WithRSA, 61 "sha384withrsa": x509.SHA384WithRSA, 62 "sha512withrsa": x509.SHA512WithRSA, 63 "ecdsawithsha256": x509.ECDSAWithSHA256, 64 "ecdsawithsha384": x509.ECDSAWithSHA384, 65 "ecdsawithsha512": x509.ECDSAWithSHA512, 66 "sha256withrsapss": x509.SHA256WithRSAPSS, 67 "sha384withrsapss": x509.SHA384WithRSAPSS, 68 "sha512withrsapss": x509.SHA512WithRSAPSS, 69 "pureed25519": x509.PureEd25519, 70 "ed25519": x509.PureEd25519, // Duplicated for clarity; most won't expect the "Pure" prefix. 71 } 72 73 // Mapping of constant values<->constant names for SignatureAlgorithm 74 var InvSignatureAlgorithmNames = map[x509.SignatureAlgorithm]string{ 75 x509.SHA256WithRSA: "SHA256WithRSA", 76 x509.SHA384WithRSA: "SHA384WithRSA", 77 x509.SHA512WithRSA: "SHA512WithRSA", 78 x509.ECDSAWithSHA256: "ECDSAWithSHA256", 79 x509.ECDSAWithSHA384: "ECDSAWithSHA384", 80 x509.ECDSAWithSHA512: "ECDSAWithSHA512", 81 x509.SHA256WithRSAPSS: "SHA256WithRSAPSS", 82 x509.SHA384WithRSAPSS: "SHA384WithRSAPSS", 83 x509.SHA512WithRSAPSS: "SHA512WithRSAPSS", 84 x509.PureEd25519: "Ed25519", 85 } 86 87 // OIDs for X.509 SAN Extension 88 var OidExtensionSubjectAltName = asn1.ObjectIdentifier([]int{2, 5, 29, 17}) 89 90 // OID for RFC 5280 CRL Number extension. 91 // 92 // > id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } 93 var CRLNumberOID = asn1.ObjectIdentifier([]int{2, 5, 29, 20}) 94 95 // OID for RFC 5280 Delta CRL Indicator CRL extension. 96 // 97 // > id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 } 98 var DeltaCRLIndicatorOID = asn1.ObjectIdentifier([]int{2, 5, 29, 27}) 99 100 // OID for KeyUsage from RFC 2459 : https://www.rfc-editor.org/rfc/rfc2459.html#section-4.2.1.3 101 // 102 // > id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } 103 var KeyUsageOID = asn1.ObjectIdentifier([]int{2, 5, 29, 15}) 104 105 // OID for Extended Key Usage from RFC 5280 : https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.12 106 // 107 // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } 108 var ExtendedKeyUsageOID = asn1.ObjectIdentifier([]int{2, 5, 29, 37}) 109 110 // GetHexFormatted returns the byte buffer formatted in hex with 111 // the specified separator between bytes. 112 func GetHexFormatted(buf []byte, sep string) string { 113 var ret bytes.Buffer 114 for _, cur := range buf { 115 if ret.Len() > 0 { 116 fmt.Fprintf(&ret, sep) 117 } 118 fmt.Fprintf(&ret, "%02x", cur) 119 } 120 return ret.String() 121 } 122 123 // ParseHexFormatted returns the raw bytes from a formatted hex string 124 func ParseHexFormatted(in, sep string) []byte { 125 var ret bytes.Buffer 126 var err error 127 var inBits uint64 128 inBytes := strings.Split(in, sep) 129 for _, inByte := range inBytes { 130 if inBits, err = strconv.ParseUint(inByte, 16, 8); err != nil { 131 return nil 132 } 133 ret.WriteByte(uint8(inBits)) 134 } 135 return ret.Bytes() 136 } 137 138 // GetSubjKeyID returns the subject key ID. The computed ID is the SHA-1 hash of 139 // the marshaled public key according to 140 // https://tools.ietf.org/html/rfc5280#section-4.2.1.2 (1) 141 func GetSubjKeyID(privateKey crypto.Signer) ([]byte, error) { 142 if privateKey == nil { 143 return nil, errutil.InternalError{Err: "passed-in private key is nil"} 144 } 145 return GetSubjectKeyID(privateKey.Public()) 146 } 147 148 // Returns the explicit SKID when used for cross-signing, else computes a new 149 // SKID from the key itself. 150 func getSubjectKeyIDFromBundle(data *CreationBundle) ([]byte, error) { 151 if len(data.Params.SKID) > 0 { 152 return data.Params.SKID, nil 153 } 154 155 return GetSubjectKeyID(data.CSR.PublicKey) 156 } 157 158 func GetSubjectKeyID(pub interface{}) ([]byte, error) { 159 var publicKeyBytes []byte 160 switch pub := pub.(type) { 161 case *rsa.PublicKey: 162 type pkcs1PublicKey struct { 163 N *big.Int 164 E int 165 } 166 167 var err error 168 publicKeyBytes, err = asn1.Marshal(pkcs1PublicKey{ 169 N: pub.N, 170 E: pub.E, 171 }) 172 if err != nil { 173 return nil, errutil.InternalError{Err: fmt.Sprintf("error marshalling public key: %s", err)} 174 } 175 case *ecdsa.PublicKey: 176 publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) 177 case ed25519.PublicKey: 178 publicKeyBytes = pub 179 default: 180 return nil, errutil.InternalError{Err: fmt.Sprintf("unsupported public key type: %T", pub)} 181 } 182 skid := sha1.Sum(publicKeyBytes) 183 return skid[:], nil 184 } 185 186 // ParsePKIMap takes a map (for instance, the Secret.Data 187 // returned from the PKI backend) and returns a ParsedCertBundle. 188 func ParsePKIMap(data map[string]interface{}) (*ParsedCertBundle, error) { 189 result := &CertBundle{} 190 err := mapstructure.Decode(data, result) 191 if err != nil { 192 return nil, errutil.UserError{Err: err.Error()} 193 } 194 195 return result.ToParsedCertBundle() 196 } 197 198 // ParsePKIJSON takes a JSON-encoded string and returns a ParsedCertBundle. 199 // 200 // This can be either the output of an 201 // issue call from the PKI backend or just its data member; or, 202 // JSON not coming from the PKI backend. 203 func ParsePKIJSON(input []byte) (*ParsedCertBundle, error) { 204 result := &CertBundle{} 205 err := jsonutil.DecodeJSON(input, &result) 206 207 if err == nil { 208 return result.ToParsedCertBundle() 209 } 210 211 var secret Secret 212 err = jsonutil.DecodeJSON(input, &secret) 213 214 if err == nil { 215 return ParsePKIMap(secret.Data) 216 } 217 218 return nil, errutil.UserError{Err: "unable to parse out of either secret data or a secret object"} 219 } 220 221 func ParseDERKey(privateKeyBytes []byte) (signer crypto.Signer, format BlockType, err error) { 222 var firstError error 223 if signer, firstError = x509.ParseECPrivateKey(privateKeyBytes); firstError == nil { 224 format = ECBlock 225 return 226 } 227 228 var secondError error 229 if signer, secondError = x509.ParsePKCS1PrivateKey(privateKeyBytes); secondError == nil { 230 format = PKCS1Block 231 return 232 } 233 234 var thirdError error 235 var rawKey interface{} 236 if rawKey, thirdError = x509.ParsePKCS8PrivateKey(privateKeyBytes); thirdError == nil { 237 switch rawSigner := rawKey.(type) { 238 case *rsa.PrivateKey: 239 signer = rawSigner 240 case *ecdsa.PrivateKey: 241 signer = rawSigner 242 case ed25519.PrivateKey: 243 signer = rawSigner 244 default: 245 return nil, UnknownBlock, errutil.InternalError{Err: "unknown type for parsed PKCS8 Private Key"} 246 } 247 248 format = PKCS8Block 249 return 250 } 251 252 return nil, UnknownBlock, fmt.Errorf("got errors attempting to parse DER private key:\n1. %v\n2. %v\n3. %v", firstError, secondError, thirdError) 253 } 254 255 func ParsePEMKey(keyPem string) (crypto.Signer, BlockType, error) { 256 pemBlock, _ := pem.Decode([]byte(keyPem)) 257 if pemBlock == nil { 258 return nil, UnknownBlock, errutil.UserError{Err: "no data found in PEM block"} 259 } 260 261 return ParseDERKey(pemBlock.Bytes) 262 } 263 264 // ParsePEMBundle takes a string of concatenated PEM-format certificate 265 // and private key values and decodes/parses them, checking validity along 266 // the way. The first certificate must be the subject certificate and issuing 267 // certificates may follow. There must be at most one private key. 268 func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) { 269 if len(pemBundle) == 0 { 270 return nil, errutil.UserError{Err: "empty pem bundle"} 271 } 272 273 pemBytes := []byte(pemBundle) 274 var pemBlock *pem.Block 275 parsedBundle := &ParsedCertBundle{} 276 var certPath []*CertBlock 277 278 for len(pemBytes) > 0 { 279 pemBlock, pemBytes = pem.Decode(pemBytes) 280 if pemBlock == nil { 281 return nil, errutil.UserError{Err: "no data found in PEM block"} 282 } 283 284 if signer, format, err := ParseDERKey(pemBlock.Bytes); err == nil { 285 if parsedBundle.PrivateKeyType != UnknownPrivateKey { 286 return nil, errutil.UserError{Err: "more than one private key given; provide only one private key in the bundle"} 287 } 288 289 parsedBundle.PrivateKeyFormat = format 290 parsedBundle.PrivateKeyType = GetPrivateKeyTypeFromSigner(signer) 291 if parsedBundle.PrivateKeyType == UnknownPrivateKey { 292 return nil, errutil.UserError{Err: "Unknown type of private key included in the bundle: %v"} 293 } 294 295 parsedBundle.PrivateKeyBytes = pemBlock.Bytes 296 parsedBundle.PrivateKey = signer 297 } else if certificates, err := x509.ParseCertificates(pemBlock.Bytes); err == nil { 298 certPath = append(certPath, &CertBlock{ 299 Certificate: certificates[0], 300 Bytes: pemBlock.Bytes, 301 }) 302 } else if x509.IsEncryptedPEMBlock(pemBlock) { 303 return nil, errutil.UserError{Err: "Encrypted private key given; provide only decrypted private key in the bundle"} 304 } 305 } 306 307 for i, certBlock := range certPath { 308 if i == 0 { 309 parsedBundle.Certificate = certBlock.Certificate 310 parsedBundle.CertificateBytes = certBlock.Bytes 311 } else { 312 parsedBundle.CAChain = append(parsedBundle.CAChain, certBlock) 313 } 314 } 315 316 if err := parsedBundle.Verify(); err != nil { 317 return nil, errutil.UserError{Err: fmt.Sprintf("verification of parsed bundle failed: %s", err)} 318 } 319 320 return parsedBundle, nil 321 } 322 323 func (p *ParsedCertBundle) ToTLSCertificate() tls.Certificate { 324 var cert tls.Certificate 325 cert.Certificate = append(cert.Certificate, p.CertificateBytes) 326 cert.Leaf = p.Certificate 327 cert.PrivateKey = p.PrivateKey 328 for _, ca := range p.CAChain { 329 cert.Certificate = append(cert.Certificate, ca.Bytes) 330 } 331 332 return cert 333 } 334 335 // GeneratePrivateKey generates a private key with the specified type and key bits. 336 func GeneratePrivateKey(keyType string, keyBits int, container ParsedPrivateKeyContainer) error { 337 return generatePrivateKey(keyType, keyBits, container, nil) 338 } 339 340 // GeneratePrivateKeyWithRandomSource generates a private key with the specified type and key bits. 341 // GeneratePrivateKeyWithRandomSource uses randomness from the entropyReader to generate the private key. 342 func GeneratePrivateKeyWithRandomSource(keyType string, keyBits int, container ParsedPrivateKeyContainer, entropyReader io.Reader) error { 343 return generatePrivateKey(keyType, keyBits, container, entropyReader) 344 } 345 346 // generatePrivateKey generates a private key with the specified type and key bits. 347 // generatePrivateKey uses randomness from the entropyReader to generate the private key. 348 func generatePrivateKey(keyType string, keyBits int, container ParsedPrivateKeyContainer, entropyReader io.Reader) error { 349 var err error 350 var privateKeyType PrivateKeyType 351 var privateKeyBytes []byte 352 var privateKey crypto.Signer 353 354 var randReader io.Reader = rand.Reader 355 if entropyReader != nil { 356 randReader = entropyReader 357 } 358 359 switch keyType { 360 case "rsa": 361 // XXX: there is a false-positive CodeQL path here around keyBits; 362 // because of a default zero value in the TypeDurationSecond and 363 // TypeSignedDurationSecond cases of schema.DefaultOrZero(), it 364 // thinks it is possible to end up with < 2048 bit RSA Key here. 365 // While this is true for SSH keys, it isn't true for PKI keys 366 // due to ValidateKeyTypeLength(...) below. While we could close 367 // the report as a false-positive, enforcing a minimum keyBits size 368 // here of 2048 would ensure no other paths exist. 369 if keyBits < 2048 { 370 return errutil.InternalError{Err: fmt.Sprintf("insecure bit length for RSA private key: %d", keyBits)} 371 } 372 privateKeyType = RSAPrivateKey 373 privateKey, err = rsa.GenerateKey(randReader, keyBits) 374 if err != nil { 375 return errutil.InternalError{Err: fmt.Sprintf("error generating RSA private key: %v", err)} 376 } 377 privateKeyBytes = x509.MarshalPKCS1PrivateKey(privateKey.(*rsa.PrivateKey)) 378 case "ec": 379 privateKeyType = ECPrivateKey 380 var curve elliptic.Curve 381 switch keyBits { 382 case 224: 383 curve = elliptic.P224() 384 case 256: 385 curve = elliptic.P256() 386 case 384: 387 curve = elliptic.P384() 388 case 521: 389 curve = elliptic.P521() 390 default: 391 return errutil.UserError{Err: fmt.Sprintf("unsupported bit length for EC key: %d", keyBits)} 392 } 393 privateKey, err = ecdsa.GenerateKey(curve, randReader) 394 if err != nil { 395 return errutil.InternalError{Err: fmt.Sprintf("error generating EC private key: %v", err)} 396 } 397 privateKeyBytes, err = x509.MarshalECPrivateKey(privateKey.(*ecdsa.PrivateKey)) 398 if err != nil { 399 return errutil.InternalError{Err: fmt.Sprintf("error marshalling EC private key: %v", err)} 400 } 401 case "ed25519": 402 privateKeyType = Ed25519PrivateKey 403 _, privateKey, err = ed25519.GenerateKey(randReader) 404 if err != nil { 405 return errutil.InternalError{Err: fmt.Sprintf("error generating ed25519 private key: %v", err)} 406 } 407 privateKeyBytes, err = x509.MarshalPKCS8PrivateKey(privateKey.(ed25519.PrivateKey)) 408 if err != nil { 409 return errutil.InternalError{Err: fmt.Sprintf("error marshalling Ed25519 private key: %v", err)} 410 } 411 default: 412 return errutil.UserError{Err: fmt.Sprintf("unknown key type: %s", keyType)} 413 } 414 415 container.SetParsedPrivateKey(privateKey, privateKeyType, privateKeyBytes) 416 return nil 417 } 418 419 // GenerateSerialNumber generates a serial number suitable for a certificate 420 func GenerateSerialNumber() (*big.Int, error) { 421 return generateSerialNumber(rand.Reader) 422 } 423 424 // GenerateSerialNumberWithRandomSource generates a serial number suitable 425 // for a certificate with custom entropy. 426 func GenerateSerialNumberWithRandomSource(randReader io.Reader) (*big.Int, error) { 427 return generateSerialNumber(randReader) 428 } 429 430 func generateSerialNumber(randReader io.Reader) (*big.Int, error) { 431 serial, err := rand.Int(randReader, (&big.Int{}).Exp(big.NewInt(2), big.NewInt(159), nil)) 432 if err != nil { 433 return nil, errutil.InternalError{Err: fmt.Sprintf("error generating serial number: %v", err)} 434 } 435 return serial, nil 436 } 437 438 // ComparePublicKeysAndType compares two public keys and returns true if they match, 439 // false if their types or contents differ, and an error on unsupported key types. 440 func ComparePublicKeysAndType(key1Iface, key2Iface crypto.PublicKey) (bool, error) { 441 equal, err := ComparePublicKeys(key1Iface, key2Iface) 442 if err != nil { 443 if strings.Contains(err.Error(), "key types do not match:") { 444 return false, nil 445 } 446 } 447 448 return equal, err 449 } 450 451 // ComparePublicKeys compares two public keys and returns true if they match, 452 // returns an error if public key types are mismatched, or they are an unsupported key type. 453 func ComparePublicKeys(key1Iface, key2Iface crypto.PublicKey) (bool, error) { 454 switch key1Iface.(type) { 455 case *rsa.PublicKey: 456 key1 := key1Iface.(*rsa.PublicKey) 457 key2, ok := key2Iface.(*rsa.PublicKey) 458 if !ok { 459 return false, fmt.Errorf("key types do not match: %T and %T", key1Iface, key2Iface) 460 } 461 if key1.N.Cmp(key2.N) != 0 || 462 key1.E != key2.E { 463 return false, nil 464 } 465 return true, nil 466 467 case *ecdsa.PublicKey: 468 key1 := key1Iface.(*ecdsa.PublicKey) 469 key2, ok := key2Iface.(*ecdsa.PublicKey) 470 if !ok { 471 return false, fmt.Errorf("key types do not match: %T and %T", key1Iface, key2Iface) 472 } 473 if key1.X.Cmp(key2.X) != 0 || 474 key1.Y.Cmp(key2.Y) != 0 { 475 return false, nil 476 } 477 key1Params := key1.Params() 478 key2Params := key2.Params() 479 if key1Params.P.Cmp(key2Params.P) != 0 || 480 key1Params.N.Cmp(key2Params.N) != 0 || 481 key1Params.B.Cmp(key2Params.B) != 0 || 482 key1Params.Gx.Cmp(key2Params.Gx) != 0 || 483 key1Params.Gy.Cmp(key2Params.Gy) != 0 || 484 key1Params.BitSize != key2Params.BitSize { 485 return false, nil 486 } 487 return true, nil 488 case ed25519.PublicKey: 489 key1 := key1Iface.(ed25519.PublicKey) 490 key2, ok := key2Iface.(ed25519.PublicKey) 491 if !ok { 492 return false, fmt.Errorf("key types do not match: %T and %T", key1Iface, key2Iface) 493 } 494 if !key1.Equal(key2) { 495 return false, nil 496 } 497 return true, nil 498 default: 499 return false, fmt.Errorf("cannot compare key with type %T", key1Iface) 500 } 501 } 502 503 // ParsePublicKeyPEM is used to parse RSA and ECDSA public keys from PEMs 504 func ParsePublicKeyPEM(data []byte) (interface{}, error) { 505 block, data := pem.Decode(data) 506 if block != nil { 507 if len(bytes.TrimSpace(data)) > 0 { 508 return nil, errutil.UserError{Err: "unexpected trailing data after parsed PEM block"} 509 } 510 var rawKey interface{} 511 var err error 512 if rawKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { 513 if cert, err := x509.ParseCertificate(block.Bytes); err == nil { 514 rawKey = cert.PublicKey 515 } else { 516 return nil, err 517 } 518 } 519 520 switch key := rawKey.(type) { 521 case *rsa.PublicKey: 522 return key, nil 523 case *ecdsa.PublicKey: 524 return key, nil 525 case ed25519.PublicKey: 526 return key, nil 527 } 528 } 529 return nil, errors.New("data does not contain any valid public keys") 530 } 531 532 // AddPolicyIdentifiers adds certificate policies extension, based on CreationBundle 533 func AddPolicyIdentifiers(data *CreationBundle, certTemplate *x509.Certificate) { 534 oidOnly := true 535 for _, oidStr := range data.Params.PolicyIdentifiers { 536 oid, err := StringToOid(oidStr) 537 if err == nil { 538 certTemplate.PolicyIdentifiers = append(certTemplate.PolicyIdentifiers, oid) 539 } 540 if err != nil { 541 oidOnly = false 542 } 543 } 544 if !oidOnly { // Because all policy information is held in the same extension, when we use an extra extension to 545 // add policy qualifier information, that overwrites any information in the PolicyIdentifiers field on the Cert 546 // Template, so we need to reparse all the policy identifiers here 547 extension, err := CreatePolicyInformationExtensionFromStorageStrings(data.Params.PolicyIdentifiers) 548 if err == nil { 549 // If this errors out, don't add it, rely on the OIDs parsed into PolicyIdentifiers above 550 certTemplate.ExtraExtensions = append(certTemplate.ExtraExtensions, *extension) 551 } 552 } 553 } 554 555 // AddExtKeyUsageOids adds custom extended key usage OIDs to certificate 556 func AddExtKeyUsageOids(data *CreationBundle, certTemplate *x509.Certificate) { 557 for _, oidstr := range data.Params.ExtKeyUsageOIDs { 558 oid, err := StringToOid(oidstr) 559 if err == nil { 560 certTemplate.UnknownExtKeyUsage = append(certTemplate.UnknownExtKeyUsage, oid) 561 } 562 } 563 } 564 565 func HandleOtherCSRSANs(in *x509.CertificateRequest, sans map[string][]string) error { 566 certTemplate := &x509.Certificate{ 567 DNSNames: in.DNSNames, 568 IPAddresses: in.IPAddresses, 569 EmailAddresses: in.EmailAddresses, 570 URIs: in.URIs, 571 } 572 if err := HandleOtherSANs(certTemplate, sans); err != nil { 573 return err 574 } 575 if len(certTemplate.ExtraExtensions) > 0 { 576 for _, v := range certTemplate.ExtraExtensions { 577 in.ExtraExtensions = append(in.ExtraExtensions, v) 578 } 579 } 580 return nil 581 } 582 583 func HandleOtherSANs(in *x509.Certificate, sans map[string][]string) error { 584 // If other SANs is empty we return which causes normal Go stdlib parsing 585 // of the other SAN types 586 if len(sans) == 0 { 587 return nil 588 } 589 590 var rawValues []asn1.RawValue 591 592 // We need to generate an IMPLICIT sequence for compatibility with OpenSSL 593 // -- it's an open question what the default for RFC 5280 actually is, see 594 // https://github.com/openssl/openssl/issues/5091 -- so we have to use 595 // cryptobyte because using the asn1 package's marshaling always produces 596 // an EXPLICIT sequence. Note that asn1 is way too magical according to 597 // agl, and cryptobyte is modeled after the CBB/CBS bits that agl put into 598 // boringssl. 599 for oid, vals := range sans { 600 for _, val := range vals { 601 var b cryptobyte.Builder 602 oidStr, err := StringToOid(oid) 603 if err != nil { 604 return err 605 } 606 b.AddASN1ObjectIdentifier(oidStr) 607 b.AddASN1(cbasn1.Tag(0).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) { 608 b.AddASN1(cbasn1.UTF8String, func(b *cryptobyte.Builder) { 609 b.AddBytes([]byte(val)) 610 }) 611 }) 612 m, err := b.Bytes() 613 if err != nil { 614 return err 615 } 616 rawValues = append(rawValues, asn1.RawValue{Tag: 0, Class: 2, IsCompound: true, Bytes: m}) 617 } 618 } 619 620 // If other SANs is empty we return which causes normal Go stdlib parsing 621 // of the other SAN types 622 if len(rawValues) == 0 { 623 return nil 624 } 625 626 // Append any existing SANs, sans marshalling 627 rawValues = append(rawValues, marshalSANs(in.DNSNames, in.EmailAddresses, in.IPAddresses, in.URIs)...) 628 629 // Marshal and add to ExtraExtensions 630 ext := pkix.Extension{ 631 // This is the defined OID for subjectAltName 632 Id: asn1.ObjectIdentifier{2, 5, 29, 17}, 633 } 634 var err error 635 ext.Value, err = asn1.Marshal(rawValues) 636 if err != nil { 637 return err 638 } 639 in.ExtraExtensions = append(in.ExtraExtensions, ext) 640 641 return nil 642 } 643 644 // Note: Taken from the Go source code since it's not public, and used in the 645 // modified function below (which also uses these consts upstream) 646 const ( 647 nameTypeEmail = 1 648 nameTypeDNS = 2 649 nameTypeURI = 6 650 nameTypeIP = 7 651 ) 652 653 // Note: Taken from the Go source code since it's not public, plus changed to not marshal 654 // marshalSANs marshals a list of addresses into a the contents of an X.509 655 // SubjectAlternativeName extension. 656 func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL) []asn1.RawValue { 657 var rawValues []asn1.RawValue 658 for _, name := range dnsNames { 659 rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)}) 660 } 661 for _, email := range emailAddresses { 662 rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)}) 663 } 664 for _, rawIP := range ipAddresses { 665 // If possible, we always want to encode IPv4 addresses in 4 bytes. 666 ip := rawIP.To4() 667 if ip == nil { 668 ip = rawIP 669 } 670 rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: ip}) 671 } 672 for _, uri := range uris { 673 rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uri.String())}) 674 } 675 return rawValues 676 } 677 678 func StringToOid(in string) (asn1.ObjectIdentifier, error) { 679 split := strings.Split(in, ".") 680 ret := make(asn1.ObjectIdentifier, 0, len(split)) 681 for _, v := range split { 682 i, err := strconv.Atoi(v) 683 if err != nil { 684 return nil, err 685 } 686 ret = append(ret, i) 687 } 688 return asn1.ObjectIdentifier(ret), nil 689 } 690 691 // Returns default key bits for the specified key type, or the present value 692 // if keyBits is non-zero. 693 func DefaultOrValueKeyBits(keyType string, keyBits int) (int, error) { 694 if keyBits == 0 { 695 newValue, present := defaultAlgorithmKeyBits[keyType] 696 if present { 697 keyBits = newValue 698 } /* else { 699 // We cannot return an error here as ed25519 (and potentially ed448 700 // in the future) aren't in defaultAlgorithmKeyBits -- the value of 701 // the keyBits parameter is ignored under that algorithm. 702 } */ 703 } 704 705 return keyBits, nil 706 } 707 708 // Returns default signature hash bit length for the specified key type and 709 // bits, or the present value if hashBits is non-zero. Returns an error under 710 // certain internal circumstances. 711 func DefaultOrValueHashBits(keyType string, keyBits int, hashBits int) (int, error) { 712 if keyType == "ec" { 713 // Enforcement of curve moved to selectSignatureAlgorithmForECDSA. See 714 // note there about why. 715 } else if keyType == "rsa" && hashBits == 0 { 716 // To match previous behavior (and ignoring NIST's recommendations for 717 // hash size to align with RSA key sizes), default to SHA-2-256. 718 hashBits = 256 719 } else if keyType == "ed25519" || keyType == "ed448" || keyType == "any" { 720 // No-op; ed25519 and ed448 internally specify their own hash and 721 // we do not need to select one. Double hashing isn't supported in 722 // certificate signing. Additionally, the any key type can't know 723 // what hash algorithm to use yet, so default to zero. 724 return 0, nil 725 } 726 727 return hashBits, nil 728 } 729 730 // Validates that the combination of keyType, keyBits, and hashBits are 731 // valid together; replaces individual calls to ValidateSignatureLength and 732 // ValidateKeyTypeLength. Also updates the value of keyBits and hashBits on 733 // return. 734 func ValidateDefaultOrValueKeyTypeSignatureLength(keyType string, keyBits int, hashBits int) (int, int, error) { 735 var err error 736 737 if keyBits, err = DefaultOrValueKeyBits(keyType, keyBits); err != nil { 738 return keyBits, hashBits, err 739 } 740 741 if err = ValidateKeyTypeLength(keyType, keyBits); err != nil { 742 return keyBits, hashBits, err 743 } 744 745 if hashBits, err = DefaultOrValueHashBits(keyType, keyBits, hashBits); err != nil { 746 return keyBits, hashBits, err 747 } 748 749 // Note that this check must come after we've selected a value for 750 // hashBits above, in the event it was left as the default, but we 751 // were allowed to update it. 752 if err = ValidateSignatureLength(keyType, hashBits); err != nil { 753 return keyBits, hashBits, err 754 } 755 756 return keyBits, hashBits, nil 757 } 758 759 // Validates that the length of the hash (in bits) used in the signature 760 // calculation is a known, approved value. 761 func ValidateSignatureLength(keyType string, hashBits int) error { 762 if keyType == "any" || keyType == "ec" || keyType == "ed25519" || keyType == "ed448" { 763 // ed25519 and ed448 include built-in hashing and is not externally 764 // configurable. There are three modes for each of these schemes: 765 // 766 // 1. Built-in hash (default, used in TLS, x509). 767 // 2. Double hash (notably used in some block-chain implementations, 768 // but largely regarded as a specialized use case with security 769 // concerns). 770 // 3. No hash (bring your own hash function, less commonly used). 771 // 772 // In all cases, we won't have a hash algorithm to validate here, so 773 // return nil. 774 // 775 // Additionally, when KeyType is any, we can't yet validate the 776 // signature algorithm size, so it takes the default zero value. 777 // 778 // When KeyType is ec, we also can't validate this value as we're 779 // forcefully ignoring the users' choice and specifying a value based 780 // on issuer type. 781 return nil 782 } 783 784 switch hashBits { 785 case 256: 786 case 384: 787 case 512: 788 default: 789 return fmt.Errorf("unsupported hash signature algorithm: %d", hashBits) 790 } 791 792 return nil 793 } 794 795 func ValidateKeyTypeLength(keyType string, keyBits int) error { 796 switch keyType { 797 case "rsa": 798 if keyBits < rsaMinimumSecureKeySize { 799 return fmt.Errorf("RSA keys < %d bits are unsafe and not supported: got %d", rsaMinimumSecureKeySize, keyBits) 800 } 801 802 switch keyBits { 803 case 2048: 804 case 3072: 805 case 4096: 806 case 8192: 807 default: 808 return fmt.Errorf("unsupported bit length for RSA key: %d", keyBits) 809 } 810 case "ec": 811 _, present := expectedNISTPCurveHashBits[keyBits] 812 if !present { 813 return fmt.Errorf("unsupported bit length for EC key: %d", keyBits) 814 } 815 case "any", "ed25519": 816 default: 817 return fmt.Errorf("unknown key type %s", keyType) 818 } 819 820 return nil 821 } 822 823 // CreateCertificate uses CreationBundle and the default rand.Reader to 824 // generate a cert/keypair. 825 func CreateCertificate(data *CreationBundle) (*ParsedCertBundle, error) { 826 return createCertificate(data, rand.Reader, generatePrivateKey) 827 } 828 829 // CreateCertificateWithRandomSource uses CreationBundle and a custom 830 // io.Reader for randomness to generate a cert/keypair. 831 func CreateCertificateWithRandomSource(data *CreationBundle, randReader io.Reader) (*ParsedCertBundle, error) { 832 return createCertificate(data, randReader, generatePrivateKey) 833 } 834 835 // KeyGenerator Allow us to override how/what generates the private key 836 type KeyGenerator func(keyType string, keyBits int, container ParsedPrivateKeyContainer, entropyReader io.Reader) error 837 838 func CreateCertificateWithKeyGenerator(data *CreationBundle, randReader io.Reader, keyGenerator KeyGenerator) (*ParsedCertBundle, error) { 839 return createCertificate(data, randReader, keyGenerator) 840 } 841 842 // Set correct RSA sig algo 843 func certTemplateSetSigAlgo(certTemplate *x509.Certificate, data *CreationBundle) { 844 if data.Params.UsePSS { 845 switch data.Params.SignatureBits { 846 case 256: 847 certTemplate.SignatureAlgorithm = x509.SHA256WithRSAPSS 848 case 384: 849 certTemplate.SignatureAlgorithm = x509.SHA384WithRSAPSS 850 case 512: 851 certTemplate.SignatureAlgorithm = x509.SHA512WithRSAPSS 852 } 853 } else { 854 switch data.Params.SignatureBits { 855 case 256: 856 certTemplate.SignatureAlgorithm = x509.SHA256WithRSA 857 case 384: 858 certTemplate.SignatureAlgorithm = x509.SHA384WithRSA 859 case 512: 860 certTemplate.SignatureAlgorithm = x509.SHA512WithRSA 861 } 862 } 863 } 864 865 // selectSignatureAlgorithmForRSA returns the proper x509.SignatureAlgorithm based on various properties set in the 866 // Creation Bundle parameter. This method will default to a SHA256 signature algorithm if the requested signature 867 // bits is not set/unknown. 868 func selectSignatureAlgorithmForRSA(data *CreationBundle) x509.SignatureAlgorithm { 869 if data.Params.UsePSS { 870 switch data.Params.SignatureBits { 871 case 256: 872 return x509.SHA256WithRSAPSS 873 case 384: 874 return x509.SHA384WithRSAPSS 875 case 512: 876 return x509.SHA512WithRSAPSS 877 default: 878 return x509.SHA256WithRSAPSS 879 } 880 } 881 882 switch data.Params.SignatureBits { 883 case 256: 884 return x509.SHA256WithRSA 885 case 384: 886 return x509.SHA384WithRSA 887 case 512: 888 return x509.SHA512WithRSA 889 default: 890 return x509.SHA256WithRSA 891 } 892 } 893 894 func createCertificate(data *CreationBundle, randReader io.Reader, privateKeyGenerator KeyGenerator) (*ParsedCertBundle, error) { 895 var err error 896 result := &ParsedCertBundle{} 897 898 serialNumber, err := GenerateSerialNumber() 899 if err != nil { 900 return nil, err 901 } 902 903 if err := privateKeyGenerator(data.Params.KeyType, 904 data.Params.KeyBits, 905 result, randReader); err != nil { 906 return nil, err 907 } 908 909 subjKeyID, err := GetSubjKeyID(result.PrivateKey) 910 if err != nil { 911 return nil, errutil.InternalError{Err: fmt.Sprintf("error getting subject key ID: %s", err)} 912 } 913 914 certTemplate := &x509.Certificate{ 915 SerialNumber: serialNumber, 916 NotBefore: time.Now().Add(-30 * time.Second), 917 NotAfter: data.Params.NotAfter, 918 IsCA: false, 919 SubjectKeyId: subjKeyID, 920 Subject: data.Params.Subject, 921 DNSNames: data.Params.DNSNames, 922 EmailAddresses: data.Params.EmailAddresses, 923 IPAddresses: data.Params.IPAddresses, 924 URIs: data.Params.URIs, 925 } 926 if data.Params.NotBeforeDuration > 0 { 927 certTemplate.NotBefore = time.Now().Add(-1 * data.Params.NotBeforeDuration) 928 } 929 930 if err := HandleOtherSANs(certTemplate, data.Params.OtherSANs); err != nil { 931 return nil, errutil.InternalError{Err: errwrap.Wrapf("error marshaling other SANs: {{err}}", err).Error()} 932 } 933 934 // Add this before calling addKeyUsages 935 if data.SigningBundle == nil { 936 certTemplate.IsCA = true 937 } else if data.Params.BasicConstraintsValidForNonCA { 938 certTemplate.BasicConstraintsValid = true 939 certTemplate.IsCA = false 940 } 941 942 // This will only be filled in from the generation paths 943 if len(data.Params.PermittedDNSDomains) > 0 { 944 certTemplate.PermittedDNSDomains = data.Params.PermittedDNSDomains 945 certTemplate.PermittedDNSDomainsCritical = true 946 } 947 948 AddPolicyIdentifiers(data, certTemplate) 949 950 AddKeyUsages(data, certTemplate) 951 952 AddExtKeyUsageOids(data, certTemplate) 953 954 certTemplate.IssuingCertificateURL = data.Params.URLs.IssuingCertificates 955 certTemplate.CRLDistributionPoints = data.Params.URLs.CRLDistributionPoints 956 certTemplate.OCSPServer = data.Params.URLs.OCSPServers 957 958 var certBytes []byte 959 if data.SigningBundle != nil { 960 privateKeyType := data.SigningBundle.PrivateKeyType 961 if privateKeyType == ManagedPrivateKey { 962 privateKeyType = GetPrivateKeyTypeFromSigner(data.SigningBundle.PrivateKey) 963 } 964 switch privateKeyType { 965 case RSAPrivateKey: 966 certTemplateSetSigAlgo(certTemplate, data) 967 case Ed25519PrivateKey: 968 certTemplate.SignatureAlgorithm = x509.PureEd25519 969 case ECPrivateKey: 970 certTemplate.SignatureAlgorithm = selectSignatureAlgorithmForECDSA(data.SigningBundle.PrivateKey.Public(), data.Params.SignatureBits) 971 } 972 973 caCert := data.SigningBundle.Certificate 974 certTemplate.AuthorityKeyId = caCert.SubjectKeyId 975 976 certBytes, err = x509.CreateCertificate(randReader, certTemplate, caCert, result.PrivateKey.Public(), data.SigningBundle.PrivateKey) 977 } else { 978 // Creating a self-signed root 979 if data.Params.MaxPathLength == 0 { 980 certTemplate.MaxPathLen = 0 981 certTemplate.MaxPathLenZero = true 982 } else { 983 certTemplate.MaxPathLen = data.Params.MaxPathLength 984 } 985 986 switch data.Params.KeyType { 987 case "rsa": 988 certTemplateSetSigAlgo(certTemplate, data) 989 case "ed25519": 990 certTemplate.SignatureAlgorithm = x509.PureEd25519 991 case "ec": 992 certTemplate.SignatureAlgorithm = selectSignatureAlgorithmForECDSA(result.PrivateKey.Public(), data.Params.SignatureBits) 993 } 994 995 certTemplate.AuthorityKeyId = subjKeyID 996 certTemplate.BasicConstraintsValid = true 997 certBytes, err = x509.CreateCertificate(randReader, certTemplate, certTemplate, result.PrivateKey.Public(), result.PrivateKey) 998 } 999 1000 if err != nil { 1001 return nil, errutil.InternalError{Err: fmt.Sprintf("unable to create certificate: %s", err)} 1002 } 1003 1004 result.CertificateBytes = certBytes 1005 result.Certificate, err = x509.ParseCertificate(certBytes) 1006 if err != nil { 1007 return nil, errutil.InternalError{Err: fmt.Sprintf("unable to parse created certificate: %s", err)} 1008 } 1009 1010 if data.SigningBundle != nil { 1011 if (len(data.SigningBundle.Certificate.AuthorityKeyId) > 0 && 1012 !bytes.Equal(data.SigningBundle.Certificate.AuthorityKeyId, data.SigningBundle.Certificate.SubjectKeyId)) || 1013 data.Params.ForceAppendCaChain { 1014 var chain []*CertBlock 1015 1016 signingChain := data.SigningBundle.CAChain 1017 // Some bundles already include the root included in the chain, so don't include it twice. 1018 if len(signingChain) == 0 || !bytes.Equal(signingChain[0].Bytes, data.SigningBundle.CertificateBytes) { 1019 chain = append(chain, &CertBlock{ 1020 Certificate: data.SigningBundle.Certificate, 1021 Bytes: data.SigningBundle.CertificateBytes, 1022 }) 1023 } 1024 1025 if len(signingChain) > 0 { 1026 chain = append(chain, signingChain...) 1027 } 1028 1029 result.CAChain = chain 1030 } 1031 } 1032 1033 return result, nil 1034 } 1035 1036 func selectSignatureAlgorithmForECDSA(pub crypto.PublicKey, signatureBits int) x509.SignatureAlgorithm { 1037 // Previously we preferred the user-specified signature bits for ECDSA 1038 // keys. However, this could result in using a longer hash function than 1039 // the underlying NIST P-curve will encode (e.g., a SHA-512 hash with a 1040 // P-256 key). This isn't ideal: the hash is implicitly truncated 1041 // (effectively turning it into SHA-512/256) and we then need to rely 1042 // on the prefix security of the hash. Since both NIST and Mozilla guidance 1043 // suggest instead using the correct hash function, we should prefer that 1044 // over the operator-specified signatureBits. 1045 // 1046 // Lastly, note that pub above needs to be the _signer's_ public key; 1047 // the issue with DefaultOrValueHashBits is that it is called at role 1048 // configuration time, which might _precede_ issuer generation. Thus 1049 // it only has access to the desired key type and not the actual issuer. 1050 // The reference from that function is reproduced below: 1051 // 1052 // > To comply with BSI recommendations Section 4.2 and Mozilla root 1053 // > store policy section 5.1.2, enforce that NIST P-curves use a hash 1054 // > length corresponding to curve length. Note that ed25519 does not 1055 // > implement the "ec" key type. 1056 key, ok := pub.(*ecdsa.PublicKey) 1057 if !ok { 1058 return x509.ECDSAWithSHA256 1059 } 1060 switch key.Curve { 1061 case elliptic.P224(), elliptic.P256(): 1062 return x509.ECDSAWithSHA256 1063 case elliptic.P384(): 1064 return x509.ECDSAWithSHA384 1065 case elliptic.P521(): 1066 return x509.ECDSAWithSHA512 1067 default: 1068 return x509.ECDSAWithSHA256 1069 } 1070 } 1071 1072 var ( 1073 ExtensionBasicConstraintsOID = []int{2, 5, 29, 19} 1074 ExtensionSubjectAltNameOID = []int{2, 5, 29, 17} 1075 ) 1076 1077 // CreateCSR creates a CSR with the default rand.Reader to 1078 // generate a cert/keypair. This is currently only meant 1079 // for use when generating an intermediate certificate. 1080 func CreateCSR(data *CreationBundle, addBasicConstraints bool) (*ParsedCSRBundle, error) { 1081 return createCSR(data, addBasicConstraints, rand.Reader, generatePrivateKey) 1082 } 1083 1084 // CreateCSRWithRandomSource creates a CSR with a custom io.Reader 1085 // for randomness to generate a cert/keypair. 1086 func CreateCSRWithRandomSource(data *CreationBundle, addBasicConstraints bool, randReader io.Reader) (*ParsedCSRBundle, error) { 1087 return createCSR(data, addBasicConstraints, randReader, generatePrivateKey) 1088 } 1089 1090 // CreateCSRWithKeyGenerator creates a CSR with a custom io.Reader 1091 // for randomness to generate a cert/keypair with the provided private key generator. 1092 func CreateCSRWithKeyGenerator(data *CreationBundle, addBasicConstraints bool, randReader io.Reader, keyGenerator KeyGenerator) (*ParsedCSRBundle, error) { 1093 return createCSR(data, addBasicConstraints, randReader, keyGenerator) 1094 } 1095 1096 func createCSR(data *CreationBundle, addBasicConstraints bool, randReader io.Reader, keyGenerator KeyGenerator) (*ParsedCSRBundle, error) { 1097 var err error 1098 result := &ParsedCSRBundle{} 1099 1100 if err := keyGenerator(data.Params.KeyType, 1101 data.Params.KeyBits, 1102 result, randReader); err != nil { 1103 return nil, err 1104 } 1105 1106 // Like many root CAs, other information is ignored 1107 csrTemplate := &x509.CertificateRequest{ 1108 Subject: data.Params.Subject, 1109 DNSNames: data.Params.DNSNames, 1110 EmailAddresses: data.Params.EmailAddresses, 1111 IPAddresses: data.Params.IPAddresses, 1112 URIs: data.Params.URIs, 1113 } 1114 1115 if err := HandleOtherCSRSANs(csrTemplate, data.Params.OtherSANs); err != nil { 1116 return nil, errutil.InternalError{Err: errwrap.Wrapf("error marshaling other SANs: {{err}}", err).Error()} 1117 } 1118 1119 if addBasicConstraints { 1120 type basicConstraints struct { 1121 IsCA bool `asn1:"optional"` 1122 MaxPathLen int `asn1:"optional,default:-1"` 1123 } 1124 val, err := asn1.Marshal(basicConstraints{IsCA: true, MaxPathLen: -1}) 1125 if err != nil { 1126 return nil, errutil.InternalError{Err: errwrap.Wrapf("error marshaling basic constraints: {{err}}", err).Error()} 1127 } 1128 ext := pkix.Extension{ 1129 Id: ExtensionBasicConstraintsOID, 1130 Value: val, 1131 Critical: true, 1132 } 1133 csrTemplate.ExtraExtensions = append(csrTemplate.ExtraExtensions, ext) 1134 } 1135 1136 switch data.Params.KeyType { 1137 case "rsa": 1138 // use specified RSA algorithm defaulting to the appropriate SHA256 RSA signature type 1139 csrTemplate.SignatureAlgorithm = selectSignatureAlgorithmForRSA(data) 1140 case "ec": 1141 csrTemplate.SignatureAlgorithm = selectSignatureAlgorithmForECDSA(result.PrivateKey.Public(), data.Params.SignatureBits) 1142 case "ed25519": 1143 csrTemplate.SignatureAlgorithm = x509.PureEd25519 1144 } 1145 1146 csr, err := x509.CreateCertificateRequest(randReader, csrTemplate, result.PrivateKey) 1147 if err != nil { 1148 return nil, errutil.InternalError{Err: fmt.Sprintf("unable to create certificate: %s", err)} 1149 } 1150 1151 result.CSRBytes = csr 1152 result.CSR, err = x509.ParseCertificateRequest(csr) 1153 if err != nil { 1154 return nil, errutil.InternalError{Err: fmt.Sprintf("unable to parse created certificate: %v", err)} 1155 } 1156 1157 if err = result.CSR.CheckSignature(); err != nil { 1158 return nil, errors.New("failed signature validation for CSR") 1159 } 1160 1161 return result, nil 1162 } 1163 1164 // SignCertificate performs the heavy lifting 1165 // of generating a certificate from a CSR. 1166 // Returns a ParsedCertBundle sans private keys. 1167 func SignCertificate(data *CreationBundle) (*ParsedCertBundle, error) { 1168 return signCertificate(data, rand.Reader) 1169 } 1170 1171 // SignCertificateWithRandomSource generates a certificate 1172 // from a CSR, using custom randomness from the randReader. 1173 // Returns a ParsedCertBundle sans private keys. 1174 func SignCertificateWithRandomSource(data *CreationBundle, randReader io.Reader) (*ParsedCertBundle, error) { 1175 return signCertificate(data, randReader) 1176 } 1177 1178 func signCertificate(data *CreationBundle, randReader io.Reader) (*ParsedCertBundle, error) { 1179 switch { 1180 case data == nil: 1181 return nil, errutil.UserError{Err: "nil data bundle given to signCertificate"} 1182 case data.Params == nil: 1183 return nil, errutil.UserError{Err: "nil parameters given to signCertificate"} 1184 case data.SigningBundle == nil: 1185 return nil, errutil.UserError{Err: "nil signing bundle given to signCertificate"} 1186 case data.CSR == nil: 1187 return nil, errutil.UserError{Err: "nil csr given to signCertificate"} 1188 } 1189 1190 err := data.CSR.CheckSignature() 1191 if err != nil { 1192 return nil, errutil.UserError{Err: "request signature invalid"} 1193 } 1194 1195 result := &ParsedCertBundle{} 1196 1197 serialNumber, err := GenerateSerialNumber() 1198 if err != nil { 1199 return nil, err 1200 } 1201 1202 subjKeyID, err := getSubjectKeyIDFromBundle(data) 1203 if err != nil { 1204 return nil, err 1205 } 1206 1207 caCert := data.SigningBundle.Certificate 1208 1209 certTemplate := &x509.Certificate{ 1210 SerialNumber: serialNumber, 1211 Subject: data.Params.Subject, 1212 NotBefore: time.Now().Add(-30 * time.Second), 1213 NotAfter: data.Params.NotAfter, 1214 SubjectKeyId: subjKeyID[:], 1215 AuthorityKeyId: caCert.SubjectKeyId, 1216 } 1217 if data.Params.NotBeforeDuration > 0 { 1218 certTemplate.NotBefore = time.Now().Add(-1 * data.Params.NotBeforeDuration) 1219 } 1220 1221 privateKeyType := data.SigningBundle.PrivateKeyType 1222 if privateKeyType == ManagedPrivateKey { 1223 privateKeyType = GetPrivateKeyTypeFromSigner(data.SigningBundle.PrivateKey) 1224 } 1225 1226 switch privateKeyType { 1227 case RSAPrivateKey: 1228 certTemplateSetSigAlgo(certTemplate, data) 1229 case ECPrivateKey: 1230 switch data.Params.SignatureBits { 1231 case 256: 1232 certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA256 1233 case 384: 1234 certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA384 1235 case 512: 1236 certTemplate.SignatureAlgorithm = x509.ECDSAWithSHA512 1237 } 1238 } 1239 1240 if data.Params.UseCSRValues { 1241 certTemplate.Subject = data.CSR.Subject 1242 certTemplate.Subject.ExtraNames = certTemplate.Subject.Names 1243 1244 certTemplate.DNSNames = data.CSR.DNSNames 1245 certTemplate.EmailAddresses = data.CSR.EmailAddresses 1246 certTemplate.IPAddresses = data.CSR.IPAddresses 1247 certTemplate.URIs = data.CSR.URIs 1248 1249 for _, name := range data.CSR.Extensions { 1250 if !name.Id.Equal(ExtensionBasicConstraintsOID) && !(len(data.Params.OtherSANs) > 0 && name.Id.Equal(ExtensionSubjectAltNameOID)) { 1251 certTemplate.ExtraExtensions = append(certTemplate.ExtraExtensions, name) 1252 } 1253 } 1254 1255 } else { 1256 certTemplate.DNSNames = data.Params.DNSNames 1257 certTemplate.EmailAddresses = data.Params.EmailAddresses 1258 certTemplate.IPAddresses = data.Params.IPAddresses 1259 certTemplate.URIs = data.Params.URIs 1260 } 1261 1262 if err := HandleOtherSANs(certTemplate, data.Params.OtherSANs); err != nil { 1263 return nil, errutil.InternalError{Err: errwrap.Wrapf("error marshaling other SANs: {{err}}", err).Error()} 1264 } 1265 1266 AddPolicyIdentifiers(data, certTemplate) 1267 1268 AddKeyUsages(data, certTemplate) 1269 1270 AddExtKeyUsageOids(data, certTemplate) 1271 1272 var certBytes []byte 1273 1274 certTemplate.IssuingCertificateURL = data.Params.URLs.IssuingCertificates 1275 certTemplate.CRLDistributionPoints = data.Params.URLs.CRLDistributionPoints 1276 certTemplate.OCSPServer = data.SigningBundle.URLs.OCSPServers 1277 1278 if data.Params.IsCA { 1279 certTemplate.BasicConstraintsValid = true 1280 certTemplate.IsCA = true 1281 1282 if data.SigningBundle.Certificate.MaxPathLen == 0 && 1283 data.SigningBundle.Certificate.MaxPathLenZero { 1284 return nil, errutil.UserError{Err: "signing certificate has a max path length of zero, and cannot issue further CA certificates"} 1285 } 1286 1287 certTemplate.MaxPathLen = data.Params.MaxPathLength 1288 if certTemplate.MaxPathLen == 0 { 1289 certTemplate.MaxPathLenZero = true 1290 } 1291 } else if data.Params.BasicConstraintsValidForNonCA { 1292 certTemplate.BasicConstraintsValid = true 1293 certTemplate.IsCA = false 1294 } 1295 1296 if len(data.Params.PermittedDNSDomains) > 0 { 1297 certTemplate.PermittedDNSDomains = data.Params.PermittedDNSDomains 1298 certTemplate.PermittedDNSDomainsCritical = true 1299 } 1300 1301 certBytes, err = x509.CreateCertificate(randReader, certTemplate, caCert, data.CSR.PublicKey, data.SigningBundle.PrivateKey) 1302 if err != nil { 1303 return nil, errutil.InternalError{Err: fmt.Sprintf("unable to create certificate: %s", err)} 1304 } 1305 1306 result.CertificateBytes = certBytes 1307 result.Certificate, err = x509.ParseCertificate(certBytes) 1308 if err != nil { 1309 return nil, errutil.InternalError{Err: fmt.Sprintf("unable to parse created certificate: %s", err)} 1310 } 1311 1312 result.CAChain = data.SigningBundle.GetFullChain() 1313 1314 return result, nil 1315 } 1316 1317 func NewCertPool(reader io.Reader) (*x509.CertPool, error) { 1318 pemBlock, err := ioutil.ReadAll(reader) 1319 if err != nil { 1320 return nil, err 1321 } 1322 certs, err := ParseCertsPEM(pemBlock) 1323 if err != nil { 1324 return nil, fmt.Errorf("error reading certs: %s", err) 1325 } 1326 pool := x509.NewCertPool() 1327 for _, cert := range certs { 1328 pool.AddCert(cert) 1329 } 1330 return pool, nil 1331 } 1332 1333 // ParseCertsPEM returns the x509.Certificates contained in the given PEM-encoded byte array 1334 // Returns an error if a certificate could not be parsed, or if the data does not contain any certificates 1335 func ParseCertsPEM(pemCerts []byte) ([]*x509.Certificate, error) { 1336 ok := false 1337 certs := []*x509.Certificate{} 1338 for len(pemCerts) > 0 { 1339 var block *pem.Block 1340 block, pemCerts = pem.Decode(pemCerts) 1341 if block == nil { 1342 break 1343 } 1344 // Only use PEM "CERTIFICATE" blocks without extra headers 1345 if block.Type != "CERTIFICATE" || len(block.Headers) != 0 { 1346 continue 1347 } 1348 1349 cert, err := x509.ParseCertificate(block.Bytes) 1350 if err != nil { 1351 return certs, err 1352 } 1353 1354 certs = append(certs, cert) 1355 ok = true 1356 } 1357 1358 if !ok { 1359 return certs, errors.New("data does not contain any valid RSA or ECDSA certificates") 1360 } 1361 return certs, nil 1362 } 1363 1364 // GetPublicKeySize returns the key size in bits for a given arbitrary crypto.PublicKey 1365 // Returns -1 for an unsupported key type. 1366 func GetPublicKeySize(key crypto.PublicKey) int { 1367 if key, ok := key.(*rsa.PublicKey); ok { 1368 return key.Size() * 8 1369 } 1370 if key, ok := key.(*ecdsa.PublicKey); ok { 1371 return key.Params().BitSize 1372 } 1373 if key, ok := key.(ed25519.PublicKey); ok { 1374 return len(key) * 8 1375 } 1376 if key, ok := key.(dsa.PublicKey); ok { 1377 return key.Y.BitLen() 1378 } 1379 1380 return -1 1381 } 1382 1383 // CreateKeyBundle create a KeyBundle struct object which includes a generated key 1384 // of keyType with keyBits leveraging the randomness from randReader. 1385 func CreateKeyBundle(keyType string, keyBits int, randReader io.Reader) (KeyBundle, error) { 1386 return CreateKeyBundleWithKeyGenerator(keyType, keyBits, randReader, generatePrivateKey) 1387 } 1388 1389 // CreateKeyBundleWithKeyGenerator create a KeyBundle struct object which includes 1390 // a generated key of keyType with keyBits leveraging the randomness from randReader and 1391 // delegates the actual key generation to keyGenerator 1392 func CreateKeyBundleWithKeyGenerator(keyType string, keyBits int, randReader io.Reader, keyGenerator KeyGenerator) (KeyBundle, error) { 1393 result := KeyBundle{} 1394 if err := keyGenerator(keyType, keyBits, &result, randReader); err != nil { 1395 return result, err 1396 } 1397 return result, nil 1398 } 1399 1400 // CreateDeltaCRLIndicatorExt allows creating correctly formed delta CRLs 1401 // that point back to the last complete CRL that they're based on. 1402 func CreateDeltaCRLIndicatorExt(completeCRLNumber int64) (pkix.Extension, error) { 1403 bigNum := big.NewInt(completeCRLNumber) 1404 bigNumValue, err := asn1.Marshal(bigNum) 1405 if err != nil { 1406 return pkix.Extension{}, fmt.Errorf("unable to marshal complete CRL number (%v): %v", completeCRLNumber, err) 1407 } 1408 return pkix.Extension{ 1409 Id: DeltaCRLIndicatorOID, 1410 // > When a conforming CRL issuer generates a delta CRL, the delta 1411 // > CRL MUST include a critical delta CRL indicator extension. 1412 Critical: true, 1413 // This extension only includes the complete CRL number: 1414 // 1415 // > BaseCRLNumber ::= CRLNumber 1416 // 1417 // But, this needs to be encoded as a big number for encoding/asn1 1418 // to work properly. 1419 Value: bigNumValue, 1420 }, nil 1421 } 1422 1423 // ParseBasicConstraintExtension parses a basic constraint pkix.Extension, useful if attempting to validate 1424 // CSRs are requesting CA privileges as Go does not expose its implementation. Values returned are 1425 // IsCA, MaxPathLen or error. If MaxPathLen was not set, a value of -1 will be returned. 1426 func ParseBasicConstraintExtension(ext pkix.Extension) (bool, int, error) { 1427 if !ext.Id.Equal(ExtensionBasicConstraintsOID) { 1428 return false, -1, fmt.Errorf("passed in extension was not a basic constraint extension") 1429 } 1430 1431 // All elements are set to optional here, as it is possible that we receive a CSR with the extension 1432 // containing an empty sequence by spec. 1433 type basicConstraints struct { 1434 IsCA bool `asn1:"optional"` 1435 MaxPathLen int `asn1:"optional,default:-1"` 1436 } 1437 bc := &basicConstraints{} 1438 leftOver, err := asn1.Unmarshal(ext.Value, bc) 1439 if err != nil { 1440 return false, -1, fmt.Errorf("failed unmarshalling extension value: %w", err) 1441 } 1442 1443 numLeftOver := len(bytes.TrimSpace(leftOver)) 1444 if numLeftOver > 0 { 1445 return false, -1, fmt.Errorf("%d extra bytes within basic constraints value extension", numLeftOver) 1446 } 1447 1448 return bc.IsCA, bc.MaxPathLen, nil 1449 } 1450 1451 // CreateBasicConstraintExtension create a basic constraint extension based on inputs, 1452 // if isCa is false, an empty value sequence will be returned with maxPath being 1453 // ignored. If isCa is true maxPath can be set to -1 to not set a maxPath value. 1454 func CreateBasicConstraintExtension(isCa bool, maxPath int) (pkix.Extension, error) { 1455 var asn1Bytes []byte 1456 var err error 1457 1458 switch { 1459 case isCa && maxPath >= 0: 1460 CaAndMaxPathLen := struct { 1461 IsCa bool `asn1:""` 1462 MaxPathLen int `asn1:""` 1463 }{ 1464 IsCa: isCa, 1465 MaxPathLen: maxPath, 1466 } 1467 asn1Bytes, err = asn1.Marshal(CaAndMaxPathLen) 1468 case isCa && maxPath < 0: 1469 justCa := struct { 1470 IsCa bool `asn1:""` 1471 }{IsCa: isCa} 1472 asn1Bytes, err = asn1.Marshal(justCa) 1473 default: 1474 asn1Bytes, err = asn1.Marshal(struct{}{}) 1475 } 1476 1477 if err != nil { 1478 return pkix.Extension{}, err 1479 } 1480 1481 return pkix.Extension{ 1482 Id: ExtensionBasicConstraintsOID, 1483 Critical: true, 1484 Value: asn1Bytes, 1485 }, nil 1486 } 1487 1488 // GetOtherSANsFromX509Extensions is used to find all the extensions which have the identifier (OID) of 1489 // a SAN (Subject Alternative Name), and then look at each extension to find out if it is one of a set of 1490 // well-known types (like IP SANs) or "other". Currently, the only OtherSANs vault supports are of type UTF8. 1491 func GetOtherSANsFromX509Extensions(exts []pkix.Extension) ([]OtherNameUtf8, error) { 1492 var ret []OtherNameUtf8 1493 for _, ext := range exts { 1494 if !ext.Id.Equal(OidExtensionSubjectAltName) { 1495 continue 1496 } 1497 err := forEachSAN(ext.Value, func(tag int, data []byte) error { 1498 if tag != 0 { 1499 return nil 1500 } 1501 1502 var other OtherNameRaw 1503 _, err := asn1.UnmarshalWithParams(data, &other, "tag:0") 1504 if err != nil { 1505 return fmt.Errorf("could not parse requested other SAN: %w", err) 1506 } 1507 val, err := other.ExtractUTF8String() 1508 if err != nil { 1509 return err 1510 } 1511 ret = append(ret, *val) 1512 return nil 1513 }) 1514 if err != nil { 1515 return nil, err 1516 } 1517 } 1518 1519 return ret, nil 1520 } 1521 1522 func forEachSAN(extension []byte, callback func(tag int, data []byte) error) error { 1523 // RFC 5280, 4.2.1.6 1524 1525 // SubjectAltName ::= GeneralNames 1526 // 1527 // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 1528 // 1529 // GeneralName ::= CHOICE { 1530 // otherName [0] OtherName, 1531 // rfc822Name [1] IA5String, 1532 // dNSName [2] IA5String, 1533 // x400Address [3] ORAddress, 1534 // directoryName [4] Name, 1535 // ediPartyName [5] EDIPartyName, 1536 // uniformResourceIdentifier [6] IA5String, 1537 // iPAddress [7] OCTET STRING, 1538 // registeredID [8] OBJECT IDENTIFIER } 1539 var seq asn1.RawValue 1540 rest, err := asn1.Unmarshal(extension, &seq) 1541 if err != nil { 1542 return err 1543 } else if len(rest) != 0 { 1544 return fmt.Errorf("x509: trailing data after X.509 extension") 1545 } 1546 if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 { 1547 return asn1.StructuralError{Msg: "bad SAN sequence"} 1548 } 1549 1550 rest = seq.Bytes 1551 for len(rest) > 0 { 1552 var v asn1.RawValue 1553 rest, err = asn1.Unmarshal(rest, &v) 1554 if err != nil { 1555 return err 1556 } 1557 1558 if err := callback(v.Tag, v.FullBytes); err != nil { 1559 return err 1560 } 1561 } 1562 1563 return nil 1564 } 1565 1566 // otherNameRaw describes a name related to a certificate which is not in one 1567 // of the standard name formats. RFC 5280, 4.2.1.6: 1568 // 1569 // OtherName ::= SEQUENCE { 1570 // type-id OBJECT IDENTIFIER, 1571 // Value [0] EXPLICIT ANY DEFINED BY type-id } 1572 type OtherNameRaw struct { 1573 TypeID asn1.ObjectIdentifier 1574 Value asn1.RawValue 1575 } 1576 1577 type OtherNameUtf8 struct { 1578 Oid string 1579 Value string 1580 } 1581 1582 // String() turns an OtherNameUtf8 object into the storage or field-value used to assign that name 1583 // to a certificate in an API call 1584 func (o OtherNameUtf8) String() string { 1585 return fmt.Sprintf("%s;%s:%s", o.Oid, "UTF-8", o.Value) 1586 } 1587 1588 // ExtractUTF8String returns the UTF8 string contained in the Value, or an error 1589 // if none is present. 1590 func (oraw *OtherNameRaw) ExtractUTF8String() (*OtherNameUtf8, error) { 1591 svalue := cryptobyte.String(oraw.Value.Bytes) 1592 var outTag cbasn1.Tag 1593 var val cryptobyte.String 1594 read := svalue.ReadAnyASN1(&val, &outTag) 1595 1596 if read && outTag == asn1.TagUTF8String { 1597 return &OtherNameUtf8{Oid: oraw.TypeID.String(), Value: string(val)}, nil 1598 } 1599 return nil, fmt.Errorf("no UTF-8 string found in OtherName") 1600 } 1601 1602 func getOtherSANsStringFromExtensions(exts []pkix.Extension) (string, error) { 1603 otherNames, err := GetOtherSANsFromX509Extensions(exts) 1604 if err != nil { 1605 return "", err 1606 } 1607 1608 otherSansList := make([]string, len(otherNames)) 1609 for i, otherName := range otherNames { 1610 otherSansList[i] = otherName.String() 1611 } 1612 1613 otherSans := strings.Join(otherSansList, ",") 1614 1615 return otherSans, nil 1616 } 1617 1618 func getOtherSANsMapFromExtensions(exts []pkix.Extension) (map[string][]string, error) { 1619 otherNames, err := GetOtherSANsFromX509Extensions(exts) 1620 if err != nil { 1621 return nil, err 1622 } 1623 1624 otherSans := make(map[string][]string) 1625 for _, name := range otherNames { 1626 if otherSans[name.Oid] == nil { 1627 otherSans[name.Oid] = []string{name.Value} 1628 } else { 1629 otherSans[name.Oid] = append(otherSans[name.Oid], name.Value) 1630 } 1631 } 1632 1633 return otherSans, nil 1634 } 1635 1636 func getKeyUsage(exts []pkix.Extension) (x509.KeyUsage, error) { 1637 keyUsage := x509.KeyUsage(0) 1638 for _, ext := range exts { 1639 if ext.Id.Equal(KeyUsageOID) { 1640 // ASN1 is Big Endian 1641 // another example of equivalent code: https://cs.opensource.google/go/go/+/master:src/crypto/x509/parser.go;drc=dd84bb682482390bb8465482cb7b13d2e3b17297;l=319 1642 buf := bytes.NewReader(ext.Value) 1643 err := binary.Read(buf, binary.BigEndian, &keyUsage) 1644 if err != nil { 1645 return keyUsage, err 1646 } 1647 return keyUsage, nil 1648 } 1649 } 1650 return keyUsage, nil 1651 } 1652 1653 func getExtKeyUsageOids(exts []pkix.Extension) ([]string, error) { 1654 keyUsageOidStrings := make([]string, 0) 1655 keyUsageOids := make([]asn1.ObjectIdentifier, 0) 1656 for _, ext := range exts { 1657 if ext.Id.Equal(ExtendedKeyUsageOID) { 1658 _, err := asn1.Unmarshal(ext.Value, &keyUsageOids) 1659 if err != nil { 1660 return nil, fmt.Errorf("unable to unmarshal KeyUsageOid extension: %w", err) 1661 } 1662 for _, oid := range keyUsageOids { 1663 keyUsageOidStrings = append(keyUsageOidStrings, oid.String()) 1664 } 1665 return keyUsageOidStrings, nil 1666 } 1667 } 1668 return nil, nil 1669 } 1670 1671 func getPolicyIdentifiers(exts []pkix.Extension) ([]string, error) { 1672 policyIdentifiers := make([]string, 0) 1673 for _, ext := range exts { 1674 if ext.Id.Equal(policyInformationOid) { 1675 // PolicyInformation ::= SEQUENCE { 1676 // policyIdentifier CertPolicyId, 1677 // policyQualifiers SEQUENCE SIZE (1..MAX) OF 1678 // PolicyQualifierInfo OPTIONAL } 1679 type policyInformation struct { 1680 PolicyIdentifier asn1.ObjectIdentifier `asn1:"optional"` 1681 PolicyQualifier any `asn1:"optional"` 1682 } 1683 policies := make([]policyInformation, 0) 1684 _, err := asn1.Unmarshal(ext.Value, &policies) 1685 if err != nil { 1686 return nil, err 1687 } 1688 for _, policy := range policies { 1689 policyIdentifiers = append(policyIdentifiers, policy.PolicyIdentifier.String()) 1690 } 1691 return policyIdentifiers, nil 1692 } 1693 } 1694 return nil, nil 1695 } 1696 1697 // Translate Certificates and CSRs into Certificate Template 1698 // Four "Types" Here: Certificates; Certificate Signing Requests; Fields map[string]interface{}; Creation Parameters 1699 1700 func ParseCertificateToCreationParameters(certificate x509.Certificate) (creationParameters CreationParameters, err error) { 1701 otherSans, err := getOtherSANsMapFromExtensions(certificate.Extensions) 1702 if err != nil { 1703 return CreationParameters{}, err 1704 } 1705 1706 creationParameters = CreationParameters{ 1707 Subject: removeNames(certificate.Subject), 1708 DNSNames: certificate.DNSNames, 1709 EmailAddresses: certificate.EmailAddresses, 1710 IPAddresses: certificate.IPAddresses, 1711 URIs: certificate.URIs, 1712 OtherSANs: otherSans, 1713 IsCA: certificate.IsCA, 1714 KeyType: GetKeyType(certificate.PublicKeyAlgorithm.String()), 1715 KeyBits: FindBitLength(certificate.PublicKey), 1716 NotAfter: certificate.NotAfter, 1717 KeyUsage: certificate.KeyUsage, 1718 // ExtKeyUsage: We use ExtKeyUsageOIDs instead as the more general field 1719 // ExtKeyUsageOIDs: this is an extension that may not be set, so is handled below 1720 // PolicyIdentifiers: this is an extension that may not be set, so is handled below 1721 BasicConstraintsValidForNonCA: certificate.BasicConstraintsValid, 1722 SignatureBits: FindSignatureBits(certificate.SignatureAlgorithm), 1723 UsePSS: IsPSS(certificate.SignatureAlgorithm), 1724 // The following two values are on creation parameters, but are impossible to parse from the certificate 1725 // ForceAppendCaChain 1726 // UseCSRValues 1727 PermittedDNSDomains: certificate.PermittedDNSDomains, 1728 // URLs: punting on this for now 1729 MaxPathLength: certificate.MaxPathLen, 1730 NotBeforeDuration: time.Now().Sub(certificate.NotBefore), // Assumes Certificate was created this moment 1731 SKID: certificate.SubjectKeyId, 1732 } 1733 1734 extKeyUsageOIDS, err := getExtKeyUsageOids(certificate.Extensions) 1735 if err != nil { 1736 return CreationParameters{}, err 1737 } 1738 creationParameters.ExtKeyUsageOIDs = extKeyUsageOIDS 1739 1740 policyInformationOids, err := getPolicyIdentifiers(certificate.Extensions) 1741 if err != nil { 1742 return CreationParameters{}, err 1743 } 1744 creationParameters.PolicyIdentifiers = policyInformationOids 1745 1746 return creationParameters, err 1747 } 1748 1749 func removeNames(name pkix.Name) pkix.Name { 1750 name.Names = nil 1751 return name 1752 } 1753 1754 func ParseCsrToCreationParameters(csr x509.CertificateRequest) (CreationParameters, error) { 1755 otherSANs, err := getOtherSANsMapFromExtensions(csr.Extensions) 1756 if err != nil { 1757 return CreationParameters{}, err 1758 } 1759 1760 creationParameters := CreationParameters{ 1761 Subject: removeNames(csr.Subject), 1762 DNSNames: csr.DNSNames, 1763 EmailAddresses: csr.EmailAddresses, 1764 IPAddresses: csr.IPAddresses, 1765 URIs: csr.URIs, 1766 OtherSANs: otherSANs, 1767 // IsCA: is handled below since the basic constraint it comes from might not be set on the CSR 1768 KeyType: GetKeyType(csr.PublicKeyAlgorithm.String()), 1769 KeyBits: FindBitLength(csr.PublicKey), 1770 // NotAfter: this is not set on a CSR 1771 // KeyUsage: handled below since this may not be set 1772 // ExtKeyUsage: We use exclusively ExtKeyUsageOIDs here 1773 // ExtKeyUsageOIDs: handled below since this may not be set 1774 // PolicyIdentifiers: handled below since this may not be set 1775 // BasicConstraintsValidForNonCA is handled below, since it may or may not be set on the CSR 1776 SignatureBits: FindSignatureBits(csr.SignatureAlgorithm), 1777 UsePSS: IsPSS(csr.SignatureAlgorithm), 1778 // The following two values are on creation parameters, but are impossible to parse from the csr 1779 // ForceAppendCaChain 1780 // UseCSRValues 1781 // PermittedDNSDomains : omitted, this generally isn't on a CSR 1782 // URLs : omitted, this generally isn't on a CSR 1783 // MaxPathLength is handled below since the basic constraint it comes from may not be set on the CSR 1784 // NotBeforeDuration : this is not set on a CSR 1785 // SKID: this is generally not set on a CSR, but calculated from the Key information itself 1786 } 1787 1788 keyUsage, err := getKeyUsage(csr.Extensions) 1789 if err != nil { 1790 return CreationParameters{}, err 1791 } 1792 creationParameters.KeyUsage = keyUsage 1793 1794 extKeyUsageOIDS, err := getExtKeyUsageOids(csr.Extensions) 1795 if err != nil { 1796 return CreationParameters{}, err 1797 } 1798 creationParameters.ExtKeyUsageOIDs = extKeyUsageOIDS 1799 1800 policyInformationOids, err := getPolicyIdentifiers(csr.Extensions) 1801 if err != nil { 1802 return CreationParameters{}, err 1803 } 1804 creationParameters.PolicyIdentifiers = policyInformationOids 1805 1806 found, isCA, maxPathLength, err := getBasicConstraintsFromExtension(csr.Extensions) 1807 if err != nil { 1808 return CreationParameters{}, err 1809 } 1810 if found { 1811 creationParameters.IsCA = isCA 1812 creationParameters.BasicConstraintsValidForNonCA = (isCA && maxPathLength != 0) || (!isCA && (maxPathLength == 0)) 1813 if isCA { // MaxPathLength Only Has a Meaning on a Certificate Authority 1814 creationParameters.MaxPathLength = maxPathLength 1815 } 1816 } 1817 1818 return creationParameters, err 1819 } 1820 1821 func ParseCsrToFields(csr x509.CertificateRequest) (map[string]interface{}, error) { 1822 otherSans, err := getOtherSANsStringFromExtensions(csr.Extensions) 1823 if err != nil { 1824 return nil, err 1825 } 1826 1827 templateData := map[string]interface{}{ 1828 "common_name": csr.Subject.CommonName, 1829 "alt_names": MakeAltNamesCommaSeparatedString(csr.DNSNames, csr.EmailAddresses), 1830 "ip_sans": MakeIpAddressCommaSeparatedString(csr.IPAddresses), 1831 "uri_sans": MakeUriCommaSeparatedString(csr.URIs), 1832 "other_sans": otherSans, 1833 "signature_bits": FindSignatureBits(csr.SignatureAlgorithm), 1834 "exclude_cn_from_sans": DetermineExcludeCnFromCsrSans(csr), 1835 "ou": makeCommaSeparatedString(csr.Subject.OrganizationalUnit), 1836 "organization": makeCommaSeparatedString(csr.Subject.Organization), 1837 "country": makeCommaSeparatedString(csr.Subject.Country), 1838 "locality": makeCommaSeparatedString(csr.Subject.Locality), 1839 "province": makeCommaSeparatedString(csr.Subject.Province), 1840 "street_address": makeCommaSeparatedString(csr.Subject.StreetAddress), 1841 "postal_code": makeCommaSeparatedString(csr.Subject.PostalCode), 1842 "serial_number": csr.Subject.SerialNumber, 1843 // There is no "TTL" on a CSR, that is always set by the signer 1844 // max_path_length is handled below 1845 // permitted_dns_domains is a CA thing, it generally does not appear on a CSR 1846 "use_pss": IsPSS(csr.SignatureAlgorithm), 1847 // skid could be calculated, but does not directly exist on a csr, so punting for now 1848 "key_type": GetKeyType(csr.PublicKeyAlgorithm.String()), 1849 "key_bits": FindBitLength(csr.PublicKey), 1850 } 1851 1852 // isCA is not a field in our data call - that is represented inside vault by using a different endpoint 1853 found, _, _, err := getBasicConstraintsFromExtension(csr.Extensions) 1854 if err != nil { 1855 return nil, err 1856 } 1857 templateData["add_basic_constraints"] = found 1858 1859 return templateData, nil 1860 } 1861 1862 func ParseCertificateToFields(certificate x509.Certificate) (map[string]interface{}, error) { 1863 otherSans, err := getOtherSANsStringFromExtensions(certificate.Extensions) 1864 if err != nil { 1865 return nil, err 1866 } 1867 1868 templateData := map[string]interface{}{ 1869 "common_name": certificate.Subject.CommonName, 1870 "alt_names": MakeAltNamesCommaSeparatedString(certificate.DNSNames, certificate.EmailAddresses), 1871 "ip_sans": MakeIpAddressCommaSeparatedString(certificate.IPAddresses), 1872 "uri_sans": MakeUriCommaSeparatedString(certificate.URIs), 1873 "other_sans": otherSans, 1874 "signature_bits": FindSignatureBits(certificate.SignatureAlgorithm), 1875 "exclude_cn_from_sans": DetermineExcludeCnFromCertSans(certificate), 1876 "ou": makeCommaSeparatedString(certificate.Subject.OrganizationalUnit), 1877 "organization": makeCommaSeparatedString(certificate.Subject.Organization), 1878 "country": makeCommaSeparatedString(certificate.Subject.Country), 1879 "locality": makeCommaSeparatedString(certificate.Subject.Locality), 1880 "province": makeCommaSeparatedString(certificate.Subject.Province), 1881 "street_address": makeCommaSeparatedString(certificate.Subject.StreetAddress), 1882 "postal_code": makeCommaSeparatedString(certificate.Subject.PostalCode), 1883 "serial_number": certificate.Subject.SerialNumber, 1884 "ttl": (certificate.NotAfter.Sub(certificate.NotBefore)).String(), 1885 "max_path_length": certificate.MaxPathLen, 1886 "permitted_dns_domains": strings.Join(certificate.PermittedDNSDomains, ","), 1887 "use_pss": IsPSS(certificate.SignatureAlgorithm), 1888 "skid": hex.EncodeToString(certificate.SubjectKeyId), 1889 "key_type": GetKeyType(certificate.PublicKeyAlgorithm.String()), 1890 "key_bits": FindBitLength(certificate.PublicKey), 1891 } 1892 1893 return templateData, nil 1894 } 1895 1896 func getBasicConstraintsFromExtension(exts []pkix.Extension) (found bool, isCA bool, maxPathLength int, err error) { 1897 for _, ext := range exts { 1898 if ext.Id.Equal(ExtensionBasicConstraintsOID) { 1899 isCA, maxPathLength, err = ParseBasicConstraintExtension(ext) 1900 if err != nil { 1901 return false, false, -1, err 1902 } 1903 return true, isCA, maxPathLength, nil 1904 } 1905 } 1906 1907 return false, false, -1, nil 1908 } 1909 1910 func MakeAltNamesCommaSeparatedString(names []string, emails []string) string { 1911 return strings.Join(append(names, emails...), ",") 1912 } 1913 1914 func MakeUriCommaSeparatedString(uris []*url.URL) string { 1915 stringAddresses := make([]string, len(uris)) 1916 for i, uri := range uris { 1917 stringAddresses[i] = uri.String() 1918 } 1919 return strings.Join(stringAddresses, ",") 1920 } 1921 1922 func MakeIpAddressCommaSeparatedString(addresses []net.IP) string { 1923 stringAddresses := make([]string, len(addresses)) 1924 for i, address := range addresses { 1925 stringAddresses[i] = address.String() 1926 } 1927 return strings.Join(stringAddresses, ",") 1928 } 1929 1930 func makeCommaSeparatedString(values []string) string { 1931 return strings.Join(values, ",") 1932 } 1933 1934 func DetermineExcludeCnFromCertSans(certificate x509.Certificate) bool { 1935 cn := certificate.Subject.CommonName 1936 if cn == "" { 1937 return false 1938 } 1939 1940 emails := certificate.EmailAddresses 1941 for _, email := range emails { 1942 if email == cn { 1943 return false 1944 } 1945 } 1946 1947 dnses := certificate.DNSNames 1948 for _, dns := range dnses { 1949 if dns == cn { 1950 return false 1951 } 1952 } 1953 1954 return true 1955 } 1956 1957 func DetermineExcludeCnFromCsrSans(csr x509.CertificateRequest) bool { 1958 cn := csr.Subject.CommonName 1959 if cn == "" { 1960 return false 1961 } 1962 1963 emails := csr.EmailAddresses 1964 for _, email := range emails { 1965 if email == cn { 1966 return false 1967 } 1968 } 1969 1970 dnses := csr.DNSNames 1971 for _, dns := range dnses { 1972 if dns == cn { 1973 return false 1974 } 1975 } 1976 1977 return true 1978 } 1979 1980 func FindBitLength(publicKey any) int { 1981 if publicKey == nil { 1982 return 0 1983 } 1984 switch pub := publicKey.(type) { 1985 case *rsa.PublicKey: 1986 return pub.N.BitLen() 1987 case *ecdsa.PublicKey: 1988 switch pub.Curve { 1989 case elliptic.P224(): 1990 return 224 1991 case elliptic.P256(): 1992 return 256 1993 case elliptic.P384(): 1994 return 384 1995 case elliptic.P521(): 1996 return 521 1997 default: 1998 return 0 1999 } 2000 default: 2001 return 0 2002 } 2003 } 2004 2005 func FindSignatureBits(algo x509.SignatureAlgorithm) int { 2006 switch algo { 2007 case x509.MD2WithRSA, x509.MD5WithRSA, x509.SHA1WithRSA, x509.DSAWithSHA1, x509.ECDSAWithSHA1: 2008 return -1 2009 case x509.SHA256WithRSA, x509.DSAWithSHA256, x509.ECDSAWithSHA256, x509.SHA256WithRSAPSS: 2010 return 256 2011 case x509.SHA384WithRSA, x509.ECDSAWithSHA384, x509.SHA384WithRSAPSS: 2012 return 384 2013 case x509.SHA512WithRSA, x509.SHA512WithRSAPSS, x509.ECDSAWithSHA512: 2014 return 512 2015 case x509.PureEd25519: 2016 return 0 2017 default: 2018 return -1 2019 } 2020 } 2021 2022 func GetKeyType(goKeyType string) string { 2023 switch goKeyType { 2024 case "RSA": 2025 return "rsa" 2026 case "ECDSA": 2027 return "ec" 2028 case "Ed25519": 2029 return "ed25519" 2030 default: 2031 return "" 2032 } 2033 } 2034 2035 func IsPSS(algorithm x509.SignatureAlgorithm) bool { 2036 switch algorithm { 2037 case x509.SHA384WithRSAPSS, x509.SHA512WithRSAPSS, x509.SHA256WithRSAPSS: 2038 return true 2039 default: 2040 return false 2041 } 2042 }