Browse Source

[crypto] Generalise x509_parse_bit_string() to asn1_bit_string()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
4aad46ac70
5 changed files with 119 additions and 126 deletions
  1. 88
    1
      src/crypto/asn1.c
  2. 4
    11
      src/crypto/rsa.c
  3. 16
    93
      src/crypto/x509.c
  4. 9
    9
      src/include/ipxe/asn1.h
  5. 2
    12
      src/include/ipxe/x509.h

+ 88
- 1
src/crypto/asn1.c View File

62
 	__einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )
62
 	__einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )
63
 #define EINFO_EINVAL_ASN1_ALGORITHM \
63
 #define EINFO_EINVAL_ASN1_ALGORITHM \
64
 	__einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid algorithm" )
64
 	__einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid algorithm" )
65
+#define EINVAL_BIT_STRING \
66
+	__einfo_error ( EINFO_EINVAL_BIT_STRING )
67
+#define EINFO_EINVAL_BIT_STRING \
68
+	__einfo_uniqify ( EINFO_EINVAL, 0x07, "Invalid bit string" )
65
 #define ENOTSUP_ALGORITHM \
69
 #define ENOTSUP_ALGORITHM \
66
 	__einfo_error ( EINFO_ENOTSUP_ALGORITHM )
70
 	__einfo_error ( EINFO_ENOTSUP_ALGORITHM )
67
 #define EINFO_ENOTSUP_ALGORITHM \
71
 #define EINFO_ENOTSUP_ALGORITHM \
295
  */
299
  */
296
 int asn1_boolean ( const struct asn1_cursor *cursor ) {
300
 int asn1_boolean ( const struct asn1_cursor *cursor ) {
297
 	struct asn1_cursor contents;
301
 	struct asn1_cursor contents;
298
-	const struct asn1_boolean *boolean;
302
+	const struct {
303
+		uint8_t value;
304
+	} __attribute__ (( packed )) *boolean;
299
 
305
 
300
 	/* Enter boolean */
306
 	/* Enter boolean */
301
 	memcpy ( &contents, cursor, sizeof ( contents ) );
307
 	memcpy ( &contents, cursor, sizeof ( contents ) );
347
 	return 0;
353
 	return 0;
348
 }
354
 }
349
 
355
 
356
+/**
357
+ * Parse ASN.1 bit string
358
+ *
359
+ * @v cursor		ASN.1 cursor
360
+ * @v bits		Bit string to fill in
361
+ * @ret rc		Return status code
362
+ */
363
+int asn1_bit_string ( const struct asn1_cursor *cursor,
364
+		      struct asn1_bit_string *bits ) {
365
+	struct asn1_cursor contents;
366
+	const struct {
367
+		uint8_t unused;
368
+		uint8_t data[0];
369
+	} __attribute__ (( packed )) *bit_string;
370
+	size_t len;
371
+	unsigned int unused;
372
+	uint8_t unused_mask;
373
+	const uint8_t *last;
374
+	int rc;
375
+
376
+	/* Enter bit string */
377
+	memcpy ( &contents, cursor, sizeof ( contents ) );
378
+	if ( ( rc = asn1_enter ( &contents, ASN1_BIT_STRING ) ) != 0 ) {
379
+		DBGC ( cursor, "ASN1 %p cannot locate bit string:\n", cursor );
380
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
381
+		return rc;
382
+	}
383
+
384
+	/* Validity checks */
385
+	if ( contents.len < sizeof ( *bit_string ) ) {
386
+		DBGC ( cursor, "ASN1 %p invalid bit string:\n", cursor );
387
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
388
+		return -EINVAL_BIT_STRING;
389
+	}
390
+	bit_string = contents.data;
391
+	len = ( contents.len - offsetof ( typeof ( *bit_string ), data ) );
392
+	unused = bit_string->unused;
393
+	unused_mask = ( 0xff >> ( 8 - unused ) );
394
+	last = ( bit_string->data + len - 1 );
395
+	if ( ( unused >= 8 ) ||
396
+	     ( ( unused > 0 ) && ( len == 0 ) ) ||
397
+	     ( ( *last & unused_mask ) != 0 ) ) {
398
+		DBGC ( cursor, "ASN1 %p invalid bit string:\n", cursor );
399
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
400
+		return -EINVAL_BIT_STRING;
401
+	}
402
+
403
+	/* Populate bit string */
404
+	bits->data = &bit_string->data;
405
+	bits->len = len;
406
+	bits->unused = unused;
407
+
408
+	return 0;
409
+}
410
+
411
+/**
412
+ * Parse ASN.1 bit string that must be an integral number of bytes
413
+ *
414
+ * @v cursor		ASN.1 cursor
415
+ * @v bits		Bit string to fill in
416
+ * @ret rc		Return status code
417
+ */
418
+int asn1_integral_bit_string ( const struct asn1_cursor *cursor,
419
+			       struct asn1_bit_string *bits ) {
420
+	int rc;
421
+
422
+	/* Parse bit string */
423
+	if ( ( rc = asn1_bit_string ( cursor, bits ) ) != 0 )
424
+		return rc;
425
+
426
+	/* Check that there are no unused bits at end of string */
427
+	if ( bits->unused ) {
428
+		DBGC ( cursor, "ASN1 %p invalid integral bit string:\n",
429
+		       cursor );
430
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
431
+		return -EINVAL_BIT_STRING;
432
+	}
433
+
434
+	return 0;
435
+}
436
+
350
 /**
437
 /**
351
  * Compare two ASN.1 objects
438
  * Compare two ASN.1 objects
352
  *
439
  *

+ 4
- 11
src/crypto/rsa.c View File

241
  */
241
  */
242
 static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
242
 static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
243
 	struct rsa_context *context = ctx;
243
 	struct rsa_context *context = ctx;
244
-	const struct asn1_bit_string *bit_string;
244
+	struct asn1_bit_string bits;
245
 	struct asn1_cursor modulus;
245
 	struct asn1_cursor modulus;
246
 	struct asn1_cursor exponent;
246
 	struct asn1_cursor exponent;
247
 	struct asn1_cursor cursor;
247
 	struct asn1_cursor cursor;
274
 		asn1_skip ( &cursor, ASN1_SEQUENCE );
274
 		asn1_skip ( &cursor, ASN1_SEQUENCE );
275
 
275
 
276
 		/* Enter subjectPublicKey */
276
 		/* Enter subjectPublicKey */
277
-		asn1_enter ( &cursor, ASN1_BIT_STRING );
278
-
279
-		/* Check and skip unused-bits byte of bit string */
280
-		bit_string = cursor.data;
281
-		if ( ( cursor.len < sizeof ( *bit_string ) ) ||
282
-		     ( bit_string->unused != 0 ) ) {
283
-			rc = -EINVAL;
277
+		if ( ( rc = asn1_integral_bit_string ( &cursor, &bits ) ) != 0 )
284
 			goto err_parse;
278
 			goto err_parse;
285
-		}
286
-		cursor.data = &bit_string->data;
287
-		cursor.len -= offsetof ( typeof ( *bit_string ), data );
279
+		cursor.data = bits.data;
280
+		cursor.len = bits.len;
288
 
281
 
289
 		/* Enter RSAPublicKey */
282
 		/* Enter RSAPublicKey */
290
 		asn1_enter ( &cursor, ASN1_SEQUENCE );
283
 		asn1_enter ( &cursor, ASN1_SEQUENCE );

+ 16
- 93
src/crypto/x509.c View File

54
 	__einfo_error ( EINFO_EINVAL_ALGORITHM )
54
 	__einfo_error ( EINFO_EINVAL_ALGORITHM )
55
 #define EINFO_EINVAL_ALGORITHM \
55
 #define EINFO_EINVAL_ALGORITHM \
56
 	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid algorithm type" )
56
 	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid algorithm type" )
57
-#define EINVAL_BIT_STRING \
58
-	__einfo_error ( EINFO_EINVAL_BIT_STRING )
59
-#define EINFO_EINVAL_BIT_STRING \
60
-	__einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid bit string" )
61
 #define EINVAL_ALGORITHM_MISMATCH \
57
 #define EINVAL_ALGORITHM_MISMATCH \
62
 	__einfo_error ( EINFO_EINVAL_ALGORITHM_MISMATCH )
58
 	__einfo_error ( EINFO_EINVAL_ALGORITHM_MISMATCH )
63
 #define EINFO_EINVAL_ALGORITHM_MISMATCH \
59
 #define EINFO_EINVAL_ALGORITHM_MISMATCH \
154
 static struct asn1_cursor oid_common_name_cursor =
150
 static struct asn1_cursor oid_common_name_cursor =
155
 	ASN1_OID_CURSOR ( oid_common_name );
151
 	ASN1_OID_CURSOR ( oid_common_name );
156
 
152
 
157
-/**
158
- * Parse X.509 certificate bit string
159
- *
160
- * @v cert		X.509 certificate
161
- * @v bits		Bit string to fill in
162
- * @v raw		ASN.1 cursor
163
- * @ret rc		Return status code
164
- */
165
-static int x509_parse_bit_string ( struct x509_certificate *cert,
166
-				   struct x509_bit_string *bits,
167
-				   const struct asn1_cursor *raw ) {
168
-	struct asn1_cursor cursor;
169
-	const struct asn1_bit_string *bit_string;
170
-	size_t len;
171
-	unsigned int unused;
172
-	uint8_t unused_mask;
173
-	const uint8_t *last;
174
-	int rc;
175
-
176
-	/* Enter bit string */
177
-	memcpy ( &cursor, raw, sizeof ( cursor ) );
178
-	if ( ( rc = asn1_enter ( &cursor, ASN1_BIT_STRING ) ) != 0 ) {
179
-		DBGC ( cert, "X509 %p cannot locate bit string:\n", cert );
180
-		DBGC_HDA ( cert, 0, raw->data, raw->len );
181
-		return rc;
182
-	}
183
-
184
-	/* Validity checks */
185
-	if ( cursor.len < sizeof ( *bit_string ) ) {
186
-		DBGC ( cert, "X509 %p invalid bit string:\n", cert );
187
-		DBGC_HDA ( cert, 0, raw->data, raw->len );
188
-		return -EINVAL_BIT_STRING;
189
-	}
190
-	bit_string = cursor.data;
191
-	len = ( cursor.len - offsetof ( typeof ( *bit_string ), data ) );
192
-	unused = bit_string->unused;
193
-	unused_mask = ( 0xff >> ( 8 - unused ) );
194
-	last = ( bit_string->data + len - 1 );
195
-	if ( ( unused >= 8 ) ||
196
-	     ( ( unused > 0 ) && ( len == 0 ) ) ||
197
-	     ( ( *last & unused_mask ) != 0 ) ) {
198
-		DBGC ( cert, "X509 %p invalid bit string:\n", cert );
199
-		DBGC_HDA ( cert, 0, raw->data, raw->len );
200
-		return -EINVAL_BIT_STRING;
201
-	}
202
-
203
-	/* Populate bit string */
204
-	bits->data = &bit_string->data;
205
-	bits->len = len;
206
-	bits->unused = unused;
207
-
208
-	return 0;
209
-}
210
-
211
-/**
212
- * Parse X.509 certificate bit string that must be an integral number of bytes
213
- *
214
- * @v cert		X.509 certificate
215
- * @v bits		Bit string to fill in
216
- * @v raw		ASN.1 cursor
217
- * @ret rc		Return status code
218
- */
219
-static int x509_parse_integral_bit_string ( struct x509_certificate *cert,
220
-					    struct x509_bit_string *bits,
221
-					    const struct asn1_cursor *raw ) {
222
-	int rc;
223
-
224
-	/* Parse bit string */
225
-	if ( ( rc = x509_parse_bit_string ( cert, bits, raw ) ) != 0 )
226
-		return rc;
227
-
228
-	/* Check that there are no unused bits at end of string */
229
-	if ( bits->unused ) {
230
-		DBGC ( cert, "X509 %p invalid integral bit string:\n", cert );
231
-		DBGC_HDA ( cert, 0, raw->data, raw->len );
232
-		return -EINVAL_BIT_STRING;
233
-	}
234
-
235
-	return 0;
236
-}
237
-
238
-
239
 /**
153
 /**
240
  * Parse X.509 certificate version
154
  * Parse X.509 certificate version
241
  *
155
  *
466
 				   const struct asn1_cursor *raw ) {
380
 				   const struct asn1_cursor *raw ) {
467
 	struct x509_public_key *public_key = &cert->subject.public_key;
381
 	struct x509_public_key *public_key = &cert->subject.public_key;
468
 	struct asn1_algorithm **algorithm = &public_key->algorithm;
382
 	struct asn1_algorithm **algorithm = &public_key->algorithm;
469
-	struct x509_bit_string *raw_bits = &public_key->raw_bits;
383
+	struct asn1_bit_string *raw_bits = &public_key->raw_bits;
470
 	struct asn1_cursor cursor;
384
 	struct asn1_cursor cursor;
471
 	int rc;
385
 	int rc;
472
 
386
 
491
 	asn1_skip_any ( &cursor );
405
 	asn1_skip_any ( &cursor );
492
 
406
 
493
 	/* Parse bit string */
407
 	/* Parse bit string */
494
-	if ( ( rc = x509_parse_bit_string ( cert, raw_bits, &cursor ) ) != 0 )
408
+	if ( ( rc = asn1_bit_string ( &cursor, raw_bits ) ) != 0 ) {
409
+		DBGC ( cert, "X509 %p could not parse public key bits: %s\n",
410
+		       cert, strerror ( rc ) );
495
 		return rc;
411
 		return rc;
412
+	}
496
 
413
 
497
 	return 0;
414
 	return 0;
498
 }
415
 }
569
 static int x509_parse_key_usage ( struct x509_certificate *cert,
486
 static int x509_parse_key_usage ( struct x509_certificate *cert,
570
 				  const struct asn1_cursor *raw ) {
487
 				  const struct asn1_cursor *raw ) {
571
 	struct x509_key_usage *usage = &cert->extensions.usage;
488
 	struct x509_key_usage *usage = &cert->extensions.usage;
572
-	struct x509_bit_string bit_string;
489
+	struct asn1_bit_string bit_string;
573
 	const uint8_t *bytes;
490
 	const uint8_t *bytes;
574
 	size_t len;
491
 	size_t len;
575
 	unsigned int i;
492
 	unsigned int i;
579
 	usage->present = 1;
496
 	usage->present = 1;
580
 
497
 
581
 	/* Parse bit string */
498
 	/* Parse bit string */
582
-	if ( ( rc = x509_parse_bit_string ( cert, &bit_string, raw ) ) != 0 )
499
+	if ( ( rc = asn1_bit_string ( raw, &bit_string ) ) != 0 ) {
500
+		DBGC ( cert, "X509 %p could not parse key usage: %s\n",
501
+		       cert, strerror ( rc ) );
583
 		return rc;
502
 		return rc;
503
+	}
584
 
504
 
585
 	/* Parse key usage bits */
505
 	/* Parse key usage bits */
586
 	bytes = bit_string.data;
506
 	bytes = bit_string.data;
1034
 			const struct asn1_cursor *raw ) {
954
 			const struct asn1_cursor *raw ) {
1035
 	struct x509_signature *signature = &cert->signature;
955
 	struct x509_signature *signature = &cert->signature;
1036
 	struct asn1_algorithm **signature_algorithm = &signature->algorithm;
956
 	struct asn1_algorithm **signature_algorithm = &signature->algorithm;
1037
-	struct x509_bit_string *signature_value = &signature->value;
957
+	struct asn1_bit_string *signature_value = &signature->value;
1038
 	struct asn1_cursor cursor;
958
 	struct asn1_cursor cursor;
1039
 	int rc;
959
 	int rc;
1040
 
960
 
1062
 	asn1_skip_any ( &cursor );
982
 	asn1_skip_any ( &cursor );
1063
 
983
 
1064
 	/* Parse signatureValue */
984
 	/* Parse signatureValue */
1065
-	if ( ( rc = x509_parse_integral_bit_string ( cert, signature_value,
1066
-						     &cursor ) ) != 0 )
985
+	if ( ( rc = asn1_integral_bit_string ( &cursor,
986
+					       signature_value ) ) != 0 ) {
987
+		DBGC ( cert, "X509 %p could not parse signature value: %s\n",
988
+		       cert, strerror ( rc ) );
1067
 		return rc;
989
 		return rc;
990
+	}
1068
 	DBGC2 ( cert, "X509 %p signatureValue is:\n", cert );
991
 	DBGC2 ( cert, "X509 %p signatureValue is:\n", cert );
1069
 	DBGC2_HDA ( cert, 0, signature_value->data, signature_value->len );
992
 	DBGC2_HDA ( cert, 0, signature_value->data, signature_value->len );
1070
 
993
 

+ 9
- 9
src/include/ipxe/asn1.h View File

200
 /** Declare an ASN.1 OID-identified algorithm */
200
 /** Declare an ASN.1 OID-identified algorithm */
201
 #define __asn1_algorithm __table_entry ( ASN1_ALGORITHMS, 01 )
201
 #define __asn1_algorithm __table_entry ( ASN1_ALGORITHMS, 01 )
202
 
202
 
203
-/** An ASN.1 boolean */
204
-struct asn1_boolean {
205
-	/** Value */
206
-	uint8_t value;
207
-} __attribute__ (( packed ));
208
-
209
 /** An ASN.1 bit string */
203
 /** An ASN.1 bit string */
210
 struct asn1_bit_string {
204
 struct asn1_bit_string {
211
-	/** Number of unused bits */
212
-	uint8_t unused;
213
 	/** Data */
205
 	/** Data */
214
-	uint8_t data[0];
206
+	const void *data;
207
+	/** Length */
208
+	size_t len;
209
+	/** Unused bits at end of data */
210
+	unsigned int unused;
215
 } __attribute__ (( packed ));
211
 } __attribute__ (( packed ));
216
 
212
 
217
 /**
213
 /**
236
 extern int asn1_shrink_any ( struct asn1_cursor *cursor );
232
 extern int asn1_shrink_any ( struct asn1_cursor *cursor );
237
 extern int asn1_boolean ( const struct asn1_cursor *cursor );
233
 extern int asn1_boolean ( const struct asn1_cursor *cursor );
238
 extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
234
 extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
235
+extern int asn1_bit_string ( const struct asn1_cursor *cursor,
236
+			     struct asn1_bit_string *bits );
237
+extern int asn1_integral_bit_string ( const struct asn1_cursor *cursor,
238
+				      struct asn1_bit_string *bits );
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 int asn1_algorithm ( const struct asn1_cursor *cursor,
241
 extern int asn1_algorithm ( const struct asn1_cursor *cursor,

+ 2
- 12
src/include/ipxe/x509.h View File

16
 #include <ipxe/refcnt.h>
16
 #include <ipxe/refcnt.h>
17
 #include <ipxe/list.h>
17
 #include <ipxe/list.h>
18
 
18
 
19
-/** An X.509 bit string */
20
-struct x509_bit_string {
21
-	/** Data */
22
-	const void *data;
23
-	/** Length */
24
-	size_t len;
25
-	/** Unused bits at end of data */
26
-	unsigned int unused;
27
-};
28
-
29
 /** An X.509 serial number */
19
 /** An X.509 serial number */
30
 struct x509_serial {
20
 struct x509_serial {
31
 	/** Raw serial number */
21
 	/** Raw serial number */
59
 	/** Public key algorithm */
49
 	/** Public key algorithm */
60
 	struct asn1_algorithm *algorithm;
50
 	struct asn1_algorithm *algorithm;
61
 	/** Raw public key bit string */
51
 	/** Raw public key bit string */
62
-	struct x509_bit_string raw_bits;
52
+	struct asn1_bit_string raw_bits;
63
 };
53
 };
64
 
54
 
65
 /** An X.509 certificate subject */
55
 /** An X.509 certificate subject */
77
 	/** Signature algorithm */
67
 	/** Signature algorithm */
78
 	struct asn1_algorithm *algorithm;
68
 	struct asn1_algorithm *algorithm;
79
 	/** Signature value */
69
 	/** Signature value */
80
-	struct x509_bit_string value;
70
+	struct asn1_bit_string value;
81
 };
71
 };
82
 
72
 
83
 /** An X.509 certificate basic constraints set */
73
 /** An X.509 certificate basic constraints set */

Loading…
Cancel
Save