PKCS#7: Support CMS messages also [RFC5652]
Since CMS is an evolution of PKCS#7, with much of the ASN.1 being compatible, add support for CMS signed-data messages also [RFC5652 sec 5]. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-By: David Woodhouse <David.Woodhouse@intel.com>
This commit is contained in:
parent
a4c6e57f4f
commit
60d65cacd7
|
@ -69,7 +69,7 @@ SignerInfos ::= CHOICE {
|
|||
|
||||
SignerInfo ::= SEQUENCE {
|
||||
version INTEGER ({ pkcs7_note_signerinfo_version }),
|
||||
issuerAndSerialNumber IssuerAndSerialNumber,
|
||||
sid SignerIdentifier, -- CMS variant, not PKCS#7
|
||||
digestAlgorithm DigestAlgorithmIdentifier ({ pkcs7_sig_note_digest_algo }),
|
||||
authenticatedAttributes CHOICE {
|
||||
aaSet [0] IMPLICIT SetOfAuthenticatedAttribute
|
||||
|
@ -88,6 +88,12 @@ SignerInfo ::= SEQUENCE {
|
|||
} OPTIONAL
|
||||
} ({ pkcs7_note_signed_info })
|
||||
|
||||
SignerIdentifier ::= CHOICE {
|
||||
-- RFC5652 sec 5.3
|
||||
issuerAndSerialNumber IssuerAndSerialNumber,
|
||||
subjectKeyIdentifier [0] IMPLICIT SubjectKeyIdentifier
|
||||
}
|
||||
|
||||
IssuerAndSerialNumber ::= SEQUENCE {
|
||||
issuer Name ({ pkcs7_sig_note_issuer }),
|
||||
serialNumber CertificateSerialNumber ({ pkcs7_sig_note_serial })
|
||||
|
@ -95,6 +101,8 @@ IssuerAndSerialNumber ::= SEQUENCE {
|
|||
|
||||
CertificateSerialNumber ::= INTEGER
|
||||
|
||||
SubjectKeyIdentifier ::= OCTET STRING ({ pkcs7_sig_note_skid })
|
||||
|
||||
SetOfAuthenticatedAttribute ::= SET OF AuthenticatedAttribute
|
||||
|
||||
AuthenticatedAttribute ::= SEQUENCE {
|
||||
|
|
|
@ -33,6 +33,9 @@ struct pkcs7_parse_context {
|
|||
unsigned raw_serial_size;
|
||||
unsigned raw_issuer_size;
|
||||
const void *raw_issuer;
|
||||
const void *raw_skid;
|
||||
unsigned raw_skid_size;
|
||||
bool expect_skid;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -249,15 +252,21 @@ int pkcs7_note_signeddata_version(void *context, size_t hdrlen,
|
|||
unsigned char tag,
|
||||
const void *value, size_t vlen)
|
||||
{
|
||||
struct pkcs7_parse_context *ctx = context;
|
||||
unsigned version;
|
||||
|
||||
if (vlen != 1)
|
||||
goto unsupported;
|
||||
|
||||
version = *(const u8 *)value;
|
||||
ctx->msg->version = version = *(const u8 *)value;
|
||||
switch (version) {
|
||||
case 1:
|
||||
/* PKCS#7 SignedData [RFC2315 sec 9.1] */
|
||||
/* PKCS#7 SignedData [RFC2315 sec 9.1]
|
||||
* CMS ver 1 SignedData [RFC5652 sec 5.1]
|
||||
*/
|
||||
break;
|
||||
case 3:
|
||||
/* CMS ver 3 SignedData [RFC2315 sec 5.1] */
|
||||
break;
|
||||
default:
|
||||
goto unsupported;
|
||||
|
@ -277,6 +286,7 @@ int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
|
|||
unsigned char tag,
|
||||
const void *value, size_t vlen)
|
||||
{
|
||||
struct pkcs7_parse_context *ctx = context;
|
||||
unsigned version;
|
||||
|
||||
if (vlen != 1)
|
||||
|
@ -285,7 +295,18 @@ int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
|
|||
version = *(const u8 *)value;
|
||||
switch (version) {
|
||||
case 1:
|
||||
/* PKCS#7 SignerInfo [RFC2315 sec 9.2] */
|
||||
/* PKCS#7 SignerInfo [RFC2315 sec 9.2]
|
||||
* CMS ver 1 SignerInfo [RFC5652 sec 5.3]
|
||||
*/
|
||||
if (ctx->msg->version != 1)
|
||||
goto version_mismatch;
|
||||
ctx->expect_skid = false;
|
||||
break;
|
||||
case 3:
|
||||
/* CMS ver 3 SignerInfo [RFC2315 sec 5.3] */
|
||||
if (ctx->msg->version == 1)
|
||||
goto version_mismatch;
|
||||
ctx->expect_skid = true;
|
||||
break;
|
||||
default:
|
||||
goto unsupported;
|
||||
|
@ -296,6 +317,9 @@ int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
|
|||
unsupported:
|
||||
pr_warn("Unsupported SignerInfo version\n");
|
||||
return -EINVAL;
|
||||
version_mismatch:
|
||||
pr_warn("SignedData-SignerInfo version mismatch\n");
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -439,6 +463,22 @@ int pkcs7_sig_note_issuer(void *context, size_t hdrlen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note the issuing cert's subjectKeyIdentifier
|
||||
*/
|
||||
int pkcs7_sig_note_skid(void *context, size_t hdrlen,
|
||||
unsigned char tag,
|
||||
const void *value, size_t vlen)
|
||||
{
|
||||
struct pkcs7_parse_context *ctx = context;
|
||||
|
||||
pr_devel("SKID: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
|
||||
|
||||
ctx->raw_skid = value;
|
||||
ctx->raw_skid_size = vlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note the signature data
|
||||
*/
|
||||
|
@ -472,13 +512,21 @@ int pkcs7_note_signed_info(void *context, size_t hdrlen,
|
|||
struct asymmetric_key_id *kid;
|
||||
|
||||
/* Generate cert issuer + serial number key ID */
|
||||
kid = asymmetric_key_generate_id(ctx->raw_serial,
|
||||
ctx->raw_serial_size,
|
||||
ctx->raw_issuer,
|
||||
ctx->raw_issuer_size);
|
||||
if (!ctx->expect_skid) {
|
||||
kid = asymmetric_key_generate_id(ctx->raw_serial,
|
||||
ctx->raw_serial_size,
|
||||
ctx->raw_issuer,
|
||||
ctx->raw_issuer_size);
|
||||
} else {
|
||||
kid = asymmetric_key_generate_id(ctx->raw_skid,
|
||||
ctx->raw_skid_size,
|
||||
"", 0);
|
||||
}
|
||||
if (IS_ERR(kid))
|
||||
return PTR_ERR(kid);
|
||||
|
||||
pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
|
||||
|
||||
sinfo->signing_cert_id = kid;
|
||||
sinfo->index = ++ctx->sinfo_index;
|
||||
*ctx->ppsinfo = sinfo;
|
||||
|
|
|
@ -33,7 +33,9 @@ struct pkcs7_signed_info {
|
|||
unsigned authattrs_len;
|
||||
const void *authattrs;
|
||||
|
||||
/* Issuing cert serial number and issuer's name */
|
||||
/* Issuing cert serial number and issuer's name [PKCS#7 or CMS ver 1]
|
||||
* or issuing cert's SKID [CMS ver 3].
|
||||
*/
|
||||
struct asymmetric_key_id *signing_cert_id;
|
||||
|
||||
/* Message signature.
|
||||
|
@ -50,6 +52,7 @@ struct pkcs7_message {
|
|||
struct x509_certificate *certs; /* Certificate list */
|
||||
struct x509_certificate *crl; /* Revocation list */
|
||||
struct pkcs7_signed_info *signed_infos;
|
||||
u8 version; /* Version of cert (1 -> PKCS#7 or CMS; 3 -> CMS) */
|
||||
|
||||
/* Content Data (or NULL) */
|
||||
enum OID data_type; /* Type of Data */
|
||||
|
|
Loading…
Reference in New Issue
Block a user