github.com/emmansun/gmsm@v0.29.1/pkcs7/pkcs7.go (about)

     1  // Package pkcs7 implements parsing and generation of some PKCS#7 structures.
     2  package pkcs7
     3  
     4  import (
     5  	"bytes"
     6  	"crypto"
     7  	"crypto/dsa"
     8  	"crypto/ecdsa"
     9  	"crypto/rsa"
    10  	"crypto/x509"
    11  	"crypto/x509/pkix"
    12  	"encoding/asn1"
    13  	"errors"
    14  	"fmt"
    15  	"sort"
    16  
    17  	_ "crypto/sha1" // for crypto.SHA1
    18  
    19  	"github.com/emmansun/gmsm/sm2"
    20  	"github.com/emmansun/gmsm/smx509"
    21  )
    22  
    23  // PKCS7 Represents a PKCS7 structure
    24  type PKCS7 struct {
    25  	Content      []byte
    26  	Certificates []*smx509.Certificate
    27  	CRLs         []pkix.CertificateList
    28  	Signers      []signerInfo
    29  	raw          any
    30  }
    31  
    32  type contentInfo struct {
    33  	ContentType asn1.ObjectIdentifier
    34  	Content     asn1.RawValue `asn1:"explicit,optional,tag:0"`
    35  }
    36  
    37  // ErrUnsupportedContentType is returned when a PKCS7 content is not supported.
    38  // Currently only Data (1.2.840.113549.1.7.1), Signed Data (1.2.840.113549.1.7.2),
    39  // and Enveloped Data are supported (1.2.840.113549.1.7.3)
    40  var ErrUnsupportedContentType = errors.New("pkcs7: cannot parse data: unimplemented content type")
    41  
    42  type unsignedData []byte
    43  
    44  var (
    45  	// Signed Data OIDs
    46  	OIDData                   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1}
    47  	OIDSignedData             = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2}
    48  	OIDEnvelopedData          = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 3}
    49  	OIDSignedEnvelopedData    = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 4}
    50  	OIDDigestData             = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 5}
    51  	OIDEncryptedData          = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 6}
    52  	OIDAttributeContentType   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 3}
    53  	OIDAttributeMessageDigest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 4}
    54  	OIDAttributeSigningTime   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 5}
    55  
    56  	// Digest Algorithms
    57  	OIDDigestAlgorithmSHA1   = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26}
    58  	OIDDigestAlgorithmSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
    59  	OIDDigestAlgorithmSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
    60  	OIDDigestAlgorithmSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
    61  
    62  	OIDDigestAlgorithmDSA     = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
    63  	OIDDigestAlgorithmDSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
    64  
    65  	OIDDigestAlgorithmECDSASHA1   = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
    66  	OIDDigestAlgorithmECDSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
    67  	OIDDigestAlgorithmECDSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
    68  	OIDDigestAlgorithmECDSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
    69  
    70  	// Signature Algorithms
    71  	OIDEncryptionAlgorithmRSA       = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
    72  	OIDEncryptionAlgorithmRSASHA1   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
    73  	OIDEncryptionAlgorithmRSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
    74  	OIDEncryptionAlgorithmRSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
    75  	OIDEncryptionAlgorithmRSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
    76  
    77  	OIDEncryptionAlgorithmECDSAP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
    78  	OIDEncryptionAlgorithmECDSAP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
    79  	OIDEncryptionAlgorithmECDSAP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
    80  )
    81  
    82  var (
    83  	// SM2 Signed Data OIDs
    84  	// 《GB/T 35275-2017 信息安全技术 SM2密码算法加密签名消息语法规范》
    85  	SM2OIDData                = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 1}
    86  	SM2OIDSignedData          = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 2}
    87  	SM2OIDEnvelopedData       = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 3}
    88  	SM2OIDSignedEnvelopedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 4}
    89  	SM2OIDEncryptedData       = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 5}
    90  
    91  	// Digest Algorithms
    92  	OIDDigestAlgorithmSM3 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 401}
    93  	// SM2Sign-with-SM3
    94  	OIDDigestAlgorithmSM2SM3 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 501}
    95  	// Signature Algorithms SM2-1
    96  	OIDDigestEncryptionAlgorithmSM2 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301, 1}
    97  
    98  	// Encryption Algorithms SM2-3
    99  	OIDKeyEncryptionAlgorithmSM2 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301, 3}
   100  
   101  	//SM9 Signed Data OIDs
   102  	SM9OIDData                = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 1}
   103  	SM9OIDSignedData          = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 2}
   104  	SM9OIDEnvelopedData       = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 3}
   105  	SM9OIDSignedEnvelopedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 4}
   106  	SM9OIDEncryptedData       = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 5}
   107  
   108  	// SM9Sign-with-SM3
   109  	OIDDigestAlgorithmSM9SM3 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 502}
   110  
   111  	// Signature Algorithms SM9-1
   112  	OIDDigestEncryptionAlgorithmSM9 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 302, 1}
   113  
   114  	// Encryption Algorithms SM9-3
   115  	OIDKeyEncryptionAlgorithmSM9 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 302, 3}
   116  )
   117  
   118  func getHashForOID(oid asn1.ObjectIdentifier) (crypto.Hash, error) {
   119  	switch {
   120  	case oid.Equal(OIDDigestAlgorithmSHA1), oid.Equal(OIDDigestAlgorithmECDSASHA1),
   121  		oid.Equal(OIDDigestAlgorithmDSA), oid.Equal(OIDDigestAlgorithmDSASHA1),
   122  		oid.Equal(OIDEncryptionAlgorithmRSA):
   123  		return crypto.SHA1, nil
   124  	case oid.Equal(OIDDigestAlgorithmSHA256), oid.Equal(OIDDigestAlgorithmECDSASHA256):
   125  		return crypto.SHA256, nil
   126  	case oid.Equal(OIDDigestAlgorithmSHA384), oid.Equal(OIDDigestAlgorithmECDSASHA384):
   127  		return crypto.SHA384, nil
   128  	case oid.Equal(OIDDigestAlgorithmSHA512), oid.Equal(OIDDigestAlgorithmECDSASHA512):
   129  		return crypto.SHA512, nil
   130  	case oid.Equal(OIDDigestAlgorithmSM3), oid.Equal(OIDDigestAlgorithmSM2SM3):
   131  		return crypto.Hash(0), nil
   132  	}
   133  	return crypto.Hash(0), fmt.Errorf("pkcs7: cannot get hash from oid %v", oid)
   134  }
   135  
   136  // getDigestOIDForSignatureAlgorithm takes an x509.SignatureAlgorithm
   137  // and returns the corresponding OID digest algorithm
   138  func getDigestOIDForSignatureAlgorithm(digestAlg x509.SignatureAlgorithm) (asn1.ObjectIdentifier, error) {
   139  	switch digestAlg {
   140  	case x509.SHA1WithRSA, x509.ECDSAWithSHA1:
   141  		return OIDDigestAlgorithmSHA1, nil
   142  	case x509.SHA256WithRSA, x509.ECDSAWithSHA256:
   143  		return OIDDigestAlgorithmSHA256, nil
   144  	case x509.SHA384WithRSA, x509.ECDSAWithSHA384:
   145  		return OIDDigestAlgorithmSHA384, nil
   146  	case x509.SHA512WithRSA, x509.ECDSAWithSHA512:
   147  		return OIDDigestAlgorithmSHA512, nil
   148  	case smx509.SM2WithSM3:
   149  		return OIDDigestAlgorithmSM3, nil
   150  	}
   151  	return nil, fmt.Errorf("pkcs7: cannot convert hash to oid, unknown hash algorithm")
   152  }
   153  
   154  // getOIDForEncryptionAlgorithm takes the public or private key type of the signer and
   155  // the OID of a digest algorithm to return the appropriate signerInfo.DigestEncryptionAlgorithm
   156  func getOIDForEncryptionAlgorithm(pkey any, OIDDigestAlg asn1.ObjectIdentifier) (asn1.ObjectIdentifier, error) {
   157  	switch k := pkey.(type) {
   158  	case *rsa.PrivateKey, *rsa.PublicKey:
   159  		switch {
   160  		default:
   161  			return OIDEncryptionAlgorithmRSA, nil
   162  		case OIDDigestAlg.Equal(OIDEncryptionAlgorithmRSA):
   163  			return OIDEncryptionAlgorithmRSA, nil
   164  		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA1):
   165  			return OIDEncryptionAlgorithmRSASHA1, nil
   166  		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA256):
   167  			return OIDEncryptionAlgorithmRSASHA256, nil
   168  		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA384):
   169  			return OIDEncryptionAlgorithmRSASHA384, nil
   170  		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA512):
   171  			return OIDEncryptionAlgorithmRSASHA512, nil
   172  		}
   173  	case *ecdsa.PrivateKey, *ecdsa.PublicKey:
   174  		switch {
   175  		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA1):
   176  			return OIDDigestAlgorithmECDSASHA1, nil
   177  		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA256):
   178  			return OIDDigestAlgorithmECDSASHA256, nil
   179  		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA384):
   180  			return OIDDigestAlgorithmECDSASHA384, nil
   181  		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA512):
   182  			return OIDDigestAlgorithmECDSASHA512, nil
   183  		case OIDDigestAlg.Equal(OIDDigestAlgorithmSM3):
   184  			// Do we need further checking?
   185  			return OIDDigestEncryptionAlgorithmSM2, nil
   186  		}
   187  	case *sm2.PrivateKey:
   188  		return OIDDigestEncryptionAlgorithmSM2, nil
   189  	case *dsa.PrivateKey, *dsa.PublicKey:
   190  		return OIDDigestAlgorithmDSA, nil
   191  	case crypto.Signer:
   192  		return getOIDForEncryptionAlgorithm(k.Public(), OIDDigestAlg)
   193  	}
   194  	return nil, fmt.Errorf("pkcs7: cannot convert encryption algorithm to oid, unknown or unsupported private key type %T", pkey)
   195  
   196  }
   197  
   198  // Parse decodes a DER encoded PKCS7 package
   199  func Parse(data []byte) (p7 *PKCS7, err error) {
   200  	if len(data) == 0 {
   201  		return nil, errors.New("pkcs7: input data is empty")
   202  	}
   203  	var info contentInfo
   204  	der, err := ber2der(data)
   205  	if err != nil {
   206  		return nil, err
   207  	}
   208  	rest, err := asn1.Unmarshal(der, &info)
   209  	if len(rest) > 0 {
   210  		err = asn1.SyntaxError{Msg: "trailing data"}
   211  		return
   212  	}
   213  	if err != nil {
   214  		return
   215  	}
   216  
   217  	switch {
   218  	case info.ContentType.Equal(OIDSignedData) || info.ContentType.Equal(SM2OIDSignedData):
   219  		return parseSignedData(info.Content.Bytes)
   220  	case info.ContentType.Equal(OIDEnvelopedData) || info.ContentType.Equal(SM2OIDEnvelopedData):
   221  		return parseEnvelopedData(info.Content.Bytes)
   222  	case info.ContentType.Equal(OIDEncryptedData) || info.ContentType.Equal(SM2OIDEncryptedData):
   223  		return parseEncryptedData(info.Content.Bytes)
   224  	case info.ContentType.Equal(OIDSignedEnvelopedData) || info.ContentType.Equal(SM2OIDSignedEnvelopedData):
   225  		return parseSignedEnvelopedData(info.Content.Bytes)
   226  	default:
   227  		return nil, ErrUnsupportedContentType
   228  	}
   229  }
   230  
   231  func parseEnvelopedData(data []byte) (*PKCS7, error) {
   232  	var ed envelopedData
   233  	if _, err := asn1.Unmarshal(data, &ed); err != nil {
   234  		return nil, err
   235  	}
   236  	return &PKCS7{
   237  		raw: ed,
   238  	}, nil
   239  }
   240  
   241  func parseEncryptedData(data []byte) (*PKCS7, error) {
   242  	var ed encryptedData
   243  	if _, err := asn1.Unmarshal(data, &ed); err != nil {
   244  		return nil, err
   245  	}
   246  	return &PKCS7{
   247  		raw: ed,
   248  	}, nil
   249  }
   250  
   251  func (raw rawCertificates) Parse() ([]*smx509.Certificate, error) {
   252  	if len(raw.Raw) == 0 {
   253  		return nil, nil
   254  	}
   255  
   256  	var val asn1.RawValue
   257  	if _, err := asn1.Unmarshal(raw.Raw, &val); err != nil {
   258  		return nil, err
   259  	}
   260  
   261  	return smx509.ParseCertificates(val.Bytes)
   262  }
   263  
   264  func isCertMatchForIssuerAndSerial(cert *smx509.Certificate, ias issuerAndSerial) bool {
   265  	return cert.SerialNumber.Cmp(ias.SerialNumber) == 0 && bytes.Equal(cert.RawIssuer, ias.IssuerName.FullBytes)
   266  }
   267  
   268  // Attribute represents a key value pair attribute. Value must be marshalable byte
   269  // `encoding/asn1`
   270  type Attribute struct {
   271  	Type  asn1.ObjectIdentifier
   272  	Value any
   273  }
   274  
   275  type attributes struct {
   276  	types  []asn1.ObjectIdentifier
   277  	values []any
   278  }
   279  
   280  // Add adds the attribute, maintaining insertion order
   281  func (attrs *attributes) Add(attrType asn1.ObjectIdentifier, value any) {
   282  	attrs.types = append(attrs.types, attrType)
   283  	attrs.values = append(attrs.values, value)
   284  }
   285  
   286  type sortableAttribute struct {
   287  	SortKey   []byte
   288  	Attribute attribute
   289  }
   290  
   291  type attributeSet []sortableAttribute
   292  
   293  func (sa attributeSet) Len() int {
   294  	return len(sa)
   295  }
   296  
   297  func (sa attributeSet) Less(i, j int) bool {
   298  	return bytes.Compare(sa[i].SortKey, sa[j].SortKey) < 0
   299  }
   300  
   301  func (sa attributeSet) Swap(i, j int) {
   302  	sa[i], sa[j] = sa[j], sa[i]
   303  }
   304  
   305  func (sa attributeSet) Attributes() []attribute {
   306  	attrs := make([]attribute, len(sa))
   307  	for i, attr := range sa {
   308  		attrs[i] = attr.Attribute
   309  	}
   310  	return attrs
   311  }
   312  
   313  func (attrs *attributes) ForMarshalling() ([]attribute, error) {
   314  	sortables := make(attributeSet, len(attrs.types))
   315  	for i := range sortables {
   316  		attrType := attrs.types[i]
   317  		attrValue := attrs.values[i]
   318  		asn1Value, err := asn1.Marshal(attrValue)
   319  		if err != nil {
   320  			return nil, err
   321  		}
   322  		attr := attribute{
   323  			Type:  attrType,
   324  			Value: asn1.RawValue{Tag: 17, IsCompound: true, Bytes: asn1Value}, // 17 == SET tag
   325  		}
   326  		encoded, err := asn1.Marshal(attr)
   327  		if err != nil {
   328  			return nil, err
   329  		}
   330  		sortables[i] = sortableAttribute{
   331  			SortKey:   encoded,
   332  			Attribute: attr,
   333  		}
   334  	}
   335  	sort.Sort(sortables)
   336  	return sortables.Attributes(), nil
   337  }