helpers.go 19 KB

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