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
 	__einfo_error ( EINFO_EINVAL_ASN1_TIME )
58
 	__einfo_error ( EINFO_EINVAL_ASN1_TIME )
59
 #define EINFO_EINVAL_ASN1_TIME \
59
 #define EINFO_EINVAL_ASN1_TIME \
60
 	__einfo_uniqify ( EINFO_EINVAL, 0x05, "Invalid time" )
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
  * Invalidate ASN.1 object cursor
75
  * Invalidate ASN.1 object cursor
377
  * Parse ASN.1 OID-identified algorithm
389
  * Parse ASN.1 OID-identified algorithm
378
  *
390
  *
379
  * @v cursor		ASN.1 object cursor
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
 	struct asn1_cursor contents;
397
 	struct asn1_cursor contents;
384
-	struct asn1_algorithm *algorithm;
385
 	int rc;
398
 	int rc;
386
 
399
 
387
 	/* Enter signatureAlgorithm */
400
 	/* Enter signatureAlgorithm */
393
 		DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
406
 		DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
394
 		       cursor );
407
 		       cursor );
395
 		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
408
 		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
396
-		return NULL;
409
+		return -EINVAL_ASN1_ALGORITHM;
397
 	}
410
 	}
398
 
411
 
399
 	/* Identify algorithm */
412
 	/* Identify algorithm */
400
-	algorithm = asn1_find_algorithm ( &contents );
401
-	if ( ! algorithm ) {
413
+	*algorithm = asn1_find_algorithm ( &contents );
414
+	if ( ! *algorithm ) {
402
 		DBGC ( cursor, "ASN1 %p unrecognised algorithm:\n", cursor );
415
 		DBGC ( cursor, "ASN1 %p unrecognised algorithm:\n", cursor );
403
 		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
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
 	__einfo_error ( EINFO_ENOTSUP_SIGNEDDATA )
65
 	__einfo_error ( EINFO_ENOTSUP_SIGNEDDATA )
66
 #define EINFO_ENOTSUP_SIGNEDDATA \
66
 #define EINFO_ENOTSUP_SIGNEDDATA \
67
 	__einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Not a digital signature" )
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
 /** "pkcs7-signedData" object identifier */
69
 /** "pkcs7-signedData" object identifier */
79
 static uint8_t oid_signeddata[] = { ASN1_OID_SIGNEDDATA };
70
 static uint8_t oid_signeddata[] = { ASN1_OID_SIGNEDDATA };
257
 					struct cms_signer_info *info,
248
 					struct cms_signer_info *info,
258
 					const struct asn1_cursor *raw ) {
249
 					const struct asn1_cursor *raw ) {
259
 	struct asn1_algorithm *algorithm;
250
 	struct asn1_algorithm *algorithm;
251
+	int rc;
260
 
252
 
261
 	/* Identify algorithm */
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
 		DBGC_HDA ( sig, 0, raw->data, raw->len );
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
 	/* Record digest algorithm */
261
 	/* Record digest algorithm */
294
 					   struct cms_signer_info *info,
278
 					   struct cms_signer_info *info,
295
 					   const struct asn1_cursor *raw ) {
279
 					   const struct asn1_cursor *raw ) {
296
 	struct asn1_algorithm *algorithm;
280
 	struct asn1_algorithm *algorithm;
281
+	int rc;
297
 
282
 
298
 	/* Identify algorithm */
283
 	/* Identify algorithm */
299
-	algorithm = asn1_algorithm ( raw );
300
-	if ( ! algorithm ) {
284
+	if ( ( rc = asn1_pubkey_algorithm ( raw, &algorithm ) ) != 0 ) {
301
 		DBGC ( sig, "CMS %p/%p could not identify public-key "
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
 		DBGC_HDA ( sig, 0, raw->data, raw->len );
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
 	/* Record signature algorithm */
291
 	/* Record signature algorithm */

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

154
 static struct asn1_cursor oid_common_name_cursor =
154
 static struct asn1_cursor oid_common_name_cursor =
155
 	ASN1_OID_CURSOR ( oid_common_name );
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
  * Parse X.509 certificate bit string
158
  * Parse X.509 certificate bit string
219
  *
159
  *
541
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
481
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
542
 
482
 
543
 	/* Parse algorithm */
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
 		return rc;
487
 		return rc;
488
+	}
547
 	DBGC2 ( cert, "X509 %p public key algorithm is %s\n",
489
 	DBGC2 ( cert, "X509 %p public key algorithm is %s\n",
548
 		cert, (*algorithm)->name );
490
 		cert, (*algorithm)->name );
549
 	asn1_skip_any ( &cursor );
491
 	asn1_skip_any ( &cursor );
1045
 	asn1_skip_any ( &cursor );
987
 	asn1_skip_any ( &cursor );
1046
 
988
 
1047
 	/* Parse signature */
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
 		return rc;
993
 		return rc;
994
+	}
1051
 	DBGC2 ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
995
 	DBGC2 ( cert, "X509 %p tbsCertificate signature algorithm is %s\n",
1052
 		cert, (*algorithm)->name );
996
 		cert, (*algorithm)->name );
1053
 	asn1_skip_any ( &cursor );
997
 	asn1_skip_any ( &cursor );
1107
 	asn1_skip_any ( &cursor );
1051
 	asn1_skip_any ( &cursor );
1108
 
1052
 
1109
 	/* Parse signatureAlgorithm */
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
 		return rc;
1058
 		return rc;
1059
+	}
1113
 	DBGC2 ( cert, "X509 %p signatureAlgorithm is %s\n",
1060
 	DBGC2 ( cert, "X509 %p signatureAlgorithm is %s\n",
1114
 		cert, (*signature_algorithm)->name );
1061
 		cert, (*signature_algorithm)->name );
1115
 	asn1_skip_any ( &cursor );
1062
 	asn1_skip_any ( &cursor );

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

238
 extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
238
 extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
239
 extern int asn1_compare ( const struct asn1_cursor *cursor1,
239
 extern int asn1_compare ( const struct asn1_cursor *cursor1,
240
 			  const struct asn1_cursor *cursor2 );
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
 extern int asn1_generalized_time ( const struct asn1_cursor *cursor,
249
 extern int asn1_generalized_time ( const struct asn1_cursor *cursor,
244
 				   time_t *time );
250
 				   time_t *time );
245
 
251
 

Loading…
Cancel
Save