helpers.go 17 KB

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