gmsm/pkcs7/encrypt.go

64 lines
1.9 KiB
Go
Raw Normal View History

2023-03-09 11:45:39 +08:00
package pkcs7
import (
"crypto/rand"
2023-03-09 11:45:39 +08:00
"encoding/asn1"
"errors"
"github.com/emmansun/gmsm/pkcs"
)
type encryptedData struct {
Version int
EncryptedContentInfo encryptedContentInfo
}
// ErrPSKNotProvided is returned when attempting to encrypt
// using a PSK without actually providing the PSK.
var ErrPSKNotProvided = errors.New("pkcs7: cannot encrypt content: PSK not provided")
// EncryptUsingPSK creates and returns an encrypted data PKCS7 structure,
// encrypted using caller provided pre-shared secret.
func EncryptUsingPSK(cipher pkcs.Cipher, content []byte, key []byte) ([]byte, error) {
2024-06-21 18:00:21 +08:00
return encryptUsingPSK(cipher, content, key, []asn1.ObjectIdentifier{OIDData, OIDEncryptedData}, 0)
2023-03-09 11:45:39 +08:00
}
// EncryptSMUsingPSK creates and returns an encrypted data PKCS7 structure,
// encrypted using caller provided pre-shared secret.
// This method uses China Standard OID
func EncryptSMUsingPSK(cipher pkcs.Cipher, content []byte, key []byte) ([]byte, error) {
2024-06-21 18:00:21 +08:00
return encryptUsingPSK(cipher, content, key, []asn1.ObjectIdentifier{SM2OIDData, SM2OIDEncryptedData}, 1)
2023-03-09 11:45:39 +08:00
}
2024-06-21 18:00:21 +08:00
func encryptUsingPSK(cipher pkcs.Cipher, content []byte, key []byte, contentTypes []asn1.ObjectIdentifier, version int) ([]byte, error) {
2023-03-09 11:45:39 +08:00
var err error
if key == nil {
return nil, ErrPSKNotProvided
}
id, ciphertext, err := cipher.Encrypt(rand.Reader, key, content)
2023-03-09 11:45:39 +08:00
if err != nil {
return nil, err
}
// Prepare encrypted-data content
ed := encryptedData{
2024-06-21 18:00:21 +08:00
Version: version,
EncryptedContentInfo: newEncryptedContent(contentTypes[0], id, marshalEncryptedContent(ciphertext)),
2023-03-09 11:45:39 +08:00
}
innerContent, err := asn1.Marshal(ed)
if err != nil {
return nil, err
}
// Prepare outer payload structure
wrapper := contentInfo{
2024-06-21 18:00:21 +08:00
ContentType: contentTypes[1],
Content: asn1.RawValue{Class: asn1.ClassContextSpecific, Tag: 0, IsCompound: true, Bytes: innerContent},
2023-03-09 11:45:39 +08:00
}
return asn1.Marshal(wrapper)
}