Browse Source

[crypto] Generalise X.509 OID-identified algorithm to asn1.c

The concept of an OID-identified algorithm as defined in X.509 is used
in some other standards (e.g. PKCS#7).  Generalise this functionality
and provide it as part of the ASN.1 core.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
38b7e43f7d
5 changed files with 155 additions and 121 deletions
  1. 54
    0
      src/crypto/asn1.c
  2. 47
    0
      src/crypto/rsa.c
  3. 28
    95
      src/crypto/x509.c
  4. 23
    0
      src/include/ipxe/asn1.h
  5. 3
    26
      src/include/ipxe/x509.h

+ 54
- 0
src/crypto/asn1.c View File

@@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
22 22
 #include <stddef.h>
23 23
 #include <string.h>
24 24
 #include <errno.h>
25
+#include <ipxe/tables.h>
25 26
 #include <ipxe/asn1.h>
26 27
 
27 28
 /** @file
@@ -341,3 +342,56 @@ int asn1_compare ( const struct asn1_cursor *cursor1,
341 342
 	return ( difference ? difference :
342 343
 		 memcmp ( cursor1->data, cursor2->data, cursor1->len ) );
343 344
 }
345
+
346
+/**
347
+ * Identify ASN.1 algorithm by OID
348
+ *
349
+ * @v cursor		ASN.1 object cursor
350
+
351
+ * @ret algorithm	Algorithm, or NULL
352
+ */
353
+static struct asn1_algorithm *
354
+asn1_find_algorithm ( const struct asn1_cursor *cursor ) {
355
+	struct asn1_algorithm *algorithm;
356
+
357
+	for_each_table_entry ( algorithm, ASN1_ALGORITHMS ) {
358
+		if ( asn1_compare ( &algorithm->oid, cursor ) == 0 )
359
+			return algorithm;
360
+	}
361
+
362
+	return NULL;
363
+}
364
+
365
+/**
366
+ * Parse ASN.1 OID-identified algorithm
367
+ *
368
+ * @v cursor		ASN.1 object cursor
369
+ * @ret algorithm	Algorithm, or NULL
370
+ */
371
+struct asn1_algorithm * asn1_algorithm ( const struct asn1_cursor *cursor ) {
372
+	struct asn1_cursor contents;
373
+	struct asn1_algorithm *algorithm;
374
+	int rc;
375
+
376
+	/* Enter signatureAlgorithm */
377
+	memcpy ( &contents, cursor, sizeof ( contents ) );
378
+	asn1_enter ( &contents, ASN1_SEQUENCE );
379
+
380
+	/* Enter algorithm */
381
+	if ( ( rc = asn1_enter ( &contents, ASN1_OID ) ) != 0 ) {
382
+		DBGC ( cursor, "ASN1 %p cannot locate algorithm OID:\n",
383
+		       cursor );
384
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
385
+		return NULL;
386
+	}
387
+
388
+	/* Identify algorithm */
389
+	algorithm = asn1_find_algorithm ( &contents );
390
+	if ( ! algorithm ) {
391
+		DBGC ( cursor, "ASN1 %p unrecognised algorithm:\n", cursor );
392
+		DBGC_HDA ( cursor, 0, cursor->data, cursor->len );
393
+		return NULL;
394
+	}
395
+
396
+	return algorithm;
397
+}

+ 47
- 0
src/crypto/rsa.c View File

@@ -39,6 +39,53 @@ FILE_LICENCE ( GPL2_OR_LATER );
39 39
  * RSA is documented in RFC 3447.
40 40
  */
41 41
 
42
+/** "rsaEncryption" object identifier */
43
+static uint8_t oid_rsa_encryption[] = { ASN1_OID_RSAENCRYPTION };
44
+
45
+/** "md5WithRSAEncryption" object identifier */
46
+static uint8_t oid_md5_with_rsa_encryption[] =
47
+	{ ASN1_OID_MD5WITHRSAENCRYPTION };
48
+
49
+/** "sha1WithRSAEncryption" object identifier */
50
+static uint8_t oid_sha1_with_rsa_encryption[] =
51
+	{ ASN1_OID_SHA1WITHRSAENCRYPTION };
52
+
53
+/** "sha256WithRSAEncryption" object identifier */
54
+static uint8_t oid_sha256_with_rsa_encryption[] =
55
+	{ ASN1_OID_SHA256WITHRSAENCRYPTION };
56
+
57
+/** "rsaEncryption" OID-identified algorithm */
58
+struct asn1_algorithm rsa_encryption_algorithm __asn1_algorithm = {
59
+	.name = "rsaEncryption",
60
+	.pubkey = &rsa_algorithm,
61
+	.digest = NULL,
62
+	.oid = ASN1_OID_CURSOR ( oid_rsa_encryption ),
63
+};
64
+
65
+/** "md5WithRSAEncryption" OID-identified algorithm */
66
+struct asn1_algorithm md5_with_rsa_encryption_algorithm __asn1_algorithm = {
67
+	.name = "md5WithRSAEncryption",
68
+	.pubkey = &rsa_algorithm,
69
+	.digest = &md5_algorithm,
70
+	.oid = ASN1_OID_CURSOR ( oid_md5_with_rsa_encryption ),
71
+};
72
+
73
+/** "sha1WithRSAEncryption" OID-identified algorithm */
74
+struct asn1_algorithm sha1_with_rsa_encryption_algorithm __asn1_algorithm = {
75
+	.name = "sha1WithRSAEncryption",
76
+	.pubkey = &rsa_algorithm,
77
+	.digest = &sha1_algorithm,
78
+	.oid = ASN1_OID_CURSOR ( oid_sha1_with_rsa_encryption ),
79
+};
80
+
81
+/** "sha256WithRSAEncryption" OID-identified algorithm */
82
+struct asn1_algorithm sha256_with_rsa_encryption_algorithm __asn1_algorithm = {
83
+	.name = "sha256WithRSAEncryption",
84
+	.pubkey = &rsa_algorithm,
85
+	.digest = &sha256_algorithm,
86
+	.oid = ASN1_OID_CURSOR ( oid_sha256_with_rsa_encryption ),
87
+};
88
+
42 89
 /** MD5 digestInfo prefix */
43 90
 static const uint8_t rsa_md5_prefix_data[] =
44 91
 	{ RSA_DIGESTINFO_PREFIX ( MD5_DIGEST_SIZE, ASN1_OID_MD5 ) };

+ 28
- 95
src/crypto/x509.c View File

@@ -49,10 +49,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
49 49
 	__einfo_error ( EINFO_ENOTSUP_EXTENSION )
50 50
 #define EINFO_ENOTSUP_EXTENSION \
51 51
 	__einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported extension" )
52
-#define EINVAL_NON_SIGNATURE \
53
-	__einfo_error ( EINFO_EINVAL_NON_SIGNATURE )
54
-#define EINFO_EINVAL_NON_SIGNATURE \
55
-	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Not a signature algorithm" )
52
+#define EINVAL_ALGORITHM \
53
+	__einfo_error ( EINFO_EINVAL_ALGORITHM )
54
+#define EINFO_EINVAL_ALGORITHM \
55
+	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid algorithm type" )
56 56
 #define EINVAL_BIT_STRING \
57 57
 	__einfo_error ( EINFO_EINVAL_BIT_STRING )
58 58
 #define EINFO_EINVAL_BIT_STRING \
@@ -101,70 +101,6 @@ static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
101 101
 static struct asn1_cursor oid_common_name_cursor =
102 102
 	ASN1_OID_CURSOR ( oid_common_name );
103 103
 
104
-/** "rsaEncryption" object identifier */
105
-static uint8_t oid_rsa_encryption[] = { ASN1_OID_RSAENCRYPTION };
106
-
107
-/** "md5WithRSAEncryption" object identifier */
108
-static uint8_t oid_md5_with_rsa_encryption[] =
109
-	{ ASN1_OID_MD5WITHRSAENCRYPTION };
110
-
111
-/** "sha1WithRSAEncryption" object identifier */
112
-static uint8_t oid_sha1_with_rsa_encryption[] =
113
-	{ ASN1_OID_SHA1WITHRSAENCRYPTION };
114
-
115
-/** "sha256WithRSAEncryption" object identifier */
116
-static uint8_t oid_sha256_with_rsa_encryption[] =
117
-	{ ASN1_OID_SHA256WITHRSAENCRYPTION };
118
-
119
-/** Supported algorithms */
120
-static struct x509_algorithm x509_algorithms[] = {
121
-	{
122
-		.name = "rsaEncryption",
123
-		.pubkey = &rsa_algorithm,
124
-		.digest = NULL,
125
-		.oid = ASN1_OID_CURSOR ( oid_rsa_encryption ),
126
-	},
127
-	{
128
-		.name = "md5WithRSAEncryption",
129
-		.pubkey = &rsa_algorithm,
130
-		.digest = &md5_algorithm,
131
-		.oid = ASN1_OID_CURSOR ( oid_md5_with_rsa_encryption ),
132
-	},
133
-	{
134
-		.name = "sha1WithRSAEncryption",
135
-		.pubkey = &rsa_algorithm,
136
-		.digest = &sha1_algorithm,
137
-		.oid = ASN1_OID_CURSOR ( oid_sha1_with_rsa_encryption ),
138
-	},
139
-	{
140
-		.name = "sha256WithRSAEncryption",
141
-		.pubkey = &rsa_algorithm,
142
-		.digest = &sha256_algorithm,
143
-		.oid = ASN1_OID_CURSOR ( oid_sha256_with_rsa_encryption ),
144
-	},
145
-};
146
-
147
-/**
148
- * Identify X.509 algorithm by OID
149
- *
150
- * @v oid		OID
151
- * @ret algorithm	Algorithm, or NULL
152
- */
153
-static struct x509_algorithm *
154
-x509_find_algorithm ( const struct asn1_cursor *oid ) {
155
-	struct x509_algorithm *algorithm;
156
-	unsigned int i;
157
-
158
-	for ( i = 0 ; i < ( sizeof ( x509_algorithms ) /
159
-			    sizeof ( x509_algorithms[0] ) ) ; i++ ) {
160
-		algorithm = &x509_algorithms[i];
161
-		if ( asn1_compare ( &algorithm->oid, oid ) == 0 )
162
-			return algorithm;
163
-	}
164
-
165
-	return NULL;
166
-}
167
-
168 104
 /**
169 105
  * Parse X.509 certificate algorithm
170 106
  *
@@ -173,29 +109,24 @@ x509_find_algorithm ( const struct asn1_cursor *oid ) {
173 109
  * @v raw		ASN.1 cursor
174 110
  * @ret rc		Return status code
175 111
  */
176
-static int x509_parse_algorithm ( struct x509_certificate *cert,
177
-				  struct x509_algorithm **algorithm,
112
+int x509_parse_pubkey_algorithm ( struct x509_certificate *cert,
113
+				  struct asn1_algorithm **algorithm,
178 114
 				  const struct asn1_cursor *raw ) {
179
-	struct asn1_cursor cursor;
180
-	int rc;
181 115
 
182
-	/* Enter signatureAlgorithm */
183
-	memcpy ( &cursor, raw, sizeof ( cursor ) );
184
-	asn1_enter ( &cursor, ASN1_SEQUENCE );
185
-
186
-	/* Enter algorithm */
187
-	if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
188
-		DBGC ( cert, "X509 %p cannot locate algorithm:\n", cert );
116
+	/* Parse algorithm */
117
+	*algorithm = asn1_algorithm ( raw );
118
+	if ( ! (*algorithm) ) {
119
+		DBGC ( cert, "X509 %p unrecognised algorithm:\n", cert );
189 120
 		DBGC_HDA ( cert, 0, raw->data, raw->len );
190
-		return rc;
121
+		return -ENOTSUP_ALGORITHM;
191 122
 	}
192 123
 
193
-	/* Identify algorithm */
194
-	*algorithm = x509_find_algorithm ( &cursor );
195
-	if ( ! *algorithm ) {
196
-		DBGC ( cert, "X509 %p unsupported algorithm:\n", cert );
197
-		DBGC_HDA ( cert, 0, cursor.data, cursor.len );
198
-		return -ENOTSUP_ALGORITHM;
124
+	/* Check algorithm has a public key */
125
+	if ( ! (*algorithm)->pubkey ) {
126
+		DBGC ( cert, "X509 %p algorithm %s is not a public-key "
127
+		       "algorithm:\n", cert, (*algorithm)->name );
128
+		DBGC_HDA ( cert, 0, raw->data, raw->len );
129
+		return -EINVAL_ALGORITHM;
199 130
 	}
200 131
 
201 132
 	return 0;
@@ -210,20 +141,21 @@ static int x509_parse_algorithm ( struct x509_certificate *cert,
210 141
  * @ret rc		Return status code
211 142
  */
212 143
 static int x509_parse_signature_algorithm ( struct x509_certificate *cert,
213
-					    struct x509_algorithm **algorithm,
144
+					    struct asn1_algorithm **algorithm,
214 145
 					    const struct asn1_cursor *raw ) {
215 146
 	int rc;
216 147
 
217 148
 	/* Parse algorithm */
218
-	if ( ( rc = x509_parse_algorithm ( cert, algorithm, raw ) ) != 0 )
149
+	if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
150
+						  raw ) ) != 0 )
219 151
 		return rc;
220 152
 
221 153
 	/* Check algorithm is a signature algorithm */
222
-	if ( ! x509_is_signature_algorithm ( *algorithm ) ) {
154
+	if ( ! (*algorithm)->digest ) {
223 155
 		DBGC ( cert, "X509 %p algorithm %s is not a signature "
224 156
 		       "algorithm:\n", cert, (*algorithm)->name );
225 157
 		DBGC_HDA ( cert, 0, raw->data, raw->len );
226
-		return -EINVAL_NON_SIGNATURE;
158
+		return -EINVAL_ALGORITHM;
227 159
 	}
228 160
 
229 161
 	return 0;
@@ -600,7 +532,7 @@ static int x509_parse_subject ( struct x509_certificate *cert,
600 532
 static int x509_parse_public_key ( struct x509_certificate *cert,
601 533
 				   const struct asn1_cursor *raw ) {
602 534
 	struct x509_public_key *public_key = &cert->subject.public_key;
603
-	struct x509_algorithm **algorithm = &public_key->algorithm;
535
+	struct asn1_algorithm **algorithm = &public_key->algorithm;
604 536
 	struct asn1_cursor cursor;
605 537
 	int rc;
606 538
 
@@ -613,7 +545,8 @@ static int x509_parse_public_key ( struct x509_certificate *cert,
613 545
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
614 546
 
615 547
 	/* Parse algorithm */
616
-	if ( ( rc = x509_parse_algorithm ( cert, algorithm, &cursor ) ) != 0 )
548
+	if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
549
+						  &cursor ) ) != 0 )
617 550
 		return rc;
618 551
 	DBGC ( cert, "X509 %p public key algorithm is %s\n",
619 552
 	       cert, (*algorithm)->name );
@@ -866,7 +799,7 @@ static int x509_parse_extensions ( struct x509_certificate *cert,
866 799
  */
867 800
 static int x509_parse_tbscertificate ( struct x509_certificate *cert,
868 801
 				       const struct asn1_cursor *raw ) {
869
-	struct x509_algorithm **algorithm = &cert->signature_algorithm;
802
+	struct asn1_algorithm **algorithm = &cert->signature_algorithm;
870 803
 	struct asn1_cursor cursor;
871 804
 	int rc;
872 805
 
@@ -933,7 +866,7 @@ static int x509_parse_tbscertificate ( struct x509_certificate *cert,
933 866
  */
934 867
 int x509_parse ( struct x509_certificate *cert, const void *data, size_t len ) {
935 868
 	struct x509_signature *signature = &cert->signature;
936
-	struct x509_algorithm **signature_algorithm = &signature->algorithm;
869
+	struct asn1_algorithm **signature_algorithm = &signature->algorithm;
937 870
 	struct x509_bit_string *signature_value = &signature->value;
938 871
 	struct asn1_cursor cursor;
939 872
 	int rc;
@@ -991,7 +924,7 @@ int x509_parse ( struct x509_certificate *cert, const void *data, size_t len ) {
991 924
 static int x509_check_signature ( struct x509_certificate *cert,
992 925
 				  struct x509_public_key *public_key ) {
993 926
 	struct x509_signature *signature = &cert->signature;
994
-	struct x509_algorithm *algorithm = signature->algorithm;
927
+	struct asn1_algorithm *algorithm = signature->algorithm;
995 928
 	struct digest_algorithm *digest = algorithm->digest;
996 929
 	struct pubkey_algorithm *pubkey = algorithm->pubkey;
997 930
 	uint8_t digest_ctx[ digest->ctxsize ];

+ 23
- 0
src/include/ipxe/asn1.h View File

@@ -9,6 +9,9 @@
9 9
 
10 10
 FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12
+#include <stdint.h>
13
+#include <ipxe/tables.h>
14
+
12 15
 /** An ASN.1 object cursor */
13 16
 struct asn1_cursor {
14 17
 	/** Start of data */
@@ -143,6 +146,24 @@ struct asn1_cursor {
143 146
 		.len = sizeof ( oid_value ),			\
144 147
 	}
145 148
 
149
+/** An ASN.1 OID-identified algorithm */
150
+struct asn1_algorithm {
151
+	/** Name */
152
+	const char *name;
153
+	/** Object identifier */
154
+	struct asn1_cursor oid;
155
+	/** Public-key algorithm (if applicable) */
156
+	struct pubkey_algorithm *pubkey;
157
+	/** Digest algorithm (if applicable) */
158
+	struct digest_algorithm *digest;
159
+};
160
+
161
+/** ASN.1 OID-identified algorithms */
162
+#define ASN1_ALGORITHMS __table ( struct asn1_algorithm, "asn1_algorithms" )
163
+
164
+/** Declare an ASN.1 OID-identified algorithm */
165
+#define __asn1_algorithm __table_entry ( ASN1_ALGORITHMS, 01 )
166
+
146 167
 /** An ASN.1 boolean */
147 168
 struct asn1_boolean {
148 169
 	/** Value */
@@ -181,5 +202,7 @@ extern int asn1_boolean ( const struct asn1_cursor *cursor );
181 202
 extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
182 203
 extern int asn1_compare ( const struct asn1_cursor *cursor1,
183 204
 			  const struct asn1_cursor *cursor2 );
205
+extern struct asn1_algorithm *
206
+asn1_algorithm ( const struct asn1_cursor *cursor );
184 207
 
185 208
 #endif /* _IPXE_ASN1_H */

+ 3
- 26
src/include/ipxe/x509.h View File

@@ -14,29 +14,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
14 14
 #include <time.h>
15 15
 #include <ipxe/asn1.h>
16 16
 
17
-/** An X.509 algorithm */
18
-struct x509_algorithm {
19
-	/** Name */
20
-	const char *name;
21
-	/** Object identifier */
22
-	struct asn1_cursor oid;
23
-	/** Public-key algorithm */
24
-	struct pubkey_algorithm *pubkey;
25
-	/** Digest algorithm (if applicable) */
26
-	struct digest_algorithm *digest;
27
-};
28
-
29
-/**
30
- * Test if X.509 algorithm is a signature algorithm
31
- *
32
- * @v algorithm		Algorithm
33
- * @ret is_signature	Algorithm is a signature algorithm
34
- */
35
-static inline __attribute__ (( always_inline )) int
36
-x509_is_signature_algorithm ( struct x509_algorithm *algorithm ) {
37
-	return ( algorithm->digest != NULL );
38
-}
39
-
40 17
 /** An X.509 bit string */
41 18
 struct x509_bit_string {
42 19
 	/** Data */
@@ -80,7 +57,7 @@ struct x509_public_key {
80 57
 	/** Raw public key */
81 58
 	struct asn1_cursor raw;
82 59
 	/** Public key algorithm */
83
-	struct x509_algorithm *algorithm;
60
+	struct asn1_algorithm *algorithm;
84 61
 };
85 62
 
86 63
 /** An X.509 certificate subject */
@@ -96,7 +73,7 @@ struct x509_subject {
96 73
 /** An X.509 certificate signature */
97 74
 struct x509_signature {
98 75
 	/** Signature algorithm */
99
-	struct x509_algorithm *algorithm;
76
+	struct asn1_algorithm *algorithm;
100 77
 	/** Signature value */
101 78
 	struct x509_bit_string value;
102 79
 };
@@ -147,7 +124,7 @@ struct x509_certificate {
147 124
 	/** Raw tbsCertificate */
148 125
 	struct asn1_cursor tbs;
149 126
 	/** Signature algorithm */
150
-	struct x509_algorithm *signature_algorithm;
127
+	struct asn1_algorithm *signature_algorithm;
151 128
 	/** Issuer */
152 129
 	struct x509_issuer issuer;
153 130
 	/** Validity */

Loading…
Cancel
Save