github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/cloudflare/cfssl/helpers/helpers.go (about) 1 // Package helpers implements utility functionality common to many 2 // CFSSL packages. 3 package helpers 4 5 import ( 6 "bytes" 7 "crypto" 8 "crypto/elliptic" 9 "crypto/rsa" 10 "encoding/asn1" 11 "encoding/binary" 12 "encoding/pem" 13 "errors" 14 "fmt" 15 ct "github.com/google/certificate-transparency-go" 16 "github.com/hellobchain/newcryptosm/ecdsa" 17 "github.com/hellobchain/newcryptosm/sm2" 18 "github.com/hellobchain/newcryptosm/tls" 19 "github.com/hellobchain/newcryptosm/x509" 20 "github.com/hellobchain/newcryptosm/x509/pkix" 21 "io" 22 "io/ioutil" 23 "os" 24 25 cttls "github.com/google/certificate-transparency-go/tls" 26 "github.com/hellobchain/third_party/ocsp" 27 28 "strings" 29 "time" 30 31 "github.com/hellobchain/third_party/cloudflare/cfssl/crypto/pkcs7" 32 cferr "github.com/hellobchain/third_party/cloudflare/cfssl/errors" 33 "github.com/hellobchain/third_party/cloudflare/cfssl/helpers/derhelpers" 34 "github.com/hellobchain/third_party/cloudflare/cfssl/log" 35 ) 36 37 // OneYear is a time.Duration representing a year's worth of seconds. 38 const OneYear = 8760 * time.Hour 39 40 // OneDay is a time.Duration representing a day's worth of seconds. 41 const OneDay = 24 * time.Hour 42 43 // InclusiveDate returns the time.Time representation of a date - 1 44 // nanosecond. This allows time.After to be used inclusively. 45 func InclusiveDate(year int, month time.Month, day int) time.Time { 46 return time.Date(year, month, day, 0, 0, 0, 0, time.UTC).Add(-1 * time.Nanosecond) 47 } 48 49 // Jul2012 is the July 2012 CAB Forum deadline for when CAs must stop 50 // issuing certificates valid for more than 5 years. 51 var Jul2012 = InclusiveDate(2012, time.July, 01) 52 53 // Apr2015 is the April 2015 CAB Forum deadline for when CAs must stop 54 // issuing certificates valid for more than 39 months. 55 var Apr2015 = InclusiveDate(2015, time.April, 01) 56 57 // KeyLength returns the bit size of ECDSA or RSA PublicKey 58 func KeyLength(key interface{}) int { 59 if key == nil { 60 return 0 61 } 62 if ecdsaKey, ok := key.(*ecdsa.PublicKey); ok { 63 return ecdsaKey.Curve.Params().BitSize 64 } else if rsaKey, ok := key.(*rsa.PublicKey); ok { 65 return rsaKey.N.BitLen() 66 } 67 68 return 0 69 } 70 71 // ExpiryTime returns the time when the certificate chain is expired. 72 func ExpiryTime(chain []*x509.Certificate) (notAfter time.Time) { 73 if len(chain) == 0 { 74 return 75 } 76 77 notAfter = chain[0].NotAfter 78 for _, cert := range chain { 79 if notAfter.After(cert.NotAfter) { 80 notAfter = cert.NotAfter 81 } 82 } 83 return 84 } 85 86 // MonthsValid returns the number of months for which a certificate is valid. 87 func MonthsValid(c *x509.Certificate) int { 88 issued := c.NotBefore 89 expiry := c.NotAfter 90 years := expiry.Year() - issued.Year() 91 months := years*12 + int(expiry.Month()) - int(issued.Month()) 92 93 // Round up if valid for less than a full month 94 if expiry.Day() > issued.Day() { 95 months++ 96 } 97 return months 98 } 99 100 // ValidExpiry determines if a certificate is valid for an acceptable 101 // length of time per the CA/Browser Forum baseline requirements. 102 // See https://cabforum.org/wp-content/uploads/CAB-Forum-BR-1.3.0.pdf 103 func ValidExpiry(c *x509.Certificate) bool { 104 issued := c.NotBefore 105 106 var maxMonths int 107 switch { 108 case issued.After(Apr2015): 109 maxMonths = 39 110 case issued.After(Jul2012): 111 maxMonths = 60 112 case issued.Before(Jul2012): 113 maxMonths = 120 114 } 115 116 if MonthsValid(c) > maxMonths { 117 return false 118 } 119 return true 120 } 121 122 // SignatureString returns the TLS signature string corresponding to 123 // an X509 signature algorithm. 124 func SignatureString(alg x509.SignatureAlgorithm) string { 125 switch alg { 126 case x509.MD2WithRSA: 127 return "MD2WithRSA" 128 case x509.MD5WithRSA: 129 return "MD5WithRSA" 130 case x509.SHA1WithRSA: 131 return "SHA1WithRSA" 132 case x509.SHA256WithRSA: 133 return "SHA256WithRSA" 134 case x509.SHA384WithRSA: 135 return "SHA384WithRSA" 136 case x509.SHA512WithRSA: 137 return "SHA512WithRSA" 138 case x509.DSAWithSHA1: 139 return "DSAWithSHA1" 140 case x509.DSAWithSHA256: 141 return "DSAWithSHA256" 142 case x509.ECDSAWithSHA1: 143 return "ECDSAWithSHA1" 144 case x509.ECDSAWithSHA256: 145 return "ECDSAWithSHA256" 146 case x509.ECDSAWithSHA384: 147 return "ECDSAWithSHA384" 148 case x509.ECDSAWithSHA512: 149 return "ECDSAWithSHA512" 150 case x509.SM2WithSM3: 151 return "SM2WithSM3" 152 case x509.SM2WithSHA1: 153 return "SM2WithSHA1" 154 case x509.SM2WithSHA256: 155 return "SM2WithSHA256" 156 default: 157 return "Unknown Signature" 158 } 159 } 160 161 // HashAlgoString returns the hash algorithm name contains in the signature 162 // method. 163 func HashAlgoString(alg x509.SignatureAlgorithm) string { 164 switch alg { 165 case x509.MD2WithRSA: 166 return "MD2" 167 case x509.MD5WithRSA: 168 return "MD5" 169 case x509.SHA1WithRSA: 170 return "SHA1" 171 case x509.SHA256WithRSA: 172 return "SHA256" 173 case x509.SHA384WithRSA: 174 return "SHA384" 175 case x509.SHA512WithRSA: 176 return "SHA512" 177 case x509.DSAWithSHA1: 178 return "SHA1" 179 case x509.DSAWithSHA256: 180 return "SHA256" 181 case x509.ECDSAWithSHA1: 182 return "SHA1" 183 case x509.ECDSAWithSHA256: 184 return "SHA256" 185 case x509.ECDSAWithSHA384: 186 return "SHA384" 187 case x509.ECDSAWithSHA512: 188 return "SHA512" 189 case x509.SM2WithSHA256: 190 return "SHA256" 191 case x509.SM2WithSHA1: 192 return "SHA1" 193 case x509.SM2WithSM3: 194 return "SM3" 195 default: 196 return "Unknown Hash Algorithm" 197 } 198 } 199 200 // EncodeCertificatesPEM encodes a number of x509 certficates to PEM 201 func EncodeCertificatesPEM(certs []*x509.Certificate) []byte { 202 var buffer bytes.Buffer 203 for _, cert := range certs { 204 pem.Encode(&buffer, &pem.Block{ 205 Type: "CERTIFICATE", 206 Bytes: cert.Raw, 207 }) 208 } 209 210 return buffer.Bytes() 211 } 212 213 // EncodeCertificatePEM encodes a single x509 certficates to PEM 214 func EncodeCertificatePEM(cert *x509.Certificate) []byte { 215 return EncodeCertificatesPEM([]*x509.Certificate{cert}) 216 } 217 218 // ParseCertificatesPEM parses a sequence of PEM-encoded certificate and returns them, 219 // can handle PEM encoded PKCS #7 structures. 220 func ParseCertificatesPEM(certsPEM []byte) ([]*x509.Certificate, error) { 221 var certs []*x509.Certificate 222 var err error 223 certsPEM = bytes.TrimSpace(certsPEM) 224 for len(certsPEM) > 0 { 225 var cert []*x509.Certificate 226 cert, certsPEM, err = ParseOneCertificateFromPEM(certsPEM) 227 if err != nil { 228 229 return nil, cferr.New(cferr.CertificateError, cferr.ParseFailed) 230 } else if cert == nil { 231 break 232 } 233 234 certs = append(certs, cert...) 235 } 236 if len(certsPEM) > 0 { 237 return nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) 238 } 239 return certs, nil 240 } 241 242 // ParseCertificatesDER parses a DER encoding of a certificate object and possibly private key, 243 // either PKCS #7, PKCS #12, or raw x509. 244 //func ParseCertificatesDER(certsDER []byte, password string) (certs []*x509.Certificate, key crypto.Signer, err error) { 245 // certsDER = bytes.TrimSpace(certsDER) 246 // pkcs7data, err := pkcs7.ParsePKCS7(certsDER) 247 // if err != nil { 248 // var pkcs12data interface{} 249 // certs = make([]*x509.Certificate, 1) 250 // pkcs12data, certs[0], err = pkcs12.Decode(certsDER, password) 251 // if err != nil { 252 // certs, err = x509.ParseCertificates(certsDER) 253 // if err != nil { 254 // return nil, nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) 255 // } 256 // } else { 257 // key = pkcs12data.(crypto.Signer) 258 // } 259 // } else { 260 // if pkcs7data.ContentInfo != "SignedData" { 261 // return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.DecodeFailed, errors.New("can only extract certificates from signed data content info")) 262 // } 263 // certs = pkcs7data.Content.SignedData.Certificates 264 // } 265 // if certs == nil { 266 // return nil, key, cferr.New(cferr.CertificateError, cferr.DecodeFailed) 267 // } 268 // return certs, key, nil 269 //} 270 271 // ParseSelfSignedCertificatePEM parses a PEM-encoded certificate and check if it is self-signed. 272 func ParseSelfSignedCertificatePEM(certPEM []byte) (*x509.Certificate, error) { 273 cert, err := ParseCertificatePEM(certPEM) 274 if err != nil { 275 return nil, err 276 } 277 278 if err := cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature); err != nil { 279 return nil, cferr.Wrap(cferr.CertificateError, cferr.VerifyFailed, err) 280 } 281 return cert, nil 282 } 283 284 // ParseCertificatePEM parses and returns a PEM-encoded certificate, 285 // can handle PEM encoded PKCS #7 structures. 286 func ParseCertificatePEM(certPEM []byte) (*x509.Certificate, error) { 287 certPEM = bytes.TrimSpace(certPEM) 288 cert, rest, err := ParseOneCertificateFromPEM(certPEM) 289 if err != nil { 290 // Log the actual parsing error but throw a default parse error message. 291 log.Debugf("Certificate parsing error: %v", err) 292 return nil, cferr.New(cferr.CertificateError, cferr.ParseFailed) 293 } else if cert == nil { 294 return nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) 295 } else if len(rest) > 0 { 296 return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("the PEM file should contain only one object")) 297 } else if len(cert) > 1 { 298 return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("the PKCS7 object in the PEM file should contain only one certificate")) 299 } 300 return cert[0], nil 301 } 302 303 // ParseOneCertificateFromPEM attempts to parse one PEM encoded certificate object, 304 // either a raw x509 certificate or a PKCS #7 structure possibly containing 305 // multiple certificates, from the top of certsPEM, which itself may 306 // contain multiple PEM encoded certificate objects. 307 func ParseOneCertificateFromPEM(certsPEM []byte) ([]*x509.Certificate, []byte, error) { 308 309 block, rest := pem.Decode(certsPEM) 310 if block == nil { 311 return nil, rest, nil 312 } 313 314 cert, err := x509.ParseCertificate(block.Bytes) 315 if err != nil { 316 pkcs7data, err := pkcs7.ParsePKCS7(block.Bytes) 317 if err != nil { 318 return nil, rest, err 319 } 320 if pkcs7data.ContentInfo != "SignedData" { 321 return nil, rest, errors.New("only PKCS #7 Signed Data Content Info supported for certificate parsing") 322 } 323 certs := pkcs7data.Content.SignedData.Certificates 324 if certs == nil { 325 return nil, rest, errors.New("PKCS #7 structure contains no certificates") 326 } 327 return certs, rest, nil 328 } 329 var certs = []*x509.Certificate{cert} 330 return certs, rest, nil 331 } 332 333 // LoadPEMCertPool loads a pool of PEM certificates from file. 334 func LoadPEMCertPool(certsFile string) (*x509.CertPool, error) { 335 if certsFile == "" { 336 return nil, nil 337 } 338 pemCerts, err := ioutil.ReadFile(certsFile) 339 if err != nil { 340 return nil, err 341 } 342 343 return PEMToCertPool(pemCerts) 344 } 345 346 // PEMToCertPool concerts PEM certificates to a CertPool. 347 func PEMToCertPool(pemCerts []byte) (*x509.CertPool, error) { 348 if len(pemCerts) == 0 { 349 return nil, nil 350 } 351 352 certPool := x509.NewCertPool() 353 if !certPool.AppendCertsFromPEM(pemCerts) { 354 return nil, errors.New("failed to load cert pool") 355 } 356 357 return certPool, nil 358 } 359 360 // ParsePrivateKeyPEM parses and returns a PEM-encoded private 361 // key. The private key may be either an unencrypted PKCS#8, PKCS#1, 362 // or elliptic private key. 363 func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.Signer, err error) { 364 return ParsePrivateKeyPEMWithPassword(keyPEM, nil) 365 } 366 367 // ParsePrivateKeyPEMWithPassword parses and returns a PEM-encoded private 368 // key. The private key may be a potentially encrypted PKCS#8, PKCS#1, 369 // or elliptic private key. 370 func ParsePrivateKeyPEMWithPassword(keyPEM []byte, password []byte) (key crypto.Signer, err error) { 371 keyDER, err := GetKeyDERFromPEM(keyPEM, password) 372 if err != nil { 373 return nil, err 374 } 375 376 return derhelpers.ParsePrivateKeyDER(keyDER) 377 } 378 379 // GetKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes. 380 func GetKeyDERFromPEM(in []byte, password []byte) ([]byte, error) { 381 keyDER, _ := pem.Decode(in) 382 if keyDER != nil { 383 if procType, ok := keyDER.Headers["Proc-Type"]; ok { 384 if strings.Contains(procType, "ENCRYPTED") { 385 if password != nil { 386 return x509.DecryptPEMBlock(keyDER, password) 387 } 388 return nil, cferr.New(cferr.PrivateKeyError, cferr.Encrypted) 389 } 390 } 391 return keyDER.Bytes, nil 392 } 393 394 return nil, cferr.New(cferr.PrivateKeyError, cferr.DecodeFailed) 395 } 396 397 // ParseCSR parses a PEM- or DER-encoded PKCS #10 certificate signing request. 398 func ParseCSR(in []byte) (csr *x509.CertificateRequest, rest []byte, err error) { 399 in = bytes.TrimSpace(in) 400 p, rest := pem.Decode(in) 401 if p != nil { 402 if p.Type != "NEW CERTIFICATE REQUEST" && p.Type != "CERTIFICATE REQUEST" { 403 return nil, rest, cferr.New(cferr.CSRError, cferr.BadRequest) 404 } 405 406 csr, err = x509.ParseCertificateRequest(p.Bytes) 407 } else { 408 csr, err = x509.ParseCertificateRequest(in) 409 } 410 411 if err != nil { 412 return nil, rest, err 413 } 414 415 err = csr.CheckSignature() 416 if err != nil { 417 return nil, rest, err 418 } 419 420 return csr, rest, nil 421 } 422 423 // ParseCSRPEM parses a PEM-encoded certificiate signing request. 424 // It does not check the signature. This is useful for dumping data from a CSR 425 // locally. 426 func ParseCSRPEM(csrPEM []byte) (*x509.CertificateRequest, error) { 427 block, _ := pem.Decode([]byte(csrPEM)) 428 if block == nil { 429 return nil, cferr.New(cferr.CSRError, cferr.DecodeFailed) 430 } 431 csrObject, err := x509.ParseCertificateRequest(block.Bytes) 432 433 if err != nil { 434 return nil, err 435 } 436 437 return csrObject, nil 438 } 439 440 // SignerAlgo returns an X.509 signature algorithm from a crypto.Signer. 441 func SignerAlgo(priv crypto.Signer) x509.SignatureAlgorithm { 442 switch pub := priv.Public().(type) { 443 case *rsa.PublicKey: 444 bitLength := pub.N.BitLen() 445 switch { 446 case bitLength >= 4096: 447 return x509.SHA512WithRSA 448 case bitLength >= 3072: 449 return x509.SHA384WithRSA 450 case bitLength >= 2048: 451 return x509.SHA256WithRSA 452 default: 453 return x509.SHA1WithRSA 454 } 455 case *ecdsa.PublicKey: 456 switch pub.Curve { 457 case elliptic.P521(): 458 return x509.ECDSAWithSHA512 459 case elliptic.P384(): 460 return x509.ECDSAWithSHA384 461 case elliptic.P256(): 462 return x509.ECDSAWithSHA256 463 case sm2.SM2(): 464 return x509.SM2WithSM3 465 default: 466 return x509.ECDSAWithSHA1 467 } 468 default: 469 return x509.UnknownSignatureAlgorithm 470 } 471 } 472 473 // LoadClientCertificate load key/certificate from pem files 474 func LoadClientCertificate(certFile string, keyFile string) (*tls.Certificate, error) { 475 if certFile != "" && keyFile != "" { 476 cert, err := tls.LoadX509KeyPair(certFile, keyFile) 477 if err != nil { 478 log.Critical("Unable to read client certificate from file: %s or key from file: %s", certFile, keyFile) 479 return nil, err 480 } 481 log.Debug("Client certificate loaded ") 482 return &cert, nil 483 } 484 return nil, nil 485 } 486 487 // CreateTLSConfig creates a tls.Config object from certs and roots 488 func CreateTLSConfig(remoteCAs *x509.CertPool, cert *tls.Certificate) *tls.Config { 489 var certs []tls.Certificate 490 if cert != nil { 491 certs = []tls.Certificate{*cert} 492 } 493 return &tls.Config{ 494 Certificates: certs, 495 RootCAs: remoteCAs, 496 } 497 } 498 499 // SerializeSCTList serializes a list of SCTs. 500 func SerializeSCTList(sctList []ct.SignedCertificateTimestamp) ([]byte, error) { 501 var buf bytes.Buffer 502 for _, sct := range sctList { 503 sct, err := cttls.Marshal(sct) 504 if err != nil { 505 return nil, err 506 } 507 binary.Write(&buf, binary.BigEndian, uint16(len(sct))) 508 buf.Write(sct) 509 } 510 511 var sctListLengthField = make([]byte, 2) 512 binary.BigEndian.PutUint16(sctListLengthField, uint16(buf.Len())) 513 return bytes.Join([][]byte{sctListLengthField, buf.Bytes()}, nil), nil 514 } 515 516 // DeserializeSCTList deserializes a list of SCTs. 517 func DeserializeSCTList(serializedSCTList []byte) (*[]ct.SignedCertificateTimestamp, error) { 518 sctList := new([]ct.SignedCertificateTimestamp) 519 sctReader := bytes.NewBuffer(serializedSCTList) 520 521 var sctListLen uint16 522 err := binary.Read(sctReader, binary.BigEndian, &sctListLen) 523 if err != nil { 524 if err == io.EOF { 525 return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, 526 errors.New("serialized SCT list could not be read")) 527 } 528 return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err) 529 } 530 if sctReader.Len() != int(sctListLen) { 531 return sctList, errors.New("SCT length field and SCT length don't match") 532 } 533 534 for err != io.EOF { 535 var sctLen uint16 536 err = binary.Read(sctReader, binary.BigEndian, &sctLen) 537 if err != nil { 538 if err == io.EOF { 539 return sctList, nil 540 } 541 return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err) 542 } 543 544 if sctReader.Len() < int(sctLen) { 545 return sctList, errors.New("SCT length field and SCT length don't match") 546 } 547 548 serializedSCT := sctReader.Next(int(sctLen)) 549 var sct ct.SignedCertificateTimestamp 550 if _, err := cttls.Unmarshal(serializedSCT, &sct); err != nil { 551 return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err) 552 } 553 554 temp := append(*sctList, sct) 555 sctList = &temp 556 } 557 558 return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err) 559 } 560 561 // SCTListFromOCSPResponse extracts the SCTList from an ocsp.Response, 562 // returning an empty list if the SCT extension was not found or could not be 563 // unmarshalled. 564 func SCTListFromOCSPResponse(response *ocsp.Response) ([]ct.SignedCertificateTimestamp, error) { 565 // This loop finds the SCTListExtension in the OCSP response. 566 var SCTListExtension, ext pkix.Extension 567 for _, ext = range response.Extensions { 568 // sctExtOid is the ObjectIdentifier of a Signed Certificate Timestamp. 569 sctExtOid := asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 5} 570 if ext.Id.Equal(sctExtOid) { 571 SCTListExtension = ext 572 break 573 } 574 } 575 576 // This code block extracts the sctList from the SCT extension. 577 var emptySCTList []ct.SignedCertificateTimestamp 578 sctList := &emptySCTList 579 var err error 580 if numBytes := len(SCTListExtension.Value); numBytes != 0 { 581 serializedSCTList := new([]byte) 582 rest := make([]byte, numBytes) 583 copy(rest, SCTListExtension.Value) 584 for len(rest) != 0 { 585 rest, err = asn1.Unmarshal(rest, serializedSCTList) 586 if err != nil { 587 return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) 588 } 589 } 590 sctList, err = DeserializeSCTList(*serializedSCTList) 591 } 592 return *sctList, err 593 } 594 595 // ReadBytes reads a []byte either from a file or an environment variable. 596 // If valFile has a prefix of 'env:', the []byte is read from the environment 597 // using the subsequent name. If the prefix is 'file:' the []byte is read from 598 // the subsequent file. If no prefix is provided, valFile is assumed to be a 599 // file path. 600 func ReadBytes(valFile string) ([]byte, error) { 601 switch splitVal := strings.SplitN(valFile, ":", 2); len(splitVal) { 602 case 1: 603 return ioutil.ReadFile(valFile) 604 case 2: 605 switch splitVal[0] { 606 case "env": 607 return []byte(os.Getenv(splitVal[1])), nil 608 case "file": 609 return ioutil.ReadFile(splitVal[1]) 610 default: 611 return nil, fmt.Errorf("unknown prefix: %s", splitVal[0]) 612 } 613 default: 614 return nil, fmt.Errorf("multiple prefixes: %s", 615 strings.Join(splitVal[:len(splitVal)-1], ", ")) 616 } 617 }