1 package x509
2
3 import (
4 "bytes"
5 "crypto"
6 "crypto/aes"
7 "crypto/cipher"
8 "crypto/des"
9 "crypto/hmac"
10 "crypto/rand"
11 "crypto/rsa"
12 _ "crypto/sha1"
13 "crypto/x509/pkix"
14 "encoding/asn1"
15 "errors"
16 "fmt"
17 "math/big"
18 "sort"
19 "time"
20 )
21
22
23 type PKCS7 struct {
24 Content []byte
25 Certificates []*Certificate
26 CRLs []pkix.CertificateList
27 Signers []signerInfo
28 raw interface{}
29 }
30
31 type contentInfo struct {
32 ContentType asn1.ObjectIdentifier
33 Content asn1.RawValue `asn1:"explicit,optional,tag:0"`
34 }
35
36
37
38
39 var ErrUnsupportedContentType = errors.New("pkcs7: cannot parse data: unimplemented content type")
40
41 type unsignedData []byte
42
43 var (
44 oidData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1}
45 oidSignedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2}
46 oidSMSignedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 2}
47 oidEnvelopedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 3}
48 oidSignedAndEnvelopedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 4}
49 oidDigestedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 5}
50 oidEncryptedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 6}
51 oidAttributeContentType = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 3}
52 oidAttributeMessageDigest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 4}
53 oidAttributeSigningTime = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 5}
54 oidSM3withSM2 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 501}
55 oidDSASM2 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301, 1}
56 )
57
58 type signedData struct {
59 Version int `asn1:"default:1"`
60 DigestAlgorithmIdentifiers []pkix.AlgorithmIdentifier `asn1:"set"`
61 ContentInfo contentInfo
62 Certificates rawCertificates `asn1:"optional,tag:0"`
63 CRLs []pkix.CertificateList `asn1:"optional,tag:1"`
64 SignerInfos []signerInfo `asn1:"set"`
65 }
66
67 type rawCertificates struct {
68 Raw asn1.RawContent
69 }
70
71 type envelopedData struct {
72 Version int
73 RecipientInfos []recipientInfo `asn1:"set"`
74 EncryptedContentInfo encryptedContentInfo
75 }
76
77 type recipientInfo struct {
78 Version int
79 IssuerAndSerialNumber issuerAndSerial
80 KeyEncryptionAlgorithm pkix.AlgorithmIdentifier
81 EncryptedKey []byte
82 }
83
84 type encryptedContentInfo struct {
85 ContentType asn1.ObjectIdentifier
86 ContentEncryptionAlgorithm pkix.AlgorithmIdentifier
87 EncryptedContent asn1.RawValue `asn1:"tag:0,optional"`
88 }
89
90 type attribute struct {
91 Type asn1.ObjectIdentifier
92 Value asn1.RawValue `asn1:"set"`
93 }
94
95 type issuerAndSerial struct {
96 IssuerName asn1.RawValue
97 SerialNumber *big.Int
98 }
99
100
101
102 type MessageDigestMismatchError struct {
103 ExpectedDigest []byte
104 ActualDigest []byte
105 }
106
107 func (err *MessageDigestMismatchError) Error() string {
108 return fmt.Sprintf("pkcs7: Message digest mismatch\n\tExpected: %X\n\tActual : %X", err.ExpectedDigest, err.ActualDigest)
109 }
110
111 type signerInfo struct {
112 Version int `asn1:"default:1"`
113 IssuerAndSerialNumber issuerAndSerial
114 DigestAlgorithm pkix.AlgorithmIdentifier
115 AuthenticatedAttributes []attribute `asn1:"optional,tag:0"`
116 DigestEncryptionAlgorithm pkix.AlgorithmIdentifier
117 EncryptedDigest []byte
118 UnauthenticatedAttributes []attribute `asn1:"optional,tag:1"`
119 }
120
121
122 func ParsePKCS7(data []byte) (p7 *PKCS7, err error) {
123 if len(data) == 0 {
124 return nil, errors.New("pkcs7: input data is empty")
125 }
126 var info contentInfo
127 der, err := ber2der(data)
128 if err != nil {
129 return nil, err
130 }
131 rest, err := asn1.Unmarshal(der, &info)
132 if len(rest) > 0 {
133 err = asn1.SyntaxError{Msg: "trailing data"}
134 return
135 }
136
137 if err != nil {
138 return
139 }
140
141
142 switch {
143 case info.ContentType.Equal(oidSignedData):
144 return parseSignedData(info.Content.Bytes)
145 case info.ContentType.Equal(oidSMSignedData):
146 return parseSignedData(info.Content.Bytes)
147 case info.ContentType.Equal(oidEnvelopedData):
148 return parseEnvelopedData(info.Content.Bytes)
149 }
150 return nil, ErrUnsupportedContentType
151 }
152
153 func parseSignedData(data []byte) (*PKCS7, error) {
154 var sd signedData
155 asn1.Unmarshal(data, &sd)
156 certs, err := sd.Certificates.Parse()
157 if err != nil {
158 return nil, err
159 }
160
161
162 var compound asn1.RawValue
163 var content unsignedData
164
165
166 if len(sd.ContentInfo.Content.Bytes) > 0 {
167 if _, err := asn1.Unmarshal(sd.ContentInfo.Content.Bytes, &compound); err != nil {
168 return nil, err
169 }
170 }
171
172 if compound.IsCompound {
173 if _, err = asn1.Unmarshal(compound.Bytes, &content); err != nil {
174 return nil, err
175 }
176 } else {
177
178 content = compound.Bytes
179 }
180 return &PKCS7{
181 Content: content,
182 Certificates: certs,
183 CRLs: sd.CRLs,
184 Signers: sd.SignerInfos,
185 raw: sd}, nil
186 }
187
188 func (raw rawCertificates) Parse() ([]*Certificate, error) {
189 if len(raw.Raw) == 0 {
190 return nil, nil
191 }
192
193 var val asn1.RawValue
194 if _, err := asn1.Unmarshal(raw.Raw, &val); err != nil {
195 return nil, err
196 }
197
198 return ParseCertificates(val.Bytes)
199 }
200
201 func parseEnvelopedData(data []byte) (*PKCS7, error) {
202 var ed envelopedData
203 if _, err := asn1.Unmarshal(data, &ed); err != nil {
204 return nil, err
205 }
206 return &PKCS7{
207 raw: ed,
208 }, nil
209 }
210
211
212
213
214 func (p7 *PKCS7) Verify() (err error) {
215 if len(p7.Signers) == 0 {
216 return errors.New("pkcs7: Message has no signers")
217 }
218 for _, signer := range p7.Signers {
219 if err := verifySignature(p7, signer); err != nil {
220 return err
221 }
222 }
223 return nil
224 }
225
226 func verifySignature(p7 *PKCS7, signer signerInfo) error {
227 signedData := p7.Content
228 hash, err := getHashForOID(signer.DigestAlgorithm.Algorithm)
229 if err != nil {
230 return err
231 }
232
233 if len(signer.AuthenticatedAttributes) > 0 {
234 var digest []byte
235 err := unmarshalAttribute(signer.AuthenticatedAttributes, oidAttributeMessageDigest, &digest)
236 if err != nil {
237 return err
238 }
239 h := hash.New()
240 h.Write(p7.Content)
241 computed := h.Sum(nil)
242 if !hmac.Equal(digest, computed) {
243 return &MessageDigestMismatchError{
244 ExpectedDigest: digest,
245 ActualDigest: computed,
246 }
247 }
248
249
250 signedData, err = marshalAttributes(signer.AuthenticatedAttributes)
251 if err != nil {
252 return err
253 }
254 }
255 cert := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
256 if cert == nil {
257 return errors.New("pkcs7: No certificate for signer")
258 }
259
260 algo := getSignatureAlgorithmByHash(hash, signer.DigestEncryptionAlgorithm.Algorithm)
261 if algo == UnknownSignatureAlgorithm {
262 return ErrPKCS7UnsupportedAlgorithm
263 }
264 return cert.CheckSignature(algo, signedData, signer.EncryptedDigest)
265 }
266
267 func getSignatureAlgorithmByHash(hash Hash, oid asn1.ObjectIdentifier) SignatureAlgorithm {
268 switch hash {
269 case SM3:
270 switch {
271 case oid.Equal(oidSM3withSM2):
272 return SM2WithSM3
273 }
274 case SHA256:
275 switch {
276 case oid.Equal(oidDSASM2):
277 return SM2WithSHA256
278 }
279 }
280 return UnknownSignatureAlgorithm
281 }
282
283 func marshalAttributes(attrs []attribute) ([]byte, error) {
284 encodedAttributes, err := asn1.Marshal(struct {
285 A []attribute `asn1:"set"`
286 }{A: attrs})
287 if err != nil {
288 return nil, err
289 }
290
291
292 var raw asn1.RawValue
293 _, err = asn1.Unmarshal(encodedAttributes, &raw)
294 if err != nil {
295 return nil, err
296 }
297 return raw.Bytes, nil
298 }
299
300 var (
301 oidDigestAlgorithmSHA1 = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26}
302 oidEncryptionAlgorithmRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
303 )
304
305 func getCertFromCertsByIssuerAndSerial(certs []*Certificate, ias issuerAndSerial) *Certificate {
306 for _, cert := range certs {
307 if isCertMatchForIssuerAndSerial(cert, ias) {
308 return cert
309 }
310 }
311 return nil
312 }
313
314 func getHashForOID(oid asn1.ObjectIdentifier) (Hash, error) {
315 switch {
316 case oid.Equal(oidDigestAlgorithmSHA1):
317 return SHA1, nil
318 case oid.Equal(oidSHA256):
319 return SHA256, nil
320 case oid.Equal(oidSM3):
321 case oid.Equal(oidHashSM3):
322 return SM3, nil
323 }
324 return Hash(0), ErrPKCS7UnsupportedAlgorithm
325 }
326
327
328
329 func (p7 *PKCS7) GetOnlySigner() *Certificate {
330 if len(p7.Signers) != 1 {
331 return nil
332 }
333 signer := p7.Signers[0]
334 return getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
335 }
336
337
338 var ErrPKCS7UnsupportedAlgorithm = errors.New("pkcs7: cannot decrypt data: only RSA, DES, DES-EDE3, AES-256-CBC and AES-128-GCM supported")
339
340
341 var ErrNotEncryptedContent = errors.New("pkcs7: content data is a decryptable data type")
342
343
344 func (p7 *PKCS7) Decrypt(cert *Certificate, pk crypto.PrivateKey) ([]byte, error) {
345 data, ok := p7.raw.(envelopedData)
346 if !ok {
347 return nil, ErrNotEncryptedContent
348 }
349 recipient := selectRecipientForCertificate(data.RecipientInfos, cert)
350 if recipient.EncryptedKey == nil {
351 return nil, errors.New("pkcs7: no enveloped recipient for provided certificate")
352 }
353 if priv := pk.(*rsa.PrivateKey); priv != nil {
354 var contentKey []byte
355 contentKey, err := rsa.DecryptPKCS1v15(rand.Reader, priv, recipient.EncryptedKey)
356 if err != nil {
357 return nil, err
358 }
359 return data.EncryptedContentInfo.decrypt(contentKey)
360 }
361 fmt.Printf("Unsupported Private Key: %v\n", pk)
362
363 return nil, ErrPKCS7UnsupportedAlgorithm
364 }
365
366 var oidEncryptionAlgorithmDESCBC = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 7}
367 var oidEncryptionAlgorithmDESEDE3CBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 3, 7}
368 var oidEncryptionAlgorithmAES256CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42}
369 var oidEncryptionAlgorithmAES128GCM = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 6}
370 var oidEncryptionAlgorithmAES128CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2}
371
372 func (eci encryptedContentInfo) decrypt(key []byte) ([]byte, error) {
373 alg := eci.ContentEncryptionAlgorithm.Algorithm
374 if !alg.Equal(oidEncryptionAlgorithmDESCBC) &&
375 !alg.Equal(oidEncryptionAlgorithmDESEDE3CBC) &&
376 !alg.Equal(oidEncryptionAlgorithmAES256CBC) &&
377 !alg.Equal(oidEncryptionAlgorithmAES128CBC) &&
378 !alg.Equal(oidEncryptionAlgorithmAES128GCM) {
379 fmt.Printf("Unsupported Content Encryption Algorithm: %s\n", alg)
380 return nil, ErrPKCS7UnsupportedAlgorithm
381 }
382
383
384
385 var cyphertext []byte
386 if eci.EncryptedContent.IsCompound {
387
388 var buf bytes.Buffer
389 cypherbytes := eci.EncryptedContent.Bytes
390 for {
391 var part []byte
392 cypherbytes, _ = asn1.Unmarshal(cypherbytes, &part)
393 buf.Write(part)
394 if cypherbytes == nil {
395 break
396 }
397 }
398 cyphertext = buf.Bytes()
399 } else {
400
401 cyphertext = eci.EncryptedContent.Bytes
402 }
403
404 var block cipher.Block
405 var err error
406
407 switch {
408 case alg.Equal(oidEncryptionAlgorithmDESCBC):
409 block, err = des.NewCipher(key)
410 case alg.Equal(oidEncryptionAlgorithmDESEDE3CBC):
411 block, err = des.NewTripleDESCipher(key)
412 case alg.Equal(oidEncryptionAlgorithmAES256CBC):
413 fallthrough
414 case alg.Equal(oidEncryptionAlgorithmAES128GCM), alg.Equal(oidEncryptionAlgorithmAES128CBC):
415 block, err = aes.NewCipher(key)
416 }
417
418 if err != nil {
419 return nil, err
420 }
421
422 if alg.Equal(oidEncryptionAlgorithmAES128GCM) {
423 params := aesGCMParameters{}
424 paramBytes := eci.ContentEncryptionAlgorithm.Parameters.Bytes
425
426 _, err := asn1.Unmarshal(paramBytes, ¶ms)
427 if err != nil {
428 return nil, err
429 }
430
431 gcm, err := cipher.NewGCM(block)
432 if err != nil {
433 return nil, err
434 }
435
436 if len(params.Nonce) != gcm.NonceSize() {
437 return nil, errors.New("pkcs7: encryption algorithm parameters are incorrect")
438 }
439 if params.ICVLen != gcm.Overhead() {
440 return nil, errors.New("pkcs7: encryption algorithm parameters are incorrect")
441 }
442
443 plaintext, err := gcm.Open(nil, params.Nonce, cyphertext, nil)
444 if err != nil {
445 return nil, err
446 }
447
448 return plaintext, nil
449 }
450
451 iv := eci.ContentEncryptionAlgorithm.Parameters.Bytes
452 if len(iv) != block.BlockSize() {
453 return nil, errors.New("pkcs7: encryption algorithm parameters are malformed")
454 }
455 mode := cipher.NewCBCDecrypter(block, iv)
456 plaintext := make([]byte, len(cyphertext))
457 mode.CryptBlocks(plaintext, cyphertext)
458 if plaintext, err = unpad(plaintext, mode.BlockSize()); err != nil {
459 return nil, err
460 }
461 return plaintext, nil
462 }
463
464 func selectRecipientForCertificate(recipients []recipientInfo, cert *Certificate) recipientInfo {
465 for _, recp := range recipients {
466 if isCertMatchForIssuerAndSerial(cert, recp.IssuerAndSerialNumber) {
467 return recp
468 }
469 }
470 return recipientInfo{}
471 }
472
473 func isCertMatchForIssuerAndSerial(cert *Certificate, ias issuerAndSerial) bool {
474 return cert.SerialNumber.Cmp(ias.SerialNumber) == 0 && bytes.Compare(cert.RawIssuer, ias.IssuerName.FullBytes) == 0
475 }
476
477 func pad(data []byte, blocklen int) ([]byte, error) {
478 if blocklen < 1 {
479 return nil, fmt.Errorf("invalid blocklen %d", blocklen)
480 }
481 padlen := blocklen - (len(data) % blocklen)
482 if padlen == 0 {
483 padlen = blocklen
484 }
485 pad := bytes.Repeat([]byte{byte(padlen)}, padlen)
486 return append(data, pad...), nil
487 }
488
489 func unpad(data []byte, blocklen int) ([]byte, error) {
490 if blocklen < 1 {
491 return nil, fmt.Errorf("invalid blocklen %d", blocklen)
492 }
493 if len(data)%blocklen != 0 || len(data) == 0 {
494 return nil, fmt.Errorf("invalid data len %d", len(data))
495 }
496
497
498 padlen := int(data[len(data)-1])
499
500
501 pad := data[len(data)-padlen:]
502 for _, padbyte := range pad {
503 if padbyte != byte(padlen) {
504 return nil, errors.New("invalid padding")
505 }
506 }
507
508 return data[:len(data)-padlen], nil
509 }
510
511 func unmarshalAttribute(attrs []attribute, attributeType asn1.ObjectIdentifier, out interface{}) error {
512 for _, attr := range attrs {
513 if attr.Type.Equal(attributeType) {
514 _, err := asn1.Unmarshal(attr.Value.Bytes, out)
515 return err
516 }
517 }
518 return errors.New("pkcs7: attribute type not in attributes")
519 }
520
521
522 func (p7 *PKCS7) UnmarshalSignedAttribute(attributeType asn1.ObjectIdentifier, out interface{}) error {
523 sd, ok := p7.raw.(signedData)
524 if !ok {
525 return errors.New("pkcs7: payload is not signedData content")
526 }
527 if len(sd.SignerInfos) < 1 {
528 return errors.New("pkcs7: payload has no signers")
529 }
530 attributes := sd.SignerInfos[0].AuthenticatedAttributes
531 return unmarshalAttribute(attributes, attributeType, out)
532 }
533
534
535 type SignedData struct {
536 sd signedData
537 certs []*Certificate
538 messageDigest []byte
539 }
540
541
542
543 type Attribute struct {
544 Type asn1.ObjectIdentifier
545 Value interface{}
546 }
547
548
549 type SignerInfoConfig struct {
550 ExtraSignedAttributes []Attribute
551 }
552
553
554 func NewSignedData(data []byte) (*SignedData, error) {
555 content, err := asn1.Marshal(data)
556 if err != nil {
557 return nil, err
558 }
559 ci := contentInfo{
560 ContentType: oidData,
561 Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: content, IsCompound: true},
562 }
563 digAlg := pkix.AlgorithmIdentifier{
564 Algorithm: oidDigestAlgorithmSHA1,
565 }
566 h := crypto.SHA1.New()
567 h.Write(data)
568 md := h.Sum(nil)
569 sd := signedData{
570 ContentInfo: ci,
571 Version: 1,
572 DigestAlgorithmIdentifiers: []pkix.AlgorithmIdentifier{digAlg},
573 }
574 return &SignedData{sd: sd, messageDigest: md}, nil
575 }
576
577 type attributes struct {
578 types []asn1.ObjectIdentifier
579 values []interface{}
580 }
581
582
583 func (attrs *attributes) Add(attrType asn1.ObjectIdentifier, value interface{}) {
584 attrs.types = append(attrs.types, attrType)
585 attrs.values = append(attrs.values, value)
586 }
587
588 type sortableAttribute struct {
589 SortKey []byte
590 Attribute attribute
591 }
592
593 type attributeSet []sortableAttribute
594
595 func (sa attributeSet) Len() int {
596 return len(sa)
597 }
598
599 func (sa attributeSet) Less(i, j int) bool {
600 return bytes.Compare(sa[i].SortKey, sa[j].SortKey) < 0
601 }
602
603 func (sa attributeSet) Swap(i, j int) {
604 sa[i], sa[j] = sa[j], sa[i]
605 }
606
607 func (sa attributeSet) Attributes() []attribute {
608 attrs := make([]attribute, len(sa))
609 for i, attr := range sa {
610 attrs[i] = attr.Attribute
611 }
612 return attrs
613 }
614
615 func (attrs *attributes) ForMarshaling() ([]attribute, error) {
616 sortables := make(attributeSet, len(attrs.types))
617 for i := range sortables {
618 attrType := attrs.types[i]
619 attrValue := attrs.values[i]
620 asn1Value, err := asn1.Marshal(attrValue)
621 if err != nil {
622 return nil, err
623 }
624 attr := attribute{
625 Type: attrType,
626 Value: asn1.RawValue{Tag: 17, IsCompound: true, Bytes: asn1Value},
627 }
628 encoded, err := asn1.Marshal(attr)
629 if err != nil {
630 return nil, err
631 }
632 sortables[i] = sortableAttribute{
633 SortKey: encoded,
634 Attribute: attr,
635 }
636 }
637 sort.Sort(sortables)
638 return sortables.Attributes(), nil
639 }
640
641
642 func (sd *SignedData) AddSigner(cert *Certificate, pkey crypto.PrivateKey, config SignerInfoConfig) error {
643 attrs := &attributes{}
644 attrs.Add(oidAttributeContentType, sd.sd.ContentInfo.ContentType)
645 attrs.Add(oidAttributeMessageDigest, sd.messageDigest)
646 attrs.Add(oidAttributeSigningTime, time.Now())
647 for _, attr := range config.ExtraSignedAttributes {
648 attrs.Add(attr.Type, attr.Value)
649 }
650 finalAttrs, err := attrs.ForMarshaling()
651 if err != nil {
652 return err
653 }
654 signature, err := signAttributes(finalAttrs, pkey, crypto.SHA1)
655 if err != nil {
656 return err
657 }
658
659 ias, err := cert2issuerAndSerial(cert)
660 if err != nil {
661 return err
662 }
663
664 signer := signerInfo{
665 AuthenticatedAttributes: finalAttrs,
666 DigestAlgorithm: pkix.AlgorithmIdentifier{Algorithm: oidDigestAlgorithmSHA1},
667 DigestEncryptionAlgorithm: pkix.AlgorithmIdentifier{Algorithm: oidSignatureSHA1WithRSA},
668 IssuerAndSerialNumber: ias,
669 EncryptedDigest: signature,
670 Version: 1,
671 }
672
673 sd.certs = append(sd.certs, cert)
674 sd.sd.SignerInfos = append(sd.sd.SignerInfos, signer)
675 return nil
676 }
677
678
679 func (sd *SignedData) AddCertificate(cert *Certificate) {
680 sd.certs = append(sd.certs, cert)
681 }
682
683
684
685 func (sd *SignedData) Detach() {
686 sd.sd.ContentInfo = contentInfo{ContentType: oidData}
687 }
688
689
690 func (sd *SignedData) Finish() ([]byte, error) {
691 sd.sd.Certificates = marshalCertificates(sd.certs)
692 inner, err := asn1.Marshal(sd.sd)
693 if err != nil {
694 return nil, err
695 }
696 outer := contentInfo{
697 ContentType: oidSignedData,
698 Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: inner, IsCompound: true},
699 }
700 return asn1.Marshal(outer)
701 }
702
703 func cert2issuerAndSerial(cert *Certificate) (issuerAndSerial, error) {
704 var ias issuerAndSerial
705
706
707 ias.IssuerName = asn1.RawValue{FullBytes: cert.RawIssuer}
708 ias.SerialNumber = cert.SerialNumber
709
710 return ias, nil
711 }
712
713
714 func signAttributes(attrs []attribute, pkey crypto.PrivateKey, hash crypto.Hash) ([]byte, error) {
715 attrBytes, err := marshalAttributes(attrs)
716 if err != nil {
717 return nil, err
718 }
719 h := hash.New()
720 h.Write(attrBytes)
721 hashed := h.Sum(nil)
722 switch priv := pkey.(type) {
723 case *rsa.PrivateKey:
724 return rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA1, hashed)
725 }
726 return nil, ErrPKCS7UnsupportedAlgorithm
727 }
728
729
730 func marshalCertificates(certs []*Certificate) rawCertificates {
731 var buf bytes.Buffer
732 for _, cert := range certs {
733 buf.Write(cert.Raw)
734 }
735 rawCerts, _ := marshalCertificateBytes(buf.Bytes())
736 return rawCerts
737 }
738
739
740
741
742 func marshalCertificateBytes(certs []byte) (rawCertificates, error) {
743 var val = asn1.RawValue{Bytes: certs, Class: 2, Tag: 0, IsCompound: true}
744 b, err := asn1.Marshal(val)
745 if err != nil {
746 return rawCertificates{}, err
747 }
748 return rawCertificates{Raw: b}, nil
749 }
750
751
752
753 func DegenerateCertificate(cert []byte) ([]byte, error) {
754 rawCert, err := marshalCertificateBytes(cert)
755 if err != nil {
756 return nil, err
757 }
758 emptyContent := contentInfo{ContentType: oidData}
759 sd := signedData{
760 Version: 1,
761 ContentInfo: emptyContent,
762 Certificates: rawCert,
763 CRLs: []pkix.CertificateList{},
764 }
765 content, err := asn1.Marshal(sd)
766 if err != nil {
767 return nil, err
768 }
769 signedContent := contentInfo{
770 ContentType: oidSignedData,
771 Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: content, IsCompound: true},
772 }
773 return asn1.Marshal(signedContent)
774 }
775
776 const (
777 EncryptionAlgorithmDESCBC = iota
778 EncryptionAlgorithmAES128GCM
779 )
780
781
782
783
784 var ContentEncryptionAlgorithm = EncryptionAlgorithmDESCBC
785
786
787
788 var ErrUnsupportedEncryptionAlgorithm = errors.New("pkcs7: cannot encrypt content: only DES-CBC and AES-128-GCM supported")
789
790 const nonceSize = 12
791
792 type aesGCMParameters struct {
793 Nonce []byte `asn1:"tag:4"`
794 ICVLen int
795 }
796
797 func encryptAES128GCM(content []byte) ([]byte, *encryptedContentInfo, error) {
798
799 key := make([]byte, 16)
800 nonce := make([]byte, nonceSize)
801
802 _, err := rand.Read(key)
803 if err != nil {
804 return nil, nil, err
805 }
806
807 _, err = rand.Read(nonce)
808 if err != nil {
809 return nil, nil, err
810 }
811
812
813 block, err := aes.NewCipher(key)
814 if err != nil {
815 return nil, nil, err
816 }
817
818 gcm, err := cipher.NewGCM(block)
819 if err != nil {
820 return nil, nil, err
821 }
822
823 ciphertext := gcm.Seal(nil, nonce, content, nil)
824
825
826 paramSeq := aesGCMParameters{
827 Nonce: nonce,
828 ICVLen: gcm.Overhead(),
829 }
830
831 paramBytes, err := asn1.Marshal(paramSeq)
832 if err != nil {
833 return nil, nil, err
834 }
835
836 eci := encryptedContentInfo{
837 ContentType: oidData,
838 ContentEncryptionAlgorithm: pkix.AlgorithmIdentifier{
839 Algorithm: oidEncryptionAlgorithmAES128GCM,
840 Parameters: asn1.RawValue{
841 Tag: asn1.TagSequence,
842 Bytes: paramBytes,
843 },
844 },
845 EncryptedContent: marshalEncryptedContent(ciphertext),
846 }
847
848 return key, &eci, nil
849 }
850
851 func encryptDESCBC(content []byte) ([]byte, *encryptedContentInfo, error) {
852
853 key := make([]byte, 8)
854 iv := make([]byte, des.BlockSize)
855 _, err := rand.Read(key)
856 if err != nil {
857 return nil, nil, err
858 }
859 _, err = rand.Read(iv)
860 if err != nil {
861 return nil, nil, err
862 }
863
864
865 block, err := des.NewCipher(key)
866 if err != nil {
867 return nil, nil, err
868 }
869 mode := cipher.NewCBCEncrypter(block, iv)
870 plaintext, err := pad(content, mode.BlockSize())
871 cyphertext := make([]byte, len(plaintext))
872 mode.CryptBlocks(cyphertext, plaintext)
873
874
875 eci := encryptedContentInfo{
876 ContentType: oidData,
877 ContentEncryptionAlgorithm: pkix.AlgorithmIdentifier{
878 Algorithm: oidEncryptionAlgorithmDESCBC,
879 Parameters: asn1.RawValue{Tag: 4, Bytes: iv},
880 },
881 EncryptedContent: marshalEncryptedContent(cyphertext),
882 }
883
884 return key, &eci, nil
885 }
886
887
888
889
890
891
892
893
894
895
896
897
898 func PKCS7Encrypt(content []byte, recipients []*Certificate) ([]byte, error) {
899 var eci *encryptedContentInfo
900 var key []byte
901 var err error
902
903
904 switch ContentEncryptionAlgorithm {
905 case EncryptionAlgorithmDESCBC:
906 key, eci, err = encryptDESCBC(content)
907
908 case EncryptionAlgorithmAES128GCM:
909 key, eci, err = encryptAES128GCM(content)
910
911 default:
912 return nil, ErrUnsupportedEncryptionAlgorithm
913 }
914
915 if err != nil {
916 return nil, err
917 }
918
919
920 recipientInfos := make([]recipientInfo, len(recipients))
921 for i, recipient := range recipients {
922 encrypted, err := encryptKey(key, recipient)
923 if err != nil {
924 return nil, err
925 }
926 ias, err := cert2issuerAndSerial(recipient)
927 if err != nil {
928 return nil, err
929 }
930 info := recipientInfo{
931 Version: 0,
932 IssuerAndSerialNumber: ias,
933 KeyEncryptionAlgorithm: pkix.AlgorithmIdentifier{
934 Algorithm: oidEncryptionAlgorithmRSA,
935 },
936 EncryptedKey: encrypted,
937 }
938 recipientInfos[i] = info
939 }
940
941
942 envelope := envelopedData{
943 EncryptedContentInfo: *eci,
944 Version: 0,
945 RecipientInfos: recipientInfos,
946 }
947 innerContent, err := asn1.Marshal(envelope)
948 if err != nil {
949 return nil, err
950 }
951
952
953 wrapper := contentInfo{
954 ContentType: oidEnvelopedData,
955 Content: asn1.RawValue{Class: 2, Tag: 0, IsCompound: true, Bytes: innerContent},
956 }
957
958 return asn1.Marshal(wrapper)
959 }
960
961 func marshalEncryptedContent(content []byte) asn1.RawValue {
962 asn1Content, _ := asn1.Marshal(content)
963 return asn1.RawValue{Tag: 0, Class: 2, Bytes: asn1Content, IsCompound: true}
964 }
965
966 func encryptKey(key []byte, recipient *Certificate) ([]byte, error) {
967 if pub := recipient.PublicKey.(*rsa.PublicKey); pub != nil {
968 return rsa.EncryptPKCS1v15(rand.Reader, pub, key)
969 }
970 return nil, ErrPKCS7UnsupportedAlgorithm
971 }
972
View as plain text