aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2015-07-20 16:16:33 -0400
committerDavid Howells <dhowells@redhat.com>2015-08-12 12:01:01 -0400
commit60d65cacd7c2d84a6dcad69bcb57bbf0220c8643 (patch)
tree636bda3cc9024a04edf1ae5780266fde743e7b1e /crypto
parenta4c6e57f4f5fa65cbdb8cc1c14ff5ca7c56766c3 (diff)
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>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/asymmetric_keys/pkcs7.asn110
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.c62
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.h5
3 files changed, 68 insertions, 9 deletions
diff --git a/crypto/asymmetric_keys/pkcs7.asn1 b/crypto/asymmetric_keys/pkcs7.asn1
index 05504431e1c1..6bf8ff4f7414 100644
--- a/crypto/asymmetric_keys/pkcs7.asn1
+++ b/crypto/asymmetric_keys/pkcs7.asn1
@@ -69,7 +69,7 @@ SignerInfos ::= CHOICE {
69 69
70SignerInfo ::= SEQUENCE { 70SignerInfo ::= SEQUENCE {
71 version INTEGER ({ pkcs7_note_signerinfo_version }), 71 version INTEGER ({ pkcs7_note_signerinfo_version }),
72 issuerAndSerialNumber IssuerAndSerialNumber, 72 sid SignerIdentifier, -- CMS variant, not PKCS#7
73 digestAlgorithm DigestAlgorithmIdentifier ({ pkcs7_sig_note_digest_algo }), 73 digestAlgorithm DigestAlgorithmIdentifier ({ pkcs7_sig_note_digest_algo }),
74 authenticatedAttributes CHOICE { 74 authenticatedAttributes CHOICE {
75 aaSet [0] IMPLICIT SetOfAuthenticatedAttribute 75 aaSet [0] IMPLICIT SetOfAuthenticatedAttribute
@@ -88,6 +88,12 @@ SignerInfo ::= SEQUENCE {
88 } OPTIONAL 88 } OPTIONAL
89} ({ pkcs7_note_signed_info }) 89} ({ pkcs7_note_signed_info })
90 90
91SignerIdentifier ::= CHOICE {
92 -- RFC5652 sec 5.3
93 issuerAndSerialNumber IssuerAndSerialNumber,
94 subjectKeyIdentifier [0] IMPLICIT SubjectKeyIdentifier
95}
96
91IssuerAndSerialNumber ::= SEQUENCE { 97IssuerAndSerialNumber ::= SEQUENCE {
92 issuer Name ({ pkcs7_sig_note_issuer }), 98 issuer Name ({ pkcs7_sig_note_issuer }),
93 serialNumber CertificateSerialNumber ({ pkcs7_sig_note_serial }) 99 serialNumber CertificateSerialNumber ({ pkcs7_sig_note_serial })
@@ -95,6 +101,8 @@ IssuerAndSerialNumber ::= SEQUENCE {
95 101
96CertificateSerialNumber ::= INTEGER 102CertificateSerialNumber ::= INTEGER
97 103
104SubjectKeyIdentifier ::= OCTET STRING ({ pkcs7_sig_note_skid })
105
98SetOfAuthenticatedAttribute ::= SET OF AuthenticatedAttribute 106SetOfAuthenticatedAttribute ::= SET OF AuthenticatedAttribute
99 107
100AuthenticatedAttribute ::= SEQUENCE { 108AuthenticatedAttribute ::= SEQUENCE {
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index ab427f04b299..826e2f3f507b 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -33,6 +33,9 @@ struct pkcs7_parse_context {
33 unsigned raw_serial_size; 33 unsigned raw_serial_size;
34 unsigned raw_issuer_size; 34 unsigned raw_issuer_size;
35 const void *raw_issuer; 35 const void *raw_issuer;
36 const void *raw_skid;
37 unsigned raw_skid_size;
38 bool expect_skid;
36}; 39};
37 40
38/* 41/*
@@ -249,15 +252,21 @@ int pkcs7_note_signeddata_version(void *context, size_t hdrlen,
249 unsigned char tag, 252 unsigned char tag,
250 const void *value, size_t vlen) 253 const void *value, size_t vlen)
251{ 254{
255 struct pkcs7_parse_context *ctx = context;
252 unsigned version; 256 unsigned version;
253 257
254 if (vlen != 1) 258 if (vlen != 1)
255 goto unsupported; 259 goto unsupported;
256 260
257 version = *(const u8 *)value; 261 ctx->msg->version = version = *(const u8 *)value;
258 switch (version) { 262 switch (version) {
259 case 1: 263 case 1:
260 /* PKCS#7 SignedData [RFC2315 sec 9.1] */ 264 /* PKCS#7 SignedData [RFC2315 sec 9.1]
265 * CMS ver 1 SignedData [RFC5652 sec 5.1]
266 */
267 break;
268 case 3:
269 /* CMS ver 3 SignedData [RFC2315 sec 5.1] */
261 break; 270 break;
262 default: 271 default:
263 goto unsupported; 272 goto unsupported;
@@ -277,6 +286,7 @@ int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
277 unsigned char tag, 286 unsigned char tag,
278 const void *value, size_t vlen) 287 const void *value, size_t vlen)
279{ 288{
289 struct pkcs7_parse_context *ctx = context;
280 unsigned version; 290 unsigned version;
281 291
282 if (vlen != 1) 292 if (vlen != 1)
@@ -285,7 +295,18 @@ int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
285 version = *(const u8 *)value; 295 version = *(const u8 *)value;
286 switch (version) { 296 switch (version) {
287 case 1: 297 case 1:
288 /* PKCS#7 SignerInfo [RFC2315 sec 9.2] */ 298 /* PKCS#7 SignerInfo [RFC2315 sec 9.2]
299 * CMS ver 1 SignerInfo [RFC5652 sec 5.3]
300 */
301 if (ctx->msg->version != 1)
302 goto version_mismatch;
303 ctx->expect_skid = false;
304 break;
305 case 3:
306 /* CMS ver 3 SignerInfo [RFC2315 sec 5.3] */
307 if (ctx->msg->version == 1)
308 goto version_mismatch;
309 ctx->expect_skid = true;
289 break; 310 break;
290 default: 311 default:
291 goto unsupported; 312 goto unsupported;
@@ -296,6 +317,9 @@ int pkcs7_note_signerinfo_version(void *context, size_t hdrlen,
296unsupported: 317unsupported:
297 pr_warn("Unsupported SignerInfo version\n"); 318 pr_warn("Unsupported SignerInfo version\n");
298 return -EINVAL; 319 return -EINVAL;
320version_mismatch:
321 pr_warn("SignedData-SignerInfo version mismatch\n");
322 return -EBADMSG;
299} 323}
300 324
301/* 325/*
@@ -440,6 +464,22 @@ int pkcs7_sig_note_issuer(void *context, size_t hdrlen,
440} 464}
441 465
442/* 466/*
467 * Note the issuing cert's subjectKeyIdentifier
468 */
469int pkcs7_sig_note_skid(void *context, size_t hdrlen,
470 unsigned char tag,
471 const void *value, size_t vlen)
472{
473 struct pkcs7_parse_context *ctx = context;
474
475 pr_devel("SKID: %02x %zu [%*ph]\n", tag, vlen, (unsigned)vlen, value);
476
477 ctx->raw_skid = value;
478 ctx->raw_skid_size = vlen;
479 return 0;
480}
481
482/*
443 * Note the signature data 483 * Note the signature data
444 */ 484 */
445int pkcs7_sig_note_signature(void *context, size_t hdrlen, 485int pkcs7_sig_note_signature(void *context, size_t hdrlen,
@@ -472,13 +512,21 @@ int pkcs7_note_signed_info(void *context, size_t hdrlen,
472 struct asymmetric_key_id *kid; 512 struct asymmetric_key_id *kid;
473 513
474 /* Generate cert issuer + serial number key ID */ 514 /* Generate cert issuer + serial number key ID */
475 kid = asymmetric_key_generate_id(ctx->raw_serial, 515 if (!ctx->expect_skid) {
476 ctx->raw_serial_size, 516 kid = asymmetric_key_generate_id(ctx->raw_serial,
477 ctx->raw_issuer, 517 ctx->raw_serial_size,
478 ctx->raw_issuer_size); 518 ctx->raw_issuer,
519 ctx->raw_issuer_size);
520 } else {
521 kid = asymmetric_key_generate_id(ctx->raw_skid,
522 ctx->raw_skid_size,
523 "", 0);
524 }
479 if (IS_ERR(kid)) 525 if (IS_ERR(kid))
480 return PTR_ERR(kid); 526 return PTR_ERR(kid);
481 527
528 pr_devel("SINFO KID: %u [%*phN]\n", kid->len, kid->len, kid->data);
529
482 sinfo->signing_cert_id = kid; 530 sinfo->signing_cert_id = kid;
483 sinfo->index = ++ctx->sinfo_index; 531 sinfo->index = ++ctx->sinfo_index;
484 *ctx->ppsinfo = sinfo; 532 *ctx->ppsinfo = sinfo;
diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h
index efc7dc9b8f9c..790dd7cec82c 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.h
+++ b/crypto/asymmetric_keys/pkcs7_parser.h
@@ -33,7 +33,9 @@ struct pkcs7_signed_info {
33 unsigned authattrs_len; 33 unsigned authattrs_len;
34 const void *authattrs; 34 const void *authattrs;
35 35
36 /* Issuing cert serial number and issuer's name */ 36 /* Issuing cert serial number and issuer's name [PKCS#7 or CMS ver 1]
37 * or issuing cert's SKID [CMS ver 3].
38 */
37 struct asymmetric_key_id *signing_cert_id; 39 struct asymmetric_key_id *signing_cert_id;
38 40
39 /* Message signature. 41 /* Message signature.
@@ -50,6 +52,7 @@ struct pkcs7_message {
50 struct x509_certificate *certs; /* Certificate list */ 52 struct x509_certificate *certs; /* Certificate list */
51 struct x509_certificate *crl; /* Revocation list */ 53 struct x509_certificate *crl; /* Revocation list */
52 struct pkcs7_signed_info *signed_infos; 54 struct pkcs7_signed_info *signed_infos;
55 u8 version; /* Version of cert (1 -> PKCS#7 or CMS; 3 -> CMS) */
53 56
54 /* Content Data (or NULL) */ 57 /* Content Data (or NULL) */
55 enum OID data_type; /* Type of Data */ 58 enum OID data_type; /* Type of Data */