github.com/Hyperledger-TWGC/tjfoc-gm@v1.4.0/x509/pkcs7.go (about) 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" // for crypto.SHA1 13 "crypto/x509/pkix" 14 "encoding/asn1" 15 "errors" 16 "fmt" 17 "math/big" 18 "sort" 19 "time" 20 ) 21 22 // PKCS7 Represents a PKCS7 structure 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 // ErrUnsupportedContentType is returned when a PKCS7 content is not supported. 37 // Currently only Data (1.2.156.10197.6.1.4.2.1), Signed Data (1.2.156.10197.6.1.4.2.2), 38 // and Enveloped Data are supported (1.2.156.10197.6.1.4.2.3) 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 // MessageDigestMismatchError is returned when the signer data digest does not 101 // match the computed digest for the contained content 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 // ParsePKCS7 decodes a DER encoded PKCS7. 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 // fmt.Printf("--> Content Type: %s", info.ContentType) 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 // fmt.Printf("--> Signed Data Version %d\n", sd.Version) 161 162 var compound asn1.RawValue 163 var content unsignedData 164 165 // The Content.Bytes maybe empty on PKI responses. 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 // Compound octet string 172 if compound.IsCompound { 173 if _, err = asn1.Unmarshal(compound.Bytes, &content); err != nil { 174 return nil, err 175 } 176 } else { 177 // assuming this is tag 04 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 // Verify checks the signatures of a PKCS7 object 212 // WARNING: Verify does not check signing time or verify certificate chains at 213 // this time. 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 // fmt.Println("===== hash algo=====:", hash) 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 // TODO(shengzhi): Optionally verify certificate chain 249 // TODO(shengzhi): Optionally verify signingTime against certificate NotAfter/NotBefore 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 // Remove the leading sequence octets 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 // GetOnlySigner returns an x509.Certificate for the first signer of the signed 328 // data payload. If there are more or less than one signer, nil is returned 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 // ErrPKCS7UnsupportedAlgorithm tells you when our quick dev assumptions have failed 338 var ErrPKCS7UnsupportedAlgorithm = errors.New("pkcs7: cannot decrypt data: only RSA, DES, DES-EDE3, AES-256-CBC and AES-128-GCM supported") 339 340 // ErrNotEncryptedContent is returned when attempting to Decrypt data that is not encrypted data 341 var ErrNotEncryptedContent = errors.New("pkcs7: content data is a decryptable data type") 342 343 // Decrypt decrypts encrypted content info for recipient cert and private key 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 // TODO: SM decript 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 // EncryptedContent can either be constructed of multple OCTET STRINGs 384 // or _be_ a tagged OCTET STRING 385 var cyphertext []byte 386 if eci.EncryptedContent.IsCompound { 387 // Complex case to concat all of the children OCTET STRINGs 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 // Simple case, the bytes _are_ the cyphertext 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 // the last byte is the length of padding 498 padlen := int(data[len(data)-1]) 499 500 // check padding integrity, all bytes should be the same 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 // UnmarshalSignedAttribute decodes a single attribute from the signer info 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 // SignedData is an opaque data structure for creating signed data payloads 535 type SignedData struct { 536 sd signedData 537 certs []*Certificate 538 messageDigest []byte 539 } 540 541 // Attribute represents a key value pair attribute. Value must be marshalable byte 542 // `encoding/asn1` 543 type Attribute struct { 544 Type asn1.ObjectIdentifier 545 Value interface{} 546 } 547 548 // SignerInfoConfig are optional values to include when adding a signer 549 type SignerInfoConfig struct { 550 ExtraSignedAttributes []Attribute 551 } 552 553 // NewSignedData initializes a SignedData with content 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 // Add adds the attribute, maintaining insertion order 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}, // 17 == SET tag 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 // AddSigner signs attributes about the content and adds certificate to payload 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 // create signature of signed attributes 673 sd.certs = append(sd.certs, cert) 674 sd.sd.SignerInfos = append(sd.sd.SignerInfos, signer) 675 return nil 676 } 677 678 // AddCertificate adds the certificate to the payload. Useful for parent certificates 679 func (sd *SignedData) AddCertificate(cert *Certificate) { 680 sd.certs = append(sd.certs, cert) 681 } 682 683 // Detach removes content from the signed data struct to make it a detached signature. 684 // This must be called right before Finish() 685 func (sd *SignedData) Detach() { 686 sd.sd.ContentInfo = contentInfo{ContentType: oidData} 687 } 688 689 // Finish marshals the content and its signers 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 // The issuer RDNSequence has to match exactly the sequence in the certificate 706 // We cannot use cert.Issuer.ToRDNSequence() here since it mangles the sequence 707 ias.IssuerName = asn1.RawValue{FullBytes: cert.RawIssuer} 708 ias.SerialNumber = cert.SerialNumber 709 710 return ias, nil 711 } 712 713 // signs the DER encoded form of the attributes with the private key 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 // concats and wraps the certificates in the RawValue structure 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 // Even though, the tag & length are stripped out during marshalling the 740 // RawContent, we have to encode it into the RawContent. If its missing, 741 // then `asn1.Marshal()` will strip out the certificate wrapper instead. 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 // DegenerateCertificate creates a signed data structure containing only the 752 // provided certificate or certificate chain. 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 // ContentEncryptionAlgorithm determines the algorithm used to encrypt the 782 // plaintext message. Change the value of this variable to change which 783 // algorithm is used in the Encrypt() function. 784 var ContentEncryptionAlgorithm = EncryptionAlgorithmDESCBC 785 786 // ErrUnsupportedEncryptionAlgorithm is returned when attempting to encrypt 787 // content with an unsupported algorithm. 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 // Create AES key and nonce 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 // Encrypt content 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 // Prepare ASN.1 Encrypted Content Info 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 // Create DES key & CBC IV 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 // Encrypt padded content 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 // Prepare ASN.1 Encrypted Content Info 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 // Encrypt creates and returns an envelope data PKCS7 structure with encrypted 888 // recipient keys for each recipient public key. 889 // 890 // The algorithm used to perform encryption is determined by the current value 891 // of the global ContentEncryptionAlgorithm package variable. By default, the 892 // value is EncryptionAlgorithmDESCBC. To use a different algorithm, change the 893 // value before calling Encrypt(). For example: 894 // 895 // ContentEncryptionAlgorithm = EncryptionAlgorithmAES128GCM 896 // 897 // TODO(fullsailor): Add support for encrypting content with other algorithms 898 func PKCS7Encrypt(content []byte, recipients []*Certificate) ([]byte, error) { 899 var eci *encryptedContentInfo 900 var key []byte 901 var err error 902 903 // Apply chosen symmetric encryption method 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 // Prepare each recipient's encrypted cipher key 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 // Prepare envelope content 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 // Prepare outer payload structure 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 }