hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/crypto/asymmetric_keys/x509_cert_parser.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* X.509 certificate parser
23 *
34 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
45 * Written by David Howells (dhowells@redhat.com)
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public Licence
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the Licence, or (at your option) any later version.
106 */
117
128 #define pr_fmt(fmt) "X.509: "fmt
....@@ -26,6 +22,9 @@
2622 const void *cert_start; /* Start of cert content */
2723 const void *key; /* Key data */
2824 size_t key_size; /* Size of key data */
25
+ const void *params; /* Key parameters */
26
+ size_t params_size; /* Size of key parameters */
27
+ enum OID key_algo; /* Public key algorithm */
2928 enum OID last_oid; /* Last OID encountered */
3029 enum OID algo_oid; /* Algorithm OID */
3130 unsigned char nr_mpi; /* Number of MPIs stored */
....@@ -108,6 +107,13 @@
108107 goto error_decode;
109108
110109 cert->pub->keylen = ctx->key_size;
110
+
111
+ cert->pub->params = kmemdup(ctx->params, ctx->params_size, GFP_KERNEL);
112
+ if (!cert->pub->params)
113
+ goto error_decode;
114
+
115
+ cert->pub->paramlen = ctx->params_size;
116
+ cert->pub->algo = ctx->key_algo;
111117
112118 /* Grab the signature bits */
113119 ret = x509_get_sig_params(cert);
....@@ -199,35 +205,54 @@
199205
200206 case OID_md4WithRSAEncryption:
201207 ctx->cert->sig->hash_algo = "md4";
202
- ctx->cert->sig->pkey_algo = "rsa";
203
- break;
208
+ goto rsa_pkcs1;
204209
205210 case OID_sha1WithRSAEncryption:
206211 ctx->cert->sig->hash_algo = "sha1";
207
- ctx->cert->sig->pkey_algo = "rsa";
208
- break;
212
+ goto rsa_pkcs1;
209213
210214 case OID_sha256WithRSAEncryption:
211215 ctx->cert->sig->hash_algo = "sha256";
212
- ctx->cert->sig->pkey_algo = "rsa";
213
- break;
216
+ goto rsa_pkcs1;
214217
215218 case OID_sha384WithRSAEncryption:
216219 ctx->cert->sig->hash_algo = "sha384";
217
- ctx->cert->sig->pkey_algo = "rsa";
218
- break;
220
+ goto rsa_pkcs1;
219221
220222 case OID_sha512WithRSAEncryption:
221223 ctx->cert->sig->hash_algo = "sha512";
222
- ctx->cert->sig->pkey_algo = "rsa";
223
- break;
224
+ goto rsa_pkcs1;
224225
225226 case OID_sha224WithRSAEncryption:
226227 ctx->cert->sig->hash_algo = "sha224";
227
- ctx->cert->sig->pkey_algo = "rsa";
228
- break;
228
+ goto rsa_pkcs1;
229
+
230
+ case OID_gost2012Signature256:
231
+ ctx->cert->sig->hash_algo = "streebog256";
232
+ goto ecrdsa;
233
+
234
+ case OID_gost2012Signature512:
235
+ ctx->cert->sig->hash_algo = "streebog512";
236
+ goto ecrdsa;
237
+
238
+ case OID_SM2_with_SM3:
239
+ ctx->cert->sig->hash_algo = "sm3";
240
+ goto sm2;
229241 }
230242
243
+rsa_pkcs1:
244
+ ctx->cert->sig->pkey_algo = "rsa";
245
+ ctx->cert->sig->encoding = "pkcs1";
246
+ ctx->algo_oid = ctx->last_oid;
247
+ return 0;
248
+ecrdsa:
249
+ ctx->cert->sig->pkey_algo = "ecrdsa";
250
+ ctx->cert->sig->encoding = "raw";
251
+ ctx->algo_oid = ctx->last_oid;
252
+ return 0;
253
+sm2:
254
+ ctx->cert->sig->pkey_algo = "sm2";
255
+ ctx->cert->sig->encoding = "raw";
231256 ctx->algo_oid = ctx->last_oid;
232257 return 0;
233258 }
....@@ -249,7 +274,9 @@
249274 return -EINVAL;
250275 }
251276
252
- if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0) {
277
+ if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0 ||
278
+ strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0 ||
279
+ strcmp(ctx->cert->sig->pkey_algo, "sm2") == 0) {
253280 /* Discard the BIT STRING metadata */
254281 if (vlen < 1 || *(const u8 *)value != 0)
255282 return -EBADMSG;
....@@ -404,6 +431,27 @@
404431 }
405432
406433 /*
434
+ * Extract the parameters for the public key
435
+ */
436
+int x509_note_params(void *context, size_t hdrlen,
437
+ unsigned char tag,
438
+ const void *value, size_t vlen)
439
+{
440
+ struct x509_parse_context *ctx = context;
441
+
442
+ /*
443
+ * AlgorithmIdentifier is used three times in the x509, we should skip
444
+ * first and ignore third, using second one which is after subject and
445
+ * before subjectPublicKey.
446
+ */
447
+ if (!ctx->cert->raw_subject || ctx->key)
448
+ return 0;
449
+ ctx->params = value - hdrlen;
450
+ ctx->params_size = vlen + hdrlen;
451
+ return 0;
452
+}
453
+
454
+/*
407455 * Extract the data for the public key algorithm
408456 */
409457 int x509_extract_key_data(void *context, size_t hdrlen,
....@@ -412,10 +460,21 @@
412460 {
413461 struct x509_parse_context *ctx = context;
414462
415
- if (ctx->last_oid != OID_rsaEncryption)
463
+ ctx->key_algo = ctx->last_oid;
464
+ switch (ctx->last_oid) {
465
+ case OID_rsaEncryption:
466
+ ctx->cert->pub->pkey_algo = "rsa";
467
+ break;
468
+ case OID_gost2012PKey256:
469
+ case OID_gost2012PKey512:
470
+ ctx->cert->pub->pkey_algo = "ecrdsa";
471
+ break;
472
+ case OID_id_ecPublicKey:
473
+ ctx->cert->pub->pkey_algo = "sm2";
474
+ break;
475
+ default:
416476 return -ENOPKG;
417
-
418
- ctx->cert->pub->pkey_algo = "rsa";
477
+ }
419478
420479 /* Discard the BIT STRING metadata */
421480 if (vlen < 1 || *(const u8 *)value != 0)