mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-27 04:36:19 +08:00
pkcs7: support GetRecipients #252
This commit is contained in:
parent
3968b9d8b5
commit
ff59b79d60
@ -6,23 +6,55 @@ import (
|
||||
"crypto/rand"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/emmansun/gmsm/pkcs"
|
||||
"github.com/emmansun/gmsm/sm2"
|
||||
"github.com/emmansun/gmsm/smx509"
|
||||
)
|
||||
|
||||
// IssuerAndSerial is a structure that holds the issuer name and serial number
|
||||
type IssuerAndSerial struct {
|
||||
RawIssuer []byte
|
||||
SerialNumber *big.Int
|
||||
}
|
||||
|
||||
func newIssuerAndSerial(issuerAndSerial issuerAndSerial) IssuerAndSerial {
|
||||
is := IssuerAndSerial{}
|
||||
if len(issuerAndSerial.IssuerName.FullBytes) > 0 {
|
||||
is.RawIssuer = make([]byte, len(issuerAndSerial.IssuerName.FullBytes))
|
||||
copy(is.RawIssuer, issuerAndSerial.IssuerName.FullBytes)
|
||||
}
|
||||
if issuerAndSerial.SerialNumber != nil {
|
||||
is.SerialNumber = new(big.Int).Set(issuerAndSerial.SerialNumber)
|
||||
}
|
||||
return is
|
||||
}
|
||||
|
||||
// ErrUnsupportedAlgorithm tells you when our quick dev assumptions have failed
|
||||
var ErrUnsupportedAlgorithm = errors.New("pkcs7: cannot decrypt data: only RSA, SM2, DES, DES-EDE3, AES and SM4 supported")
|
||||
|
||||
// ErrNotEncryptedContent is returned when attempting to Decrypt data that is not encrypted data
|
||||
var ErrNotEncryptedContent = errors.New("pkcs7: content data is NOT a decryptable data type")
|
||||
|
||||
// ErrNotEnvelopedData is returned when attempting to Decrypt data that is not enveloped data
|
||||
var ErrNotEnvelopedData = errors.New("pkcs7: content data is NOT an enveloped data type")
|
||||
|
||||
type decryptable interface {
|
||||
GetRecipient(cert *smx509.Certificate) *recipientInfo
|
||||
GetRecipients() ([]IssuerAndSerial, error)
|
||||
GetEncryptedContentInfo() *encryptedContentInfo
|
||||
}
|
||||
|
||||
// GetRecipients returns the list of recipients for the enveloped data
|
||||
func (p7 *PKCS7) GetRecipients() ([]IssuerAndSerial, error) {
|
||||
decryptableData, ok := p7.raw.(decryptable)
|
||||
if !ok {
|
||||
return nil, ErrNotEnvelopedData
|
||||
}
|
||||
return decryptableData.GetRecipients()
|
||||
}
|
||||
|
||||
// Decrypt decrypts encrypted content info for recipient cert and private key
|
||||
func (p7 *PKCS7) Decrypt(cert *smx509.Certificate, pkey crypto.PrivateKey) ([]byte, error) {
|
||||
return p7.decrypt(cert, pkey, false)
|
||||
|
@ -11,6 +11,19 @@ func TestDecrypt(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
recipents, err := p7.GetRecipients()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(recipents) != 1 {
|
||||
t.Errorf("Expected 1 recipient, got %d", len(recipents))
|
||||
}
|
||||
if recipents[0].SerialNumber.Cmp(fixture.Certificate.SerialNumber) != 0 {
|
||||
t.Errorf("Recipient serial number does not match.\n\tExpected:%s\n\tActual:%s", fixture.Certificate.SerialNumber, recipents[0].SerialNumber)
|
||||
}
|
||||
if !bytes.Equal(recipents[0].RawIssuer, fixture.Certificate.RawIssuer) {
|
||||
t.Errorf("Recipient issuer name does not match.\n\tExpected:%x\n\tActual:%x", fixture.Certificate.RawIssuer, recipents[0].RawIssuer)
|
||||
}
|
||||
content, err := p7.Decrypt(fixture.Certificate, fixture.PrivateKey)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot Decrypt with error: %v", err)
|
||||
|
@ -30,6 +30,10 @@ func TestEncryptUsingPSK(t *testing.T) {
|
||||
}
|
||||
|
||||
p7, _ := Parse(ciphertext)
|
||||
_, err = p7.GetRecipients()
|
||||
if err != ErrNotEnvelopedData {
|
||||
t.Errorf("expected ErrNotEnvelopedData, got %v", err)
|
||||
}
|
||||
result, err := p7.DecryptUsingPSK(key)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot Decrypt encrypted result: %s", err)
|
||||
|
@ -48,6 +48,15 @@ func (data envelopedData) GetRecipient(cert *smx509.Certificate) *recipientInfo
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRecipients returns the list of recipients (READONLY) for the enveloped data
|
||||
func (data envelopedData) GetRecipients() ([]IssuerAndSerial, error) {
|
||||
var recipients []IssuerAndSerial
|
||||
for _, recp := range data.RecipientInfos {
|
||||
recipients = append(recipients, newIssuerAndSerial(recp.IssuerAndSerialNumber))
|
||||
}
|
||||
return recipients, nil
|
||||
}
|
||||
|
||||
func (data envelopedData) GetEncryptedContentInfo() *encryptedContentInfo {
|
||||
return &data.EncryptedContentInfo
|
||||
}
|
||||
|
@ -34,6 +34,15 @@ func (data signedEnvelopedData) GetRecipient(cert *smx509.Certificate) *recipien
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRecipients returns the list of recipients (READONLY) for the enveloped data
|
||||
func (data signedEnvelopedData) GetRecipients() ([]IssuerAndSerial, error) {
|
||||
var recipients []IssuerAndSerial
|
||||
for _, recp := range data.RecipientInfos {
|
||||
recipients = append(recipients, newIssuerAndSerial(recp.IssuerAndSerialNumber))
|
||||
}
|
||||
return recipients, nil
|
||||
}
|
||||
|
||||
func (data signedEnvelopedData) GetEncryptedContentInfo() *encryptedContentInfo {
|
||||
return &data.EncryptedContentInfo
|
||||
}
|
||||
|
@ -103,6 +103,14 @@ func TestParseSignedEvnvelopedData(t *testing.T) {
|
||||
t.Fatal("should only one certificate")
|
||||
}
|
||||
|
||||
recipients, err := p7Data.GetRecipients()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(recipients) != 1 {
|
||||
t.Fatal("should only one recipient")
|
||||
}
|
||||
|
||||
block, rest = pem.Decode([]byte(signKey))
|
||||
if len(rest) != 0 {
|
||||
t.Fatal("unexpected remaining PEM block during decode")
|
||||
@ -263,6 +271,23 @@ func TestCreateSignedEvnvelopedData(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
recipients, err := p7Data.GetRecipients()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(recipients) != 1 {
|
||||
t.Fatal("should only one recipient")
|
||||
}
|
||||
|
||||
if recipients[0].SerialNumber.Cmp(recipient.Certificate.SerialNumber) != 0 {
|
||||
t.Errorf("Recipient serial number does not match.\n\tExpected:%s\n\tActual:%s", recipient.Certificate.SerialNumber, recipients[0].SerialNumber)
|
||||
}
|
||||
|
||||
if !bytes.Equal(recipients[0].RawIssuer, recipient.Certificate.RawIssuer) {
|
||||
t.Errorf("Recipient issuer name does not match.\n\tExpected:%x\n\tActual:%x", recipient.Certificate.RawIssuer, recipients[0].RawIssuer)
|
||||
}
|
||||
|
||||
encKeyBytes, err := p7Data.DecryptAndVerify(recipient.Certificate, *recipient.PrivateKey, func() error {
|
||||
return p7Data.Verify()
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user