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  }