Documentation ¶
Overview ¶
Package cms implements parsing and generation of some PKCS#7 structures.
Index ¶
- Constants
- Variables
- func CheckSignature(c *x509.Certificate, algo SignatureAlgorithm, signed, signature []byte) error
- func Compress(data []byte) ([]byte, error)
- func DegenerateCertificate(cert []byte) ([]byte, error)
- func Encrypt(content []byte, recipients []*x509.Certificate) ([]byte, error)
- func EncryptUsingPSK(content []byte, key []byte) ([]byte, error)
- type Attribute
- type EncryptionAlgorithm
- type MessageDigestMismatchError
- type PKCS7
- func (p7 *PKCS7) Decompress() ([]byte, error)
- func (p7 *PKCS7) Decrypt(cert *x509.Certificate, pkey crypto.PrivateKey) ([]byte, error)
- func (p7 *PKCS7) DecryptUsingPSK(key []byte) ([]byte, error)
- func (p7 *PKCS7) GetOnlySigner() *x509.Certificate
- func (p7 *PKCS7) UnmarshalSignedAttribute(attributeType asn1.ObjectIdentifier, out interface{}) error
- func (p7 *PKCS7) Verify() (err error)
- func (p7 *PKCS7) VerifyWithChain(truststore *x509.CertPool) (err error)
- func (p7 *PKCS7) VerifyWithChainAtTime(truststore *x509.CertPool, currentTime time.Time) (err error)
- type SignatureAlgorithm
- type SignedData
- func (sd *SignedData) AddCertificate(cert *x509.Certificate)
- func (sd *SignedData) AddSigner(ee *x509.Certificate, pkey crypto.PrivateKey, config SignerInfoConfig) error
- func (sd *SignedData) AddSignerChain(ee *x509.Certificate, pkey crypto.PrivateKey, parents []*x509.Certificate, ...) error
- func (sd *SignedData) Detach()
- func (sd *SignedData) Finish() ([]byte, error)
- func (sd *SignedData) GetSignedData() *signedData
- func (sd *SignedData) RemoveAuthenticatedAttributes()
- func (sd *SignedData) RemoveUnauthenticatedAttributes()
- func (sd *SignedData) SetDigestAlgorithm(d asn1.ObjectIdentifier)
- func (sd *SignedData) SetEncryptionAlgorithm(d asn1.ObjectIdentifier)
- func (sd *SignedData) SignWithoutAttr(ee *x509.Certificate, pkey crypto.PrivateKey, config SignerInfoConfig) error
- type SignerInfoConfig
Examples ¶
Constants ¶
const ( // DESCBC is the DES CBC encryption algorithm DESCBC = EncryptionAlgorithm(iota) // DESEDE3CBC is the 3DES CBC encryption algorithm DESEDE3CBC // AES128CBC is the AES 128 bits with CBC encryption algorithm // Avoid this algorithm unless required for interoperability; use AES GCM instead. AES128CBC // AES192CBC is the AES 192 bits with CBC encryption algorithm // Avoid this algorithm unless required for interoperability; use AES GCM instead. AES192CBC // AES256CBC is the AES 256 bits with CBC encryption algorithm // Avoid this algorithm unless required for interoperability; use AES GCM instead. AES256CBC // AES128GCM is the AES 128 bits with GCM encryption algorithm AES128GCM // AES192GCM is the AES 192 bits with GCM encryption algorithm AES192GCM // AES256GCM is the AES 256 bits with GCM encryption algorithm AES256GCM ChaCha20Poly1305 )
Variables ¶
var ( // Signed Data OIDs OIDData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1} OIDSignedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2} OIDEnvelopedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 3} OIDEncryptedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 6} OIDCompressedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 1, 9} OIDAttributeContentType = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 3} OIDAttributeMessageDigest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 4} OIDAttributeSigningTime = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 5} // Compression Algorithms OIDCompressionAlgorithmZLIB = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 3, 8} // Digest Algorithms OIDDigestAlgorithmMD5 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 5} // deprecated OIDDigestAlgorithmSHA1 = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26} // deprecated OIDDigestAlgorithmSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} OIDDigestAlgorithmSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} OIDDigestAlgorithmSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3} OIDDigestAlgorithmSHA224 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 4} OIDDigestAlgorithmSHAT224 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 7} OIDDigestAlgorithmSHAT256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 8} OIDDigestAlgorithmSHAT384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 9} OIDDigestAlgorithmSHAT512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 10} OIDDigestAlgorithmBlake2s256 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 8} OIDDigestAlgorithmBlake2b256 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 8} OIDDigestAlgorithmBlake2b384 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 12} OIDDigestAlgorithmBlake2b512 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 16} // Signature Algorithms OIDSignatureAlgorithmRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} OIDSignatureAlgorithmRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10} OIDSignatureAlgorithmRSAMD5 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4} OIDSignatureAlgorithmRSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} OIDSignatureAlgorithmRSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} OIDSignatureAlgorithmRSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} OIDSignatureAlgorithmRSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} OIDSignatureAlgorithmRSASHA224 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 14} OIDSignatureAlgorithmRSASHAT224 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 13} OIDSignatureAlgorithmRSASHAT256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 14} OIDSignatureAlgorithmRSASHAT384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 15} OIDSignatureAlgorithmRSASHAT512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 16} OIDSignatureAlgorithmECDSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} OIDSignatureAlgorithmECDSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} OIDSignatureAlgorithmECDSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} OIDSignatureAlgorithmECDSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} OIDSignatureAlgorithmECDSASHA224 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 1} OIDSignatureAlgorithmECDSASHAT224 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 9} OIDSignatureAlgorithmECDSASHAT256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 10} OIDSignatureAlgorithmECDSASHAT384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 11} OIDSignatureAlgorithmECDSASHAT512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 12} OIDSignatureAlgorithmED25519 = asn1.ObjectIdentifier{1, 3, 101, 112} OIDEncryptionAlgorithmECDSAP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} OIDEncryptionAlgorithmECDSAP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} OIDEncryptionAlgorithmECDSAP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} // Encryption Algorithms OIDEncryptionAlgorithmChaCha20Poly1305 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 3, 18} OIDEncryptionAlgorithmDESCBC = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 7} OIDEncryptionAlgorithmDESEDE3CBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 3, 7} OIDEncryptionAlgorithmAES128CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2} OIDEncryptionAlgorithmAES192CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 22} OIDEncryptionAlgorithmAES256CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42} OIDEncryptionAlgorithmAES128GCM = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 6} OIDEncryptionAlgorithmAES192GCM = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 26} OIDEncryptionAlgorithmAES256GCM = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 46} )
var ContentEncryptionAlgorithm = DESCBC
ContentEncryptionAlgorithm determines the algorithm used to encrypt the plaintext message. Change the value of this variable to change which algorithm is used in the Encrypt() function.
var ErrNotCompressedContent = errors.New("pkcs7: content data is not a compressed data type")
var ErrNotEncryptedContent = errors.New("pkcs7: content data is not a decryptable data type")
ErrNotEncryptedContent is returned when attempting to Decrypt data that is not encrypted data
var ErrPSKNotProvided = errors.New("pkcs7: cannot encrypt content: PSK not provided")
ErrPSKNotProvided is returned when attempting to encrypt using a PSK without actually providing the PSK.
var ErrUnsupportedAlgorithm = errors.New("pkcs7: cannot decrypt data: only RSA, DES, AES supported")
ErrUnsupportedAlgorithm tells you when our quick dev assumptions have failed
var ErrUnsupportedContentType = errors.New("pkcs7: cannot parse data: unimplemented content type")
ErrUnsupportedContentType is returned when a PKCS7 content is not supported. Currently only Data (1.2.840.113549.1.7.1), Signed Data (1.2.840.113549.1.7.2), and Enveloped Data are supported (1.2.840.113549.1.7.3)
var ErrUnsupportedEncryptionAlgorithm = errors.New("pkcs7: cannot encrypt content: only DES-CBC, AES-CBC, and AES-GCM supported")
ErrUnsupportedEncryptionAlgorithm is returned when attempting to encrypt content with an unsupported algorithm.
Functions ¶
func CheckSignature ¶
func CheckSignature(c *x509.Certificate, algo SignatureAlgorithm, signed, signature []byte) error
CheckSignature verifies that signature is a valid signature over signed from c's public key.
This is a low-level API that performs no validity checks on the certificate.
MD5WithRSA signatures are rejected, while SHA1WithRSA and ECDSAWithSHA1 signatures are currently accepted.
func DegenerateCertificate ¶
DegenerateCertificate creates a signed data structure containing only the provided certificate or certificate chain.
func Encrypt ¶
func Encrypt(content []byte, recipients []*x509.Certificate) ([]byte, error)
Encrypt creates and returns an envelope data PKCS7 structure with encrypted recipient keys for each recipient public key.
The algorithm used to perform encryption is determined by the current value of the global ContentEncryptionAlgorithm package variable. By default, the value is EncryptionAlgorithmDESCBC. To use a different algorithm, change the value before calling Encrypt(). For example:
ContentEncryptionAlgorithm = EncryptionAlgorithmAES128GCM
TODO(fullsailor): Add support for encrypting content with other algorithms
Types ¶
type Attribute ¶
type Attribute struct { Type asn1.ObjectIdentifier Value interface{} }
Attribute represents a key value pair attribute. Value must be marshalable byte `encoding/asn1`
type EncryptionAlgorithm ¶
type EncryptionAlgorithm int
type MessageDigestMismatchError ¶
MessageDigestMismatchError is returned when the signer data digest does not match the computed digest for the contained content
func (*MessageDigestMismatchError) Error ¶
func (err *MessageDigestMismatchError) Error() string
type PKCS7 ¶
type PKCS7 struct { Content []byte Certificates []*x509.Certificate CRLs []x509.RevocationList Signers []signerInfo // contains filtered or unexported fields }
PKCS7 Represents a PKCS7 structure
func (*PKCS7) Decompress ¶ added in v1.3.2
func (*PKCS7) Decrypt ¶
func (p7 *PKCS7) Decrypt(cert *x509.Certificate, pkey crypto.PrivateKey) ([]byte, error)
Decrypt decrypts encrypted content info for recipient cert and private key
func (*PKCS7) DecryptUsingPSK ¶
DecryptUsingPSK decrypts encrypted data using caller provided pre-shared secret
func (*PKCS7) GetOnlySigner ¶
func (p7 *PKCS7) GetOnlySigner() *x509.Certificate
GetOnlySigner returns an x509.Certificate for the first signer of the signed data payload. If there are more or less than one signer, nil is returned
func (*PKCS7) UnmarshalSignedAttribute ¶
func (p7 *PKCS7) UnmarshalSignedAttribute(attributeType asn1.ObjectIdentifier, out interface{}) error
UnmarshalSignedAttribute decodes a single attribute from the signer info
func (*PKCS7) Verify ¶
Verify is a wrapper around VerifyWithChain() that initializes an empty trust store, effectively disabling certificate verification when validating a signature.
func (*PKCS7) VerifyWithChain ¶
VerifyWithChain checks the signatures of a PKCS7 object.
If truststore is not nil, it also verifies the chain of trust of the end-entity signer cert to one of the roots in the truststore. When the PKCS7 object includes the signing time authenticated attr verifies the chain at that time and UTC now otherwise.
func (*PKCS7) VerifyWithChainAtTime ¶
func (p7 *PKCS7) VerifyWithChainAtTime(truststore *x509.CertPool, currentTime time.Time) (err error)
VerifyWithChainAtTime checks the signatures of a PKCS7 object.
If truststore is not nil, it also verifies the chain of trust of the end-entity signer cert to a root in the truststore at currentTime. It does not use the signing time authenticated attribute.
type SignatureAlgorithm ¶
type SignatureAlgorithm int
const ( UnknownSignatureAlgorithm SignatureAlgorithm = iota MD2WithRSA // Unsupported. MD5WithRSA // Deprecated. SHA1WithRSA // Deprecated. SHA224WithRSA SHA256WithRSA SHA384WithRSA SHA512WithRSA SHAT224WithRSA SHAT256WithRSA SHAT384WithRSA SHAT512WithRSA DSAWithSHA1 // Unsupported. DSAWithSHA256 // Unsupported. ECDSAWithSHA1 // Deprecated. ECDSAWithSHA224 ECDSAWithSHA256 ECDSAWithSHA384 ECDSAWithSHA512 ECDSAWithSHAT224 ECDSAWithSHAT256 ECDSAWithSHAT384 ECDSAWithSHAT512 SHA224WithRSAPSS SHA256WithRSAPSS SHA384WithRSAPSS SHA512WithRSAPSS SHAT224WithRSAPSS SHAT256WithRSAPSS SHAT384WithRSAPSS SHAT512WithRSAPSS PureEd25519 )
type SignedData ¶
type SignedData struct {
// contains filtered or unexported fields
}
SignedData is an opaque data structure for creating signed data payloads
Example ¶
// generate a signing cert or load a key pair cert, err := createTestCertificate(x509.SHA256WithRSA) if err != nil { fmt.Printf("Cannot create test certificates: %s", err) } // Initialize a SignedData struct with content to be signed signedData, err := NewSignedData([]byte("Example data to be signed")) if err != nil { fmt.Printf("Cannot initialize signed data: %s", err) } // Add the signing cert and private key if err := signedData.AddSigner(cert.Certificate, cert.PrivateKey, SignerInfoConfig{}); err != nil { fmt.Printf("Cannot add signer: %s", err) } // Call Detach() is you want to remove content from the signature // and generate an S/MIME detached signature signedData.Detach() // Finish() to obtain the signature bytes detachedSignature, err := signedData.Finish() if err != nil { fmt.Printf("Cannot finish signing data: %s", err) } pem.Encode(os.Stdout, &pem.Block{Type: "PKCS7", Bytes: detachedSignature})
Output:
func NewSignedData ¶
func NewSignedData(data []byte) (*SignedData, error)
NewSignedData takes data and initializes a PKCS7 SignedData struct that is ready to be signed via AddSigner. The digest algorithm is set to SHA256 by default and can be changed by calling SetDigestAlgorithm.
func (*SignedData) AddCertificate ¶
func (sd *SignedData) AddCertificate(cert *x509.Certificate)
AddCertificate adds the certificate to the payload. Useful for parent certificates
func (*SignedData) AddSigner ¶
func (sd *SignedData) AddSigner(ee *x509.Certificate, pkey crypto.PrivateKey, config SignerInfoConfig) error
AddSigner is a wrapper around AddSignerChain() that adds a signer without any parent.
func (*SignedData) AddSignerChain ¶
func (sd *SignedData) AddSignerChain(ee *x509.Certificate, pkey crypto.PrivateKey, parents []*x509.Certificate, config SignerInfoConfig) error
AddSignerChain signs attributes about the content and adds certificates and signers infos to the Signed Data. The certificate and private key of the end-entity signer are used to issue the signature, and any parent of that end-entity that need to be added to the list of certifications can be specified in the parents slice.
The signature algorithm used to hash the data is the one of the end-entity certificate.
func (*SignedData) Detach ¶
func (sd *SignedData) Detach()
Detach removes content from the signed data struct to make it a detached signature. This must be called right before Finish()
func (*SignedData) Finish ¶
func (sd *SignedData) Finish() ([]byte, error)
Finish marshals the content and its signers
func (*SignedData) GetSignedData ¶
func (sd *SignedData) GetSignedData() *signedData
GetSignedData returns the private Signed Data
func (*SignedData) RemoveAuthenticatedAttributes ¶
func (sd *SignedData) RemoveAuthenticatedAttributes()
RemoveAuthenticatedAttributes removes authenticated attributes from signedData similar to OpenSSL's PKCS7_NOATTR or -noattr flags
func (*SignedData) RemoveUnauthenticatedAttributes ¶
func (sd *SignedData) RemoveUnauthenticatedAttributes()
RemoveUnauthenticatedAttributes removes unauthenticated attributes from signedData
func (*SignedData) SetDigestAlgorithm ¶
func (sd *SignedData) SetDigestAlgorithm(d asn1.ObjectIdentifier)
SetDigestAlgorithm sets the digest algorithm to be used in the signing process.
This should be called before adding signers
func (*SignedData) SetEncryptionAlgorithm ¶
func (sd *SignedData) SetEncryptionAlgorithm(d asn1.ObjectIdentifier)
SetEncryptionAlgorithm sets the encryption algorithm to be used in the signing process.
This should be called before adding signers
func (*SignedData) SignWithoutAttr ¶
func (sd *SignedData) SignWithoutAttr(ee *x509.Certificate, pkey crypto.PrivateKey, config SignerInfoConfig) error
SignWithoutAttr issues a signature on the content of the pkcs7 SignedData. Unlike AddSigner/AddSignerChain, it calculates the digest on the data alone and does not include any signed attributes like timestamp and so on.
This function is needed to sign old Android APKs, something you probably shouldn't do unless you're maintaining backward compatibility for old applications.
type SignerInfoConfig ¶
type SignerInfoConfig struct { ExtraSignedAttributes []Attribute ExtraUnsignedAttributes []Attribute }
SignerInfoConfig are optional values to include when adding a signer