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,6 +62,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
62 62
 	__einfo_error ( EINFO_EINVAL_ASN1_ALGORITHM )
63 63
 #define EINFO_EINVAL_ASN1_ALGORITHM \
64 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 69
 #define ENOTSUP_ALGORITHM \
66 70
 	__einfo_error ( EINFO_ENOTSUP_ALGORITHM )
67 71
 #define EINFO_ENOTSUP_ALGORITHM \
@@ -295,7 +299,9 @@ int asn1_shrink_any ( struct asn1_cursor *cursor ) {
295 299
  */
296 300
 int asn1_boolean ( const struct asn1_cursor *cursor ) {
297 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 306
 	/* Enter boolean */
301 307
 	memcpy ( &contents, cursor, sizeof ( contents ) );
@@ -347,6 +353,87 @@ int asn1_integer ( const struct asn1_cursor *cursor, int *value ) {
347 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 438
  * Compare two ASN.1 objects
352 439
  *

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

@@ -241,7 +241,7 @@ static int rsa_parse_integer ( struct rsa_context *context,
241 241
  */
242 242
 static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
243 243
 	struct rsa_context *context = ctx;
244
-	const struct asn1_bit_string *bit_string;
244
+	struct asn1_bit_string bits;
245 245
 	struct asn1_cursor modulus;
246 246
 	struct asn1_cursor exponent;
247 247
 	struct asn1_cursor cursor;
@@ -274,17 +274,10 @@ static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
274 274
 		asn1_skip ( &cursor, ASN1_SEQUENCE );
275 275
 
276 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 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 282
 		/* Enter RSAPublicKey */
290 283
 		asn1_enter ( &cursor, ASN1_SEQUENCE );

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

@@ -54,10 +54,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
54 54
 	__einfo_error ( EINFO_EINVAL_ALGORITHM )
55 55
 #define EINFO_EINVAL_ALGORITHM \
56 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 57
 #define EINVAL_ALGORITHM_MISMATCH \
62 58
 	__einfo_error ( EINFO_EINVAL_ALGORITHM_MISMATCH )
63 59
 #define EINFO_EINVAL_ALGORITHM_MISMATCH \
@@ -154,88 +150,6 @@ static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
154 150
 static struct asn1_cursor oid_common_name_cursor =
155 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 154
  * Parse X.509 certificate version
241 155
  *
@@ -466,7 +380,7 @@ static int x509_parse_public_key ( struct x509_certificate *cert,
466 380
 				   const struct asn1_cursor *raw ) {
467 381
 	struct x509_public_key *public_key = &cert->subject.public_key;
468 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 384
 	struct asn1_cursor cursor;
471 385
 	int rc;
472 386
 
@@ -491,8 +405,11 @@ static int x509_parse_public_key ( struct x509_certificate *cert,
491 405
 	asn1_skip_any ( &cursor );
492 406
 
493 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 411
 		return rc;
412
+	}
496 413
 
497 414
 	return 0;
498 415
 }
@@ -569,7 +486,7 @@ static int x509_parse_basic_constraints ( struct x509_certificate *cert,
569 486
 static int x509_parse_key_usage ( struct x509_certificate *cert,
570 487
 				  const struct asn1_cursor *raw ) {
571 488
 	struct x509_key_usage *usage = &cert->extensions.usage;
572
-	struct x509_bit_string bit_string;
489
+	struct asn1_bit_string bit_string;
573 490
 	const uint8_t *bytes;
574 491
 	size_t len;
575 492
 	unsigned int i;
@@ -579,8 +496,11 @@ static int x509_parse_key_usage ( struct x509_certificate *cert,
579 496
 	usage->present = 1;
580 497
 
581 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 502
 		return rc;
503
+	}
584 504
 
585 505
 	/* Parse key usage bits */
586 506
 	bytes = bit_string.data;
@@ -1034,7 +954,7 @@ static int x509_parse ( struct x509_certificate *cert,
1034 954
 			const struct asn1_cursor *raw ) {
1035 955
 	struct x509_signature *signature = &cert->signature;
1036 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 958
 	struct asn1_cursor cursor;
1039 959
 	int rc;
1040 960
 
@@ -1062,9 +982,12 @@ static int x509_parse ( struct x509_certificate *cert,
1062 982
 	asn1_skip_any ( &cursor );
1063 983
 
1064 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 989
 		return rc;
990
+	}
1068 991
 	DBGC2 ( cert, "X509 %p signatureValue is:\n", cert );
1069 992
 	DBGC2_HDA ( cert, 0, signature_value->data, signature_value->len );
1070 993
 

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

@@ -200,18 +200,14 @@ struct asn1_algorithm {
200 200
 /** Declare an ASN.1 OID-identified algorithm */
201 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 203
 /** An ASN.1 bit string */
210 204
 struct asn1_bit_string {
211
-	/** Number of unused bits */
212
-	uint8_t unused;
213 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 211
 } __attribute__ (( packed ));
216 212
 
217 213
 /**
@@ -236,6 +232,10 @@ extern int asn1_skip_any ( struct asn1_cursor *cursor );
236 232
 extern int asn1_shrink_any ( struct asn1_cursor *cursor );
237 233
 extern int asn1_boolean ( const struct asn1_cursor *cursor );
238 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 239
 extern int asn1_compare ( const struct asn1_cursor *cursor1,
240 240
 			  const struct asn1_cursor *cursor2 );
241 241
 extern int asn1_algorithm ( const struct asn1_cursor *cursor,

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

@@ -16,16 +16,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
16 16
 #include <ipxe/refcnt.h>
17 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 19
 /** An X.509 serial number */
30 20
 struct x509_serial {
31 21
 	/** Raw serial number */
@@ -59,7 +49,7 @@ struct x509_public_key {
59 49
 	/** Public key algorithm */
60 50
 	struct asn1_algorithm *algorithm;
61 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 55
 /** An X.509 certificate subject */
@@ -77,7 +67,7 @@ struct x509_signature {
77 67
 	/** Signature algorithm */
78 68
 	struct asn1_algorithm *algorithm;
79 69
 	/** Signature value */
80
-	struct x509_bit_string value;
70
+	struct asn1_bit_string value;
81 71
 };
82 72
 
83 73
 /** An X.509 certificate basic constraints set */

Loading…
Cancel
Save