summaryrefslogtreecommitdiffstats
path: root/crypto/asymmetric_keys
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/asymmetric_keys')
-rw-r--r--crypto/asymmetric_keys/Makefile8
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c4
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c12
-rw-r--r--crypto/asymmetric_keys/x509_akid.asn135
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c142
-rw-r--r--crypto/asymmetric_keys/x509_parser.h5
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c8
7 files changed, 145 insertions, 69 deletions
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index e47fcd9ac5e8..cd1406f9b14a 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -15,15 +15,21 @@ obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
15obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o 15obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
16x509_key_parser-y := \ 16x509_key_parser-y := \
17 x509-asn1.o \ 17 x509-asn1.o \
18 x509_akid-asn1.o \
18 x509_rsakey-asn1.o \ 19 x509_rsakey-asn1.o \
19 x509_cert_parser.o \ 20 x509_cert_parser.o \
20 x509_public_key.o 21 x509_public_key.o
21 22
22$(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h $(obj)/x509_rsakey-asn1.h 23$(obj)/x509_cert_parser.o: \
24 $(obj)/x509-asn1.h \
25 $(obj)/x509_akid-asn1.h \
26 $(obj)/x509_rsakey-asn1.h
23$(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h 27$(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h
28$(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h
24$(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h 29$(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h
25 30
26clean-files += x509-asn1.c x509-asn1.h 31clean-files += x509-asn1.c x509-asn1.h
32clean-files += x509_akid-asn1.c x509_akid-asn1.h
27clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h 33clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h
28 34
29# 35#
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 1d29376072da..0f6463b6692b 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -85,8 +85,8 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
85 /* No match - see if the root certificate has a signer amongst the 85 /* No match - see if the root certificate has a signer amongst the
86 * trusted keys. 86 * trusted keys.
87 */ 87 */
88 if (last && last->authority) { 88 if (last && last->akid_skid) {
89 key = x509_request_asymmetric_key(trust_keyring, last->authority, 89 key = x509_request_asymmetric_key(trust_keyring, last->akid_skid,
90 false); 90 false);
91 if (!IS_ERR(key)) { 91 if (!IS_ERR(key)) {
92 x509 = last; 92 x509 = last;
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index cd455450b069..a4d083f7e9e1 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -187,11 +187,11 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
187 goto maybe_missing_crypto_in_x509; 187 goto maybe_missing_crypto_in_x509;
188 188
189 pr_debug("- issuer %s\n", x509->issuer); 189 pr_debug("- issuer %s\n", x509->issuer);
190 if (x509->authority) 190 if (x509->akid_skid)
191 pr_debug("- authkeyid %*phN\n", 191 pr_debug("- authkeyid %*phN\n",
192 x509->authority->len, x509->authority->data); 192 x509->akid_skid->len, x509->akid_skid->data);
193 193
194 if (!x509->authority || 194 if (!x509->akid_skid ||
195 strcmp(x509->subject, x509->issuer) == 0) { 195 strcmp(x509->subject, x509->issuer) == 0) {
196 /* If there's no authority certificate specified, then 196 /* If there's no authority certificate specified, then
197 * the certificate must be self-signed and is the root 197 * the certificate must be self-signed and is the root
@@ -216,13 +216,13 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
216 * list to see if the next one is there. 216 * list to see if the next one is there.
217 */ 217 */
218 pr_debug("- want %*phN\n", 218 pr_debug("- want %*phN\n",
219 x509->authority->len, x509->authority->data); 219 x509->akid_skid->len, x509->akid_skid->data);
220 for (p = pkcs7->certs; p; p = p->next) { 220 for (p = pkcs7->certs; p; p = p->next) {
221 if (!p->skid) 221 if (!p->skid)
222 continue; 222 continue;
223 pr_debug("- cmp [%u] %*phN\n", 223 pr_debug("- cmp [%u] %*phN\n",
224 p->index, p->skid->len, p->skid->data); 224 p->index, p->skid->len, p->skid->data);
225 if (asymmetric_key_id_same(p->skid, x509->authority)) 225 if (asymmetric_key_id_same(p->skid, x509->akid_skid))
226 goto found_issuer; 226 goto found_issuer;
227 } 227 }
228 228
@@ -338,8 +338,6 @@ int pkcs7_verify(struct pkcs7_message *pkcs7)
338 ret = x509_get_sig_params(x509); 338 ret = x509_get_sig_params(x509);
339 if (ret < 0) 339 if (ret < 0)
340 return ret; 340 return ret;
341 pr_debug("X.509[%u] %*phN\n",
342 n, x509->authority->len, x509->authority->data);
343 } 341 }
344 342
345 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) { 343 for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
diff --git a/crypto/asymmetric_keys/x509_akid.asn1 b/crypto/asymmetric_keys/x509_akid.asn1
new file mode 100644
index 000000000000..1a33231a75a8
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_akid.asn1
@@ -0,0 +1,35 @@
1-- X.509 AuthorityKeyIdentifier
2-- rfc5280 section 4.2.1.1
3
4AuthorityKeyIdentifier ::= SEQUENCE {
5 keyIdentifier [0] IMPLICIT KeyIdentifier OPTIONAL,
6 authorityCertIssuer [1] IMPLICIT GeneralNames OPTIONAL,
7 authorityCertSerialNumber [2] IMPLICIT CertificateSerialNumber OPTIONAL
8 }
9
10KeyIdentifier ::= OCTET STRING ({ x509_akid_note_kid })
11
12CertificateSerialNumber ::= INTEGER ({ x509_akid_note_serial })
13
14GeneralNames ::= SEQUENCE OF GeneralName
15
16GeneralName ::= CHOICE {
17 otherName [0] ANY,
18 rfc822Name [1] IA5String,
19 dNSName [2] IA5String,
20 x400Address [3] ANY,
21 directoryName [4] Name ({ x509_akid_note_name }),
22 ediPartyName [5] ANY,
23 uniformResourceIdentifier [6] IA5String,
24 iPAddress [7] OCTET STRING,
25 registeredID [8] OBJECT IDENTIFIER
26 }
27
28Name ::= SEQUENCE OF RelativeDistinguishedName
29
30RelativeDistinguishedName ::= SET OF AttributeValueAssertion
31
32AttributeValueAssertion ::= SEQUENCE {
33 attributeType OBJECT IDENTIFIER ({ x509_note_OID }),
34 attributeValue ANY ({ x509_extract_name_segment })
35 }
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index a668d90302d3..6c130dd56f35 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -18,6 +18,7 @@
18#include "public_key.h" 18#include "public_key.h"
19#include "x509_parser.h" 19#include "x509_parser.h"
20#include "x509-asn1.h" 20#include "x509-asn1.h"
21#include "x509_akid-asn1.h"
21#include "x509_rsakey-asn1.h" 22#include "x509_rsakey-asn1.h"
22 23
23struct x509_parse_context { 24struct x509_parse_context {
@@ -35,6 +36,10 @@ struct x509_parse_context {
35 u16 o_offset; /* Offset of organizationName (O) */ 36 u16 o_offset; /* Offset of organizationName (O) */
36 u16 cn_offset; /* Offset of commonName (CN) */ 37 u16 cn_offset; /* Offset of commonName (CN) */
37 u16 email_offset; /* Offset of emailAddress */ 38 u16 email_offset; /* Offset of emailAddress */
39 unsigned raw_akid_size;
40 const void *raw_akid; /* Raw authorityKeyId in ASN.1 */
41 const void *akid_raw_issuer; /* Raw directoryName in authorityKeyId */
42 unsigned akid_raw_issuer_size;
38}; 43};
39 44
40/* 45/*
@@ -48,7 +53,8 @@ void x509_free_certificate(struct x509_certificate *cert)
48 kfree(cert->subject); 53 kfree(cert->subject);
49 kfree(cert->id); 54 kfree(cert->id);
50 kfree(cert->skid); 55 kfree(cert->skid);
51 kfree(cert->authority); 56 kfree(cert->akid_id);
57 kfree(cert->akid_skid);
52 kfree(cert->sig.digest); 58 kfree(cert->sig.digest);
53 mpi_free(cert->sig.rsa.s); 59 mpi_free(cert->sig.rsa.s);
54 kfree(cert); 60 kfree(cert);
@@ -85,6 +91,18 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
85 if (ret < 0) 91 if (ret < 0)
86 goto error_decode; 92 goto error_decode;
87 93
94 /* Decode the AuthorityKeyIdentifier */
95 if (ctx->raw_akid) {
96 pr_devel("AKID: %u %*phN\n",
97 ctx->raw_akid_size, ctx->raw_akid_size, ctx->raw_akid);
98 ret = asn1_ber_decoder(&x509_akid_decoder, ctx,
99 ctx->raw_akid, ctx->raw_akid_size);
100 if (ret < 0) {
101 pr_warn("Couldn't decode AuthKeyIdentifier\n");
102 goto error_decode;
103 }
104 }
105
88 /* Decode the public key */ 106 /* Decode the public key */
89 ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx, 107 ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx,
90 ctx->key, ctx->key_size); 108 ctx->key, ctx->key_size);
@@ -422,7 +440,6 @@ int x509_process_extension(void *context, size_t hdrlen,
422 struct x509_parse_context *ctx = context; 440 struct x509_parse_context *ctx = context;
423 struct asymmetric_key_id *kid; 441 struct asymmetric_key_id *kid;
424 const unsigned char *v = value; 442 const unsigned char *v = value;
425 int i;
426 443
427 pr_debug("Extension: %u\n", ctx->last_oid); 444 pr_debug("Extension: %u\n", ctx->last_oid);
428 445
@@ -449,57 +466,8 @@ int x509_process_extension(void *context, size_t hdrlen,
449 466
450 if (ctx->last_oid == OID_authorityKeyIdentifier) { 467 if (ctx->last_oid == OID_authorityKeyIdentifier) {
451 /* Get hold of the CA key fingerprint */ 468 /* Get hold of the CA key fingerprint */
452 if (ctx->cert->authority || vlen < 5) 469 ctx->raw_akid = v;
453 return -EBADMSG; 470 ctx->raw_akid_size = vlen;
454
455 /* Authority Key Identifier must be a Constructed SEQUENCE */
456 if (v[0] != (ASN1_SEQ | (ASN1_CONS << 5)))
457 return -EBADMSG;
458
459 /* Authority Key Identifier is not indefinite length */
460 if (unlikely(vlen == ASN1_INDEFINITE_LENGTH))
461 return -EBADMSG;
462
463 if (vlen < ASN1_INDEFINITE_LENGTH) {
464 /* Short Form length */
465 if (v[1] != vlen - 2 ||
466 v[2] != SEQ_TAG_KEYID ||
467 v[3] > vlen - 4)
468 return -EBADMSG;
469
470 vlen = v[3];
471 v += 4;
472 } else {
473 /* Long Form length */
474 size_t seq_len = 0;
475 size_t sub = v[1] - ASN1_INDEFINITE_LENGTH;
476
477 if (sub > 2)
478 return -EBADMSG;
479
480 /* calculate the length from subsequent octets */
481 v += 2;
482 for (i = 0; i < sub; i++) {
483 seq_len <<= 8;
484 seq_len |= v[i];
485 }
486
487 if (seq_len != vlen - 2 - sub ||
488 v[sub] != SEQ_TAG_KEYID ||
489 v[sub + 1] > vlen - 4 - sub)
490 return -EBADMSG;
491
492 vlen = v[sub + 1];
493 v += (sub + 2);
494 }
495
496 kid = asymmetric_key_generate_id(ctx->cert->raw_issuer,
497 ctx->cert->raw_issuer_size,
498 v, vlen);
499 if (IS_ERR(kid))
500 return PTR_ERR(kid);
501 pr_debug("authkeyid %*phN\n", kid->len, kid->data);
502 ctx->cert->authority = kid;
503 return 0; 471 return 0;
504 } 472 }
505 473
@@ -569,3 +537,71 @@ int x509_note_not_after(void *context, size_t hdrlen,
569 struct x509_parse_context *ctx = context; 537 struct x509_parse_context *ctx = context;
570 return x509_note_time(&ctx->cert->valid_to, hdrlen, tag, value, vlen); 538 return x509_note_time(&ctx->cert->valid_to, hdrlen, tag, value, vlen);
571} 539}
540
541/*
542 * Note a key identifier-based AuthorityKeyIdentifier
543 */
544int x509_akid_note_kid(void *context, size_t hdrlen,
545 unsigned char tag,
546 const void *value, size_t vlen)
547{
548 struct x509_parse_context *ctx = context;
549 struct asymmetric_key_id *kid;
550
551 pr_debug("AKID: keyid: %*phN\n", (int)vlen, value);
552
553 if (ctx->cert->akid_skid)
554 return 0;
555
556 kid = asymmetric_key_generate_id(ctx->cert->raw_issuer,
557 ctx->cert->raw_issuer_size,
558 value, vlen);
559 if (IS_ERR(kid))
560 return PTR_ERR(kid);
561 pr_debug("authkeyid %*phN\n", kid->len, kid->data);
562 ctx->cert->akid_skid = kid;
563 return 0;
564}
565
566/*
567 * Note a directoryName in an AuthorityKeyIdentifier
568 */
569int x509_akid_note_name(void *context, size_t hdrlen,
570 unsigned char tag,
571 const void *value, size_t vlen)
572{
573 struct x509_parse_context *ctx = context;
574
575 pr_debug("AKID: name: %*phN\n", (int)vlen, value);
576
577 ctx->akid_raw_issuer = value;
578 ctx->akid_raw_issuer_size = vlen;
579 return 0;
580}
581
582/*
583 * Note a serial number in an AuthorityKeyIdentifier
584 */
585int x509_akid_note_serial(void *context, size_t hdrlen,
586 unsigned char tag,
587 const void *value, size_t vlen)
588{
589 struct x509_parse_context *ctx = context;
590 struct asymmetric_key_id *kid;
591
592 pr_debug("AKID: serial: %*phN\n", (int)vlen, value);
593
594 if (!ctx->akid_raw_issuer || ctx->cert->akid_id)
595 return 0;
596
597 kid = asymmetric_key_generate_id(value,
598 vlen,
599 ctx->akid_raw_issuer,
600 ctx->akid_raw_issuer_size);
601 if (IS_ERR(kid))
602 return PTR_ERR(kid);
603
604 pr_debug("authkeyid %*phN\n", kid->len, kid->data);
605 ctx->cert->akid_id = kid;
606 return 0;
607}
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index 3dfe6b5d6f0b..dcdb5c94f514 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -19,9 +19,10 @@ struct x509_certificate {
19 struct public_key_signature sig; /* Signature parameters */ 19 struct public_key_signature sig; /* Signature parameters */
20 char *issuer; /* Name of certificate issuer */ 20 char *issuer; /* Name of certificate issuer */
21 char *subject; /* Name of certificate subject */ 21 char *subject; /* Name of certificate subject */
22 struct asymmetric_key_id *id; /* Serial number + issuer */ 22 struct asymmetric_key_id *id; /* Issuer + Serial number */
23 struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */ 23 struct asymmetric_key_id *skid; /* Subject + subjectKeyId (optional) */
24 struct asymmetric_key_id *authority; /* Authority key identifier (optional) */ 24 struct asymmetric_key_id *akid_id; /* CA AuthKeyId matching ->id (optional) */
25 struct asymmetric_key_id *akid_skid; /* CA AuthKeyId matching ->skid (optional) */
25 struct tm valid_from; 26 struct tm valid_from;
26 struct tm valid_to; 27 struct tm valid_to;
27 const void *tbs; /* Signed data */ 28 const void *tbs; /* Signed data */
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 24f17e6c5904..bb55d6074d5f 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -227,10 +227,10 @@ static int x509_validate_trust(struct x509_certificate *cert,
227 if (!trust_keyring) 227 if (!trust_keyring)
228 return -EOPNOTSUPP; 228 return -EOPNOTSUPP;
229 229
230 if (ca_keyid && !asymmetric_key_id_partial(cert->authority, ca_keyid)) 230 if (ca_keyid && !asymmetric_key_id_partial(cert->akid_skid, ca_keyid))
231 return -EPERM; 231 return -EPERM;
232 232
233 key = x509_request_asymmetric_key(trust_keyring, cert->authority, 233 key = x509_request_asymmetric_key(trust_keyring, cert->akid_skid,
234 false); 234 false);
235 if (!IS_ERR(key)) { 235 if (!IS_ERR(key)) {
236 if (!use_builtin_keys 236 if (!use_builtin_keys
@@ -287,8 +287,8 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
287 cert->pub->id_type = PKEY_ID_X509; 287 cert->pub->id_type = PKEY_ID_X509;
288 288
289 /* Check the signature on the key if it appears to be self-signed */ 289 /* Check the signature on the key if it appears to be self-signed */
290 if (!cert->authority || 290 if (!cert->akid_skid ||
291 asymmetric_key_id_same(cert->skid, cert->authority)) { 291 asymmetric_key_id_same(cert->skid, cert->akid_skid)) {
292 ret = x509_check_signature(cert->pub, cert); /* self-signed */ 292 ret = x509_check_signature(cert->pub, cert); /* self-signed */
293 if (ret < 0) 293 if (ret < 0)
294 goto error_free_cert; 294 goto error_free_cert;