...

Source file src/github.com/digitorus/pkcs7/pkcs7.go

Documentation: github.com/digitorus/pkcs7

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

View as plain text