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
 #include <stddef.h>
22
 #include <stddef.h>
23
 #include <string.h>
23
 #include <string.h>
24
 #include <errno.h>
24
 #include <errno.h>
25
+#include <ipxe/tables.h>
25
 #include <ipxe/asn1.h>
26
 #include <ipxe/asn1.h>
26
 
27
 
27
 /** @file
28
 /** @file
341
 	return ( difference ? difference :
342
 	return ( difference ? difference :
342
 		 memcmp ( cursor1->data, cursor2->data, cursor1->len ) );
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
  * RSA is documented in RFC 3447.
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
 /** MD5 digestInfo prefix */
89
 /** MD5 digestInfo prefix */
43
 static const uint8_t rsa_md5_prefix_data[] =
90
 static const uint8_t rsa_md5_prefix_data[] =
44
 	{ RSA_DIGESTINFO_PREFIX ( MD5_DIGEST_SIZE, ASN1_OID_MD5 ) };
91
 	{ RSA_DIGESTINFO_PREFIX ( MD5_DIGEST_SIZE, ASN1_OID_MD5 ) };

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

49
 	__einfo_error ( EINFO_ENOTSUP_EXTENSION )
49
 	__einfo_error ( EINFO_ENOTSUP_EXTENSION )
50
 #define EINFO_ENOTSUP_EXTENSION \
50
 #define EINFO_ENOTSUP_EXTENSION \
51
 	__einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported extension" )
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
 #define EINVAL_BIT_STRING \
56
 #define EINVAL_BIT_STRING \
57
 	__einfo_error ( EINFO_EINVAL_BIT_STRING )
57
 	__einfo_error ( EINFO_EINVAL_BIT_STRING )
58
 #define EINFO_EINVAL_BIT_STRING \
58
 #define EINFO_EINVAL_BIT_STRING \
101
 static struct asn1_cursor oid_common_name_cursor =
101
 static struct asn1_cursor oid_common_name_cursor =
102
 	ASN1_OID_CURSOR ( oid_common_name );
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
  * Parse X.509 certificate algorithm
105
  * Parse X.509 certificate algorithm
170
  *
106
  *
173
  * @v raw		ASN.1 cursor
109
  * @v raw		ASN.1 cursor
174
  * @ret rc		Return status code
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
 				  const struct asn1_cursor *raw ) {
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
 		DBGC_HDA ( cert, 0, raw->data, raw->len );
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
 	return 0;
132
 	return 0;
210
  * @ret rc		Return status code
141
  * @ret rc		Return status code
211
  */
142
  */
212
 static int x509_parse_signature_algorithm ( struct x509_certificate *cert,
143
 static int x509_parse_signature_algorithm ( struct x509_certificate *cert,
213
-					    struct x509_algorithm **algorithm,
144
+					    struct asn1_algorithm **algorithm,
214
 					    const struct asn1_cursor *raw ) {
145
 					    const struct asn1_cursor *raw ) {
215
 	int rc;
146
 	int rc;
216
 
147
 
217
 	/* Parse algorithm */
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
 		return rc;
151
 		return rc;
220
 
152
 
221
 	/* Check algorithm is a signature algorithm */
153
 	/* Check algorithm is a signature algorithm */
222
-	if ( ! x509_is_signature_algorithm ( *algorithm ) ) {
154
+	if ( ! (*algorithm)->digest ) {
223
 		DBGC ( cert, "X509 %p algorithm %s is not a signature "
155
 		DBGC ( cert, "X509 %p algorithm %s is not a signature "
224
 		       "algorithm:\n", cert, (*algorithm)->name );
156
 		       "algorithm:\n", cert, (*algorithm)->name );
225
 		DBGC_HDA ( cert, 0, raw->data, raw->len );
157
 		DBGC_HDA ( cert, 0, raw->data, raw->len );
226
-		return -EINVAL_NON_SIGNATURE;
158
+		return -EINVAL_ALGORITHM;
227
 	}
159
 	}
228
 
160
 
229
 	return 0;
161
 	return 0;
600
 static int x509_parse_public_key ( struct x509_certificate *cert,
532
 static int x509_parse_public_key ( struct x509_certificate *cert,
601
 				   const struct asn1_cursor *raw ) {
533
 				   const struct asn1_cursor *raw ) {
602
 	struct x509_public_key *public_key = &cert->subject.public_key;
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
 	struct asn1_cursor cursor;
536
 	struct asn1_cursor cursor;
605
 	int rc;
537
 	int rc;
606
 
538
 
613
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
545
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
614
 
546
 
615
 	/* Parse algorithm */
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
 		return rc;
550
 		return rc;
618
 	DBGC ( cert, "X509 %p public key algorithm is %s\n",
551
 	DBGC ( cert, "X509 %p public key algorithm is %s\n",
619
 	       cert, (*algorithm)->name );
552
 	       cert, (*algorithm)->name );
866
  */
799
  */
867
 static int x509_parse_tbscertificate ( struct x509_certificate *cert,
800
 static int x509_parse_tbscertificate ( struct x509_certificate *cert,
868
 				       const struct asn1_cursor *raw ) {
801
 				       const struct asn1_cursor *raw ) {
869
-	struct x509_algorithm **algorithm = &cert->signature_algorithm;
802
+	struct asn1_algorithm **algorithm = &cert->signature_algorithm;
870
 	struct asn1_cursor cursor;
803
 	struct asn1_cursor cursor;
871
 	int rc;
804
 	int rc;
872
 
805
 
933
  */
866
  */
934
 int x509_parse ( struct x509_certificate *cert, const void *data, size_t len ) {
867
 int x509_parse ( struct x509_certificate *cert, const void *data, size_t len ) {
935
 	struct x509_signature *signature = &cert->signature;
868
 	struct x509_signature *signature = &cert->signature;
936
-	struct x509_algorithm **signature_algorithm = &signature->algorithm;
869
+	struct asn1_algorithm **signature_algorithm = &signature->algorithm;
937
 	struct x509_bit_string *signature_value = &signature->value;
870
 	struct x509_bit_string *signature_value = &signature->value;
938
 	struct asn1_cursor cursor;
871
 	struct asn1_cursor cursor;
939
 	int rc;
872
 	int rc;
991
 static int x509_check_signature ( struct x509_certificate *cert,
924
 static int x509_check_signature ( struct x509_certificate *cert,
992
 				  struct x509_public_key *public_key ) {
925
 				  struct x509_public_key *public_key ) {
993
 	struct x509_signature *signature = &cert->signature;
926
 	struct x509_signature *signature = &cert->signature;
994
-	struct x509_algorithm *algorithm = signature->algorithm;
927
+	struct asn1_algorithm *algorithm = signature->algorithm;
995
 	struct digest_algorithm *digest = algorithm->digest;
928
 	struct digest_algorithm *digest = algorithm->digest;
996
 	struct pubkey_algorithm *pubkey = algorithm->pubkey;
929
 	struct pubkey_algorithm *pubkey = algorithm->pubkey;
997
 	uint8_t digest_ctx[ digest->ctxsize ];
930
 	uint8_t digest_ctx[ digest->ctxsize ];

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

9
 
9
 
10
 FILE_LICENCE ( GPL2_OR_LATER );
10
 FILE_LICENCE ( GPL2_OR_LATER );
11
 
11
 
12
+#include <stdint.h>
13
+#include <ipxe/tables.h>
14
+
12
 /** An ASN.1 object cursor */
15
 /** An ASN.1 object cursor */
13
 struct asn1_cursor {
16
 struct asn1_cursor {
14
 	/** Start of data */
17
 	/** Start of data */
143
 		.len = sizeof ( oid_value ),			\
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
 /** An ASN.1 boolean */
167
 /** An ASN.1 boolean */
147
 struct asn1_boolean {
168
 struct asn1_boolean {
148
 	/** Value */
169
 	/** Value */
181
 extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
202
 extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
182
 extern int asn1_compare ( const struct asn1_cursor *cursor1,
203
 extern int asn1_compare ( const struct asn1_cursor *cursor1,
183
 			  const struct asn1_cursor *cursor2 );
204
 			  const struct asn1_cursor *cursor2 );
205
+extern struct asn1_algorithm *
206
+asn1_algorithm ( const struct asn1_cursor *cursor );
184
 
207
 
185
 #endif /* _IPXE_ASN1_H */
208
 #endif /* _IPXE_ASN1_H */

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

14
 #include <time.h>
14
 #include <time.h>
15
 #include <ipxe/asn1.h>
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
 /** An X.509 bit string */
17
 /** An X.509 bit string */
41
 struct x509_bit_string {
18
 struct x509_bit_string {
42
 	/** Data */
19
 	/** Data */
80
 	/** Raw public key */
57
 	/** Raw public key */
81
 	struct asn1_cursor raw;
58
 	struct asn1_cursor raw;
82
 	/** Public key algorithm */
59
 	/** Public key algorithm */
83
-	struct x509_algorithm *algorithm;
60
+	struct asn1_algorithm *algorithm;
84
 };
61
 };
85
 
62
 
86
 /** An X.509 certificate subject */
63
 /** An X.509 certificate subject */
96
 /** An X.509 certificate signature */
73
 /** An X.509 certificate signature */
97
 struct x509_signature {
74
 struct x509_signature {
98
 	/** Signature algorithm */
75
 	/** Signature algorithm */
99
-	struct x509_algorithm *algorithm;
76
+	struct asn1_algorithm *algorithm;
100
 	/** Signature value */
77
 	/** Signature value */
101
 	struct x509_bit_string value;
78
 	struct x509_bit_string value;
102
 };
79
 };
147
 	/** Raw tbsCertificate */
124
 	/** Raw tbsCertificate */
148
 	struct asn1_cursor tbs;
125
 	struct asn1_cursor tbs;
149
 	/** Signature algorithm */
126
 	/** Signature algorithm */
150
-	struct x509_algorithm *signature_algorithm;
127
+	struct asn1_algorithm *signature_algorithm;
151
 	/** Issuer */
128
 	/** Issuer */
152
 	struct x509_issuer issuer;
129
 	struct x509_issuer issuer;
153
 	/** Validity */
130
 	/** Validity */

Loading…
Cancel
Save