helpers.go 18 KB

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