Browse Source

[crypto] Generalise asn1_{digest,pubkey,signature}_algorithm()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
7deb610881
4 changed files with 137 additions and 108 deletions
  1. 107
    8
      src/crypto/asn1.c
  2. 9
    32
      src/crypto/cms.c
  3. 13
    66
      src/crypto/x509.c
  4. 8
    2
      src/include/ipxe/asn1.h

+ 107
- 8
src/crypto/asn1.c View File

@@ -58,6 +58,18 @@ FILE_LICENCE ( GPL2_OR_LATER );
58 58
 	__einfo_error ( EINFO_EINVAL_ASN1_TIME )
59 59
 #define EINFO_EINVAL_ASN1_TIME \
60 60
 	__einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid time" )
61
+#define EINVAL_ASN1_ALGORITHM \
62
+	__einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )
63
+#define EINFO_EINVAL_ASN1_ALGORITHM \
64
+	__einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid algorithm" )
65
+#define ENOTSUP_ALGORITHM \
66
+	__einfo_error ( EINFO_ENOTSUP_ALGORITHM )
67
+#define EINFO_ENOTSUP_ALGORITHM \
68
+	__einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported algorithm" )
69
+#define ENOTTY_ALGORITHM \
70
+	__einfo_error ( EINFO_ENOTTY_ALGORITHM )
71
+#define EINFO_ENOTTY_ALGORITHM \
72
+	__einfo_uniqify ( EINFO_ENOTTY, 0x01, "Inappropriate algorithm" )
61 73
 
62 74
 /**
63 75
  * Invalidate ASN.1 object cursor
@@ -377,11 +389,12 @@ asn1_find_algorithm ( const struct asn1_cursor *cursor ) {
377 389
  * Parse ASN.1 OID-identified algorithm
378 390
  *
379 391
  * @v cursor		ASN.1 object cursor
380
- * @ret algorithm	Algorithm, or NULL
392
+ * @ret algorithm	Algorithm
393
+ * @ret rc		Return status code
381 394
  */
382
-struct asn1_algorithm * asn1_algorithm ( const struct asn1_cursor *cursor ) {
395
+int asn1_algorithm ( const struct asn1_cursor *cursor,
396
+		     struct asn1_algorithm **algorithm ) {
383 397
 	struct asn1_cursor contents;
384
-	struct asn1_algorithm *algorithm;
385 398
 	int rc;
386 399
 
387 400
 	/* Enter signatureAlgorithm */
@@ -393,18 +406,104 @@ struct asn1_algorithm * asn1_algorithm ( const struct asn1_cursor *cursor ) {
393 406
 		DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
394 407
 		       cursor );
395 408
 		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
396
-		return NULL;
409
+		return -EINVAL_ASN1_ALGORITHM;
397 410
 	}
398 411
 
399 412
 	/* Identify algorithm */
400
-	algorithm = asn1_find_algorithm ( &contents );
401
-	if ( ! algorithm ) {
413
+	*algorithm = asn1_find_algorithm ( &contents );
414
+	if ( ! *algorithm ) {
402 415
 		DBGC ( cursor, "ASN1 %p unrecognised algorithm:\n", cursor );
403 416
 		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
404
-		return NULL;
417
+		return -ENOTSUP_ALGORITHM;
418
+	}
419
+
420
+	return 0;
421
+}
422
+
423
+/**
424
+ * Parse ASN.1 OID-identified public-key algorithm
425
+ *
426
+ * @v cursor		ASN.1 object cursor
427
+ * @ret algorithm	Algorithm
428
+ * @ret rc		Return status code
429
+ */
430
+int asn1_pubkey_algorithm ( const struct asn1_cursor *cursor,
431
+			    struct asn1_algorithm **algorithm ) {
432
+	int rc;
433
+
434
+	/* Parse algorithm */
435
+	if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
436
+		return rc;
437
+
438
+	/* Check algorithm has a public key */
439
+	if ( ! (*algorithm)->pubkey ) {
440
+		DBGC ( cursor, "ASN1 %p algorithm %s is not a public-key "
441
+		       "algorithm:\n", cursor, (*algorithm)->name );
442
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
443
+		return -ENOTTY_ALGORITHM;
444
+	}
445
+
446
+	return 0;
447
+}
448
+
449
+/**
450
+ * Parse ASN.1 OID-identified digest algorithm
451
+ *
452
+ * @v cursor		ASN.1 object cursor
453
+ * @ret algorithm	Algorithm
454
+ * @ret rc		Return status code
455
+ */
456
+int asn1_digest_algorithm ( const struct asn1_cursor *cursor,
457
+			    struct asn1_algorithm **algorithm ) {
458
+	int rc;
459
+
460
+	/* Parse algorithm */
461
+	if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
462
+		return rc;
463
+
464
+	/* Check algorithm has a digest */
465
+	if ( ! (*algorithm)->digest ) {
466
+		DBGC ( cursor, "ASN1 %p algorithm %s is not a digest "
467
+		       "algorithm:\n", cursor, (*algorithm)->name );
468
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
469
+		return -ENOTTY_ALGORITHM;
470
+	}
471
+
472
+	return 0;
473
+}
474
+
475
+/**
476
+ * Parse ASN.1 OID-identified signature algorithm
477
+ *
478
+ * @v cursor		ASN.1 object cursor
479
+ * @ret algorithm	Algorithm
480
+ * @ret rc		Return status code
481
+ */
482
+int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
483
+			       struct asn1_algorithm **algorithm ) {
484
+	int rc;
485
+
486
+	/* Parse algorithm */
487
+	if ( ( rc = asn1_algorithm ( cursor, algorithm ) ) != 0 )
488
+		return rc;
489
+
490
+	/* Check algorithm has a public key */
491
+	if ( ! (*algorithm)->pubkey ) {
492
+		DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
493
+		       "algorithm:\n", cursor, (*algorithm)->name );
494
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
495
+		return -ENOTTY_ALGORITHM;
496
+	}
497
+
498
+	/* Check algorithm has a digest */
499
+	if ( ! (*algorithm)->digest ) {
500
+		DBGC ( cursor, "ASN1 %p algorithm %s is not a signature "
501
+		       "algorithm:\n", cursor, (*algorithm)->name );
502
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
503
+		return -ENOTTY_ALGORITHM;
405 504
 	}
406 505
 
407
-	return algorithm;
506
+	return 0;
408 507
 }
409 508
 
410 509
 /**

+ 9
- 32
src/crypto/cms.c View File

@@ -65,15 +65,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
65 65
 	__einfo_error ( EINFO_ENOTSUP_SIGNEDDATA )
66 66
 #define EINFO_ENOTSUP_SIGNEDDATA \
67 67
 	__einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Not a digital signature" )
68
-#define ENOTSUP_DIGEST \
69
-	__einfo_error ( EINFO_ENOTSUP_DIGEST )
70
-#define EINFO_ENOTSUP_DIGEST \
71
-	__einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported digest algorithm" )
72
-#define ENOTSUP_PUBKEY \
73
-	__einfo_error ( EINFO_ENOTSUP_PUBKEY )
74
-#define EINFO_ENOTSUP_PUBKEY					\
75
-	__einfo_uniqify ( EINFO_ENOTSUP, 0x03,			\
76
-			  "Unsupported public-key algorithm" )
77 68
 
78 69
 /** "pkcs7-signedData" object identifier */
79 70
 static uint8_t oid_signeddata[] = { ASN1_OID_SIGNEDDATA };
@@ -257,21 +248,14 @@ static int cms_parse_digest_algorithm ( struct cms_signature *sig,
257 248
 					struct cms_signer_info *info,
258 249
 					const struct asn1_cursor *raw ) {
259 250
 	struct asn1_algorithm *algorithm;
251
+	int rc;
260 252
 
261 253
 	/* Identify algorithm */
262
-	algorithm = asn1_algorithm ( raw );
263
-	if ( ! algorithm ) {
264
-		DBGC ( sig, "CMS %p/%p could not identify digest algorithm:\n",
265
-		       sig, info );
254
+	if ( ( rc = asn1_digest_algorithm ( raw, &algorithm ) ) != 0 ) {
255
+		DBGC ( sig, "CMS %p/%p could not identify digest algorithm: "
256
+		       "%s\n", sig, info, strerror ( rc ) );
266 257
 		DBGC_HDA ( sig, 0, raw->data, raw->len );
267
-		return -ENOTSUP_DIGEST;
268
-	}
269
-
270
-	/* Check algorithm is a digest algorithm */
271
-	if ( ! algorithm->digest ) {
272
-		DBGC ( sig, "CMS %p/%p algorithm %s is not a digest "
273
-		       "algorithm\n", sig, info, algorithm->name );
274
-		return -EINVAL_DIGEST;
258
+		return rc;
275 259
 	}
276 260
 
277 261
 	/* Record digest algorithm */
@@ -294,21 +278,14 @@ static int cms_parse_signature_algorithm ( struct cms_signature *sig,
294 278
 					   struct cms_signer_info *info,
295 279
 					   const struct asn1_cursor *raw ) {
296 280
 	struct asn1_algorithm *algorithm;
281
+	int rc;
297 282
 
298 283
 	/* Identify algorithm */
299
-	algorithm = asn1_algorithm ( raw );
300
-	if ( ! algorithm ) {
284
+	if ( ( rc = asn1_pubkey_algorithm ( raw, &algorithm ) ) != 0 ) {
301 285
 		DBGC ( sig, "CMS %p/%p could not identify public-key "
302
-		       "algorithm:\n", sig, info );
286
+		       "algorithm: %s\n", sig, info, strerror ( rc ) );
303 287
 		DBGC_HDA ( sig, 0, raw->data, raw->len );
304
-		return -ENOTSUP_PUBKEY;
305
-	}
306
-
307
-	/* Check algorithm is a signature algorithm */
308
-	if ( ! algorithm->pubkey ) {
309
-		DBGC ( sig, "CMS %p/%p algorithm %s is not a public-key "
310
-		       "algorithm\n", sig, info, algorithm->name );
311
-		return -EINVAL_PUBKEY;
288
+		return rc;
312 289
 	}
313 290
 
314 291
 	/* Record signature algorithm */

+ 13
- 66
src/crypto/x509.c View File

@@ -154,66 +154,6 @@ static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
154 154
 static struct asn1_cursor oid_common_name_cursor =
155 155
 	ASN1_OID_CURSOR ( oid_common_name );
156 156
 
157
-/**
158
- * Parse X.509 certificate algorithm
159
- *
160
- * @v cert		X.509 certificate
161
- * @v algorithm		Algorithm to fill in
162
- * @v raw		ASN.1 cursor
163
- * @ret rc		Return status code
164
- */
165
-static int x509_parse_pubkey_algorithm ( struct x509_certificate *cert,
166
-					 struct asn1_algorithm **algorithm,
167
-					 const struct asn1_cursor *raw ) {
168
-
169
-	/* Parse algorithm */
170
-	*algorithm = asn1_algorithm ( raw );
171
-	if ( ! (*algorithm) ) {
172
-		DBGC ( cert, "X509 %p unrecognised algorithm:\n", cert );
173
-		DBGC_HDA ( cert, 0, raw->data, raw->len );
174
-		return -ENOTSUP_ALGORITHM;
175
-	}
176
-
177
-	/* Check algorithm has a public key */
178
-	if ( ! (*algorithm)->pubkey ) {
179
-		DBGC ( cert, "X509 %p algorithm %s is not a public-key "
180
-		       "algorithm:\n", cert, (*algorithm)->name );
181
-		DBGC_HDA ( cert, 0, raw->data, raw->len );
182
-		return -EINVAL_ALGORITHM;
183
-	}
184
-
185
-	return 0;
186
-}
187
-
188
-/**
189
- * Parse X.509 certificate signature algorithm
190
- *
191
- * @v cert		X.509 certificate
192
- * @v algorithm		Algorithm to fill in
193
- * @v raw		ASN.1 cursor
194
- * @ret rc		Return status code
195
- */
196
-static int x509_parse_signature_algorithm ( struct x509_certificate *cert,
197
-					    struct asn1_algorithm **algorithm,
198
-					    const struct asn1_cursor *raw ) {
199
-	int rc;
200
-
201
-	/* Parse algorithm */
202
-	if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
203
-						  raw ) ) != 0 )
204
-		return rc;
205
-
206
-	/* Check algorithm is a signature algorithm */
207
-	if ( ! (*algorithm)->digest ) {
208
-		DBGC ( cert, "X509 %p algorithm %s is not a signature "
209
-		       "algorithm:\n", cert, (*algorithm)->name );
210
-		DBGC_HDA ( cert, 0, raw->data, raw->len );
211
-		return -EINVAL_ALGORITHM;
212
-	}
213
-
214
-	return 0;
215
-}
216
-
217 157
 /**
218 158
  * Parse X.509 certificate bit string
219 159
  *
@@ -541,9 +481,11 @@ static int x509_parse_public_key ( struct x509_certificate *cert,
541 481
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
542 482
 
543 483
 	/* Parse algorithm */
544
-	if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
545
-						  &cursor ) ) != 0 )
484
+	if ( ( rc = asn1_pubkey_algorithm ( &cursor, algorithm ) ) != 0 ) {
485
+		DBGC ( cert, "X509 %p could not parse public key algorithm: "
486
+		       "%s\n", cert, strerror ( rc ) );
546 487
 		return rc;
488
+	}
547 489
 	DBGC2 ( cert, "X509 %p public key algorithm is %s\n",
548 490
 		cert, (*algorithm)->name );
549 491
 	asn1_skip_any ( &cursor );
@@ -1045,9 +987,11 @@ static int x509_parse_tbscertificate ( struct x509_certificate *cert,
1045 987
 	asn1_skip_any ( &cursor );
1046 988
 
1047 989
 	/* Parse signature */
1048
-	if ( ( rc = x509_parse_signature_algorithm ( cert, algorithm,
1049
-						     &cursor ) ) != 0 )
990
+	if ( ( rc = asn1_signature_algorithm ( &cursor, algorithm ) ) != 0 ) {
991
+		DBGC ( cert, "X509 %p could not parse signature algorithm: "
992
+		       "%s\n", cert, strerror ( rc ) );
1050 993
 		return rc;
994
+	}
1051 995
 	DBGC2 ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
1052 996
 		cert, (*algorithm)->name );
1053 997
 	asn1_skip_any ( &cursor );
@@ -1107,9 +1051,12 @@ static int x509_parse ( struct x509_certificate *cert,
1107 1051
 	asn1_skip_any ( &cursor );
1108 1052
 
1109 1053
 	/* Parse signatureAlgorithm */
1110
-	if ( ( rc = x509_parse_signature_algorithm ( cert, signature_algorithm,
1111
-						     &cursor ) ) != 0 )
1054
+	if ( ( rc = asn1_signature_algorithm ( &cursor,
1055
+					       signature_algorithm ) ) != 0 ) {
1056
+		DBGC ( cert, "X509 %p could not parse signature algorithm: "
1057
+		       "%s\n", cert, strerror ( rc ) );
1112 1058
 		return rc;
1059
+	}
1113 1060
 	DBGC2 ( cert, "X509 %p signatureAlgorithm is %s\n",
1114 1061
 		cert, (*signature_algorithm)->name );
1115 1062
 	asn1_skip_any ( &cursor );

+ 8
- 2
src/include/ipxe/asn1.h View File

@@ -238,8 +238,14 @@ extern int asn1_boolean ( const struct asn1_cursor *cursor );
238 238
 extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
239 239
 extern int asn1_compare ( const struct asn1_cursor *cursor1,
240 240
 			  const struct asn1_cursor *cursor2 );
241
-extern struct asn1_algorithm *
242
-asn1_algorithm ( const struct asn1_cursor *cursor );
241
+extern int asn1_algorithm ( const struct asn1_cursor *cursor,
242
+			    struct asn1_algorithm **algorithm );
243
+extern int asn1_pubkey_algorithm ( const struct asn1_cursor *cursor,
244
+				   struct asn1_algorithm **algorithm );
245
+extern int asn1_digest_algorithm ( const struct asn1_cursor *cursor,
246
+				   struct asn1_algorithm **algorithm );
247
+extern int asn1_signature_algorithm ( const struct asn1_cursor *cursor,
248
+				      struct asn1_algorithm **algorithm );
243 249
 extern int asn1_generalized_time ( const struct asn1_cursor *cursor,
244 250
 				   time_t *time );
245 251
 

Loading…
Cancel
Save