Browse Source

[crypto] Parse OCSP responder URI from X.509 certificate

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
601cb3610f
4 changed files with 194 additions and 11 deletions
  1. 142
    6
      src/crypto/x509.c
  2. 17
    0
      src/include/ipxe/asn1.h
  3. 34
    4
      src/include/ipxe/x509.h
  4. 1
    1
      src/net/tls.c

+ 142
- 6
src/crypto/x509.c View File

487
  * @ret rc		Return status code
487
  * @ret rc		Return status code
488
  */
488
  */
489
 static int x509_parse_common_name ( struct x509_certificate *cert,
489
 static int x509_parse_common_name ( struct x509_certificate *cert,
490
-				    struct x509_name *name,
490
+				    struct x509_string *name,
491
 				    const struct asn1_cursor *raw ) {
491
 				    const struct asn1_cursor *raw ) {
492
 	struct asn1_cursor cursor;
492
 	struct asn1_cursor cursor;
493
 	struct asn1_cursor oid_cursor;
493
 	struct asn1_cursor oid_cursor;
533
 static int x509_parse_subject ( struct x509_certificate *cert,
533
 static int x509_parse_subject ( struct x509_certificate *cert,
534
 				const struct asn1_cursor *raw ) {
534
 				const struct asn1_cursor *raw ) {
535
 	struct x509_subject *subject = &cert->subject;
535
 	struct x509_subject *subject = &cert->subject;
536
-	struct x509_name *name = &subject->name;
536
+	struct x509_string *name = &subject->name;
537
 	int rc;
537
 	int rc;
538
 
538
 
539
 	/* Record raw subject */
539
 	/* Record raw subject */
750
 	memcpy ( &cursor, raw, sizeof ( cursor ) );
750
 	memcpy ( &cursor, raw, sizeof ( cursor ) );
751
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
751
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
752
 
752
 
753
-	/* Parse each extension in turn */
753
+	/* Parse each extended key usage in turn */
754
 	while ( cursor.len ) {
754
 	while ( cursor.len ) {
755
 		if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
755
 		if ( ( rc = x509_parse_key_purpose ( cert, &cursor ) ) != 0 )
756
 			return rc;
756
 			return rc;
760
 	return 0;
760
 	return 0;
761
 }
761
 }
762
 
762
 
763
+/**
764
+ * Parse X.509 certificate OCSP access method
765
+ *
766
+ * @v cert		X.509 certificate
767
+ * @v raw		ASN.1 cursor
768
+ * @ret rc		Return status code
769
+ */
770
+static int x509_parse_ocsp ( struct x509_certificate *cert,
771
+			     const struct asn1_cursor *raw ) {
772
+	struct x509_ocsp_responder *ocsp = &cert->extensions.auth_info.ocsp;
773
+	struct asn1_cursor cursor;
774
+	int rc;
775
+
776
+	/* Enter accessLocation */
777
+	memcpy ( &cursor, raw, sizeof ( cursor ) );
778
+	if ( ( rc = asn1_enter ( &cursor, ASN1_IMPLICIT_TAG ( 6 ) ) ) != 0 ) {
779
+		DBGC ( cert, "X509 %p OCSP does not contain "
780
+		       "uniformResourceIdentifier:\n", cert );
781
+		DBGC_HDA ( cert, 0, raw->data, raw->len );
782
+		return rc;
783
+	}
784
+
785
+	/* Record URI */
786
+	ocsp->uri.data = cursor.data;
787
+	ocsp->uri.len = cursor.len;
788
+	DBGC ( cert, "X509 %p OCSP URI is:\n", cert );
789
+	DBGC_HDA ( cert, 0, ocsp->uri.data, ocsp->uri.len );
790
+
791
+	return 0;
792
+}
793
+
794
+/** "id-ad-ocsp" object identifier */
795
+static uint8_t oid_ad_ocsp[] = { ASN1_OID_OCSP };
796
+
797
+/** Supported access methods */
798
+static struct x509_access_method x509_access_methods[] = {
799
+	{
800
+		.name = "OCSP",
801
+		.oid = ASN1_OID_CURSOR ( oid_ad_ocsp ),
802
+		.parse = x509_parse_ocsp,
803
+	},
804
+};
805
+
806
+/**
807
+ * Identify X.509 access method by OID
808
+ *
809
+ * @v oid		OID
810
+ * @ret method		Access method, or NULL
811
+ */
812
+static struct x509_access_method *
813
+x509_find_access_method ( const struct asn1_cursor *oid ) {
814
+	struct x509_access_method *method;
815
+	unsigned int i;
816
+
817
+	for ( i = 0 ; i < ( sizeof ( x509_access_methods ) /
818
+			    sizeof ( x509_access_methods[0] ) ) ; i++ ) {
819
+		method = &x509_access_methods[i];
820
+		if ( asn1_compare ( &method->oid, oid ) == 0 )
821
+			return method;
822
+	}
823
+
824
+	return NULL;
825
+}
826
+
827
+/**
828
+ * Parse X.509 certificate access description
829
+ *
830
+ * @v cert		X.509 certificate
831
+ * @v raw		ASN.1 cursor
832
+ * @ret rc		Return status code
833
+ */
834
+static int x509_parse_access_description ( struct x509_certificate *cert,
835
+					   const struct asn1_cursor *raw ) {
836
+	struct asn1_cursor cursor;
837
+	struct asn1_cursor subcursor;
838
+	struct x509_access_method *method;
839
+	int rc;
840
+
841
+	/* Enter keyPurposeId */
842
+	memcpy ( &cursor, raw, sizeof ( cursor ) );
843
+	asn1_enter ( &cursor, ASN1_SEQUENCE );
844
+
845
+	/* Try to identify access method */
846
+	memcpy ( &subcursor, &cursor, sizeof ( subcursor ) );
847
+	asn1_enter ( &subcursor, ASN1_OID );
848
+	method = x509_find_access_method ( &subcursor );
849
+	asn1_skip_any ( &cursor );
850
+	DBGC ( cert, "X509 %p found access method %s\n",
851
+	       cert, ( method ? method->name : "<unknown>" ) );
852
+
853
+	/* Parse access location, if applicable */
854
+	if ( method && ( ( rc = method->parse ( cert, &cursor ) ) != 0 ) )
855
+		return rc;
856
+
857
+	return 0;
858
+}
859
+
860
+/**
861
+ * Parse X.509 certificate authority information access
862
+ *
863
+ * @v cert		X.509 certificate
864
+ * @v raw		ASN.1 cursor
865
+ * @ret rc		Return status code
866
+ */
867
+static int x509_parse_authority_info_access ( struct x509_certificate *cert,
868
+					      const struct asn1_cursor *raw ) {
869
+	struct asn1_cursor cursor;
870
+	int rc;
871
+
872
+	/* Enter authorityInfoAccess */
873
+	memcpy ( &cursor, raw, sizeof ( cursor ) );
874
+	asn1_enter ( &cursor, ASN1_SEQUENCE );
875
+
876
+	/* Parse each access description in turn */
877
+	while ( cursor.len ) {
878
+		if ( ( rc = x509_parse_access_description ( cert,
879
+							    &cursor ) ) != 0 )
880
+			return rc;
881
+		asn1_skip_any ( &cursor );
882
+	}
883
+
884
+	return 0;
885
+}
886
+
763
 /** "id-ce-basicConstraints" object identifier */
887
 /** "id-ce-basicConstraints" object identifier */
764
-static uint8_t oid_ce_basic_constraints[] = { ASN1_OID_BASICCONSTRAINTS };
888
+static uint8_t oid_ce_basic_constraints[] =
889
+	{ ASN1_OID_BASICCONSTRAINTS };
765
 
890
 
766
 /** "id-ce-keyUsage" object identifier */
891
 /** "id-ce-keyUsage" object identifier */
767
-static uint8_t oid_ce_key_usage[] = { ASN1_OID_KEYUSAGE };
892
+static uint8_t oid_ce_key_usage[] =
893
+	{ ASN1_OID_KEYUSAGE };
768
 
894
 
769
 /** "id-ce-extKeyUsage" object identifier */
895
 /** "id-ce-extKeyUsage" object identifier */
770
-static uint8_t oid_ce_ext_key_usage[] = { ASN1_OID_EXTKEYUSAGE };
896
+static uint8_t oid_ce_ext_key_usage[] =
897
+	{ ASN1_OID_EXTKEYUSAGE };
898
+
899
+/** "id-pe-authorityInfoAccess" object identifier */
900
+static uint8_t oid_pe_authority_info_access[] =
901
+	{ ASN1_OID_AUTHORITYINFOACCESS };
771
 
902
 
772
 /** Supported certificate extensions */
903
 /** Supported certificate extensions */
773
 static struct x509_extension x509_extensions[] = {
904
 static struct x509_extension x509_extensions[] = {
786
 		.oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
917
 		.oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
787
 		.parse = x509_parse_extended_key_usage,
918
 		.parse = x509_parse_extended_key_usage,
788
 	},
919
 	},
920
+	{
921
+		.name = "authorityInfoAccess",
922
+		.oid = ASN1_OID_CURSOR ( oid_pe_authority_info_access ),
923
+		.parse = x509_parse_authority_info_access,
924
+	},
789
 };
925
 };
790
 
926
 
791
 /**
927
 /**

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

53
 /** ASN.1 set */
53
 /** ASN.1 set */
54
 #define ASN1_SET 0x31
54
 #define ASN1_SET 0x31
55
 
55
 
56
+/** ASN.1 implicit tag */
57
+#define ASN1_IMPLICIT_TAG( number) ( 0x80 | (number) )
58
+
56
 /** ASN.1 explicit tag */
59
 /** ASN.1 explicit tag */
57
 #define ASN1_EXPLICIT_TAG( number) ( 0xa0 | (number) )
60
 #define ASN1_EXPLICIT_TAG( number) ( 0xa0 | (number) )
58
 
61
 
158
 	ASN1_OID_TRIPLE ( 113549 ), ASN1_OID_SINGLE ( 1 ),	\
161
 	ASN1_OID_TRIPLE ( 113549 ), ASN1_OID_SINGLE ( 1 ),	\
159
 	ASN1_OID_SINGLE ( 7 ), ASN1_OID_SINGLE ( 2 )
162
 	ASN1_OID_SINGLE ( 7 ), ASN1_OID_SINGLE ( 2 )
160
 
163
 
164
+/** ASN.1 OID for id-pe-authorityInfoAccess (1.3.6.1.5.5.7.1.1) */
165
+#define ASN1_OID_AUTHORITYINFOACCESS				\
166
+	ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_SINGLE ( 6 ),	\
167
+	ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 5 ),		\
168
+	ASN1_OID_SINGLE ( 5 ), ASN1_OID_SINGLE ( 7 ),		\
169
+	ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 1 )
170
+
171
+/** ASN.1 OID for id-ad-ocsp (1.3.6.1.5.5.7.48.1) */
172
+#define ASN1_OID_OCSP						\
173
+	ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_SINGLE ( 6 ),	\
174
+	ASN1_OID_SINGLE ( 1 ), ASN1_OID_SINGLE ( 5 ),		\
175
+	ASN1_OID_SINGLE ( 5 ), ASN1_OID_SINGLE ( 7 ),		\
176
+	ASN1_OID_SINGLE ( 48 ), ASN1_OID_SINGLE ( 1 )
177
+
161
 /** Define an ASN.1 cursor containing an OID */
178
 /** Define an ASN.1 cursor containing an OID */
162
 #define ASN1_OID_CURSOR( oid_value ) {				\
179
 #define ASN1_OID_CURSOR( oid_value ) {				\
163
 		.data = oid_value,				\
180
 		.data = oid_value,				\

+ 34
- 4
src/include/ipxe/x509.h View File

50
 	struct x509_time not_after;
50
 	struct x509_time not_after;
51
 };
51
 };
52
 
52
 
53
-/** An X.509 name */
54
-struct x509_name {
55
-	/** Name (not NUL-terminated) */
53
+/** An X.509 string */
54
+struct x509_string {
55
+	/** String (not NUL-terminated) */
56
 	const void *data;
56
 	const void *data;
57
 	/** Length of name */
57
 	/** Length of name */
58
 	size_t len;
58
 	size_t len;
71
 	/** Raw subject */
71
 	/** Raw subject */
72
 	struct asn1_cursor raw;
72
 	struct asn1_cursor raw;
73
 	/** Common name */
73
 	/** Common name */
74
-	struct x509_name name;
74
+	struct x509_string name;
75
 	/** Public key information */
75
 	/** Public key information */
76
 	struct x509_public_key public_key;
76
 	struct x509_public_key public_key;
77
 };
77
 };
128
 	X509_CODE_SIGNING = 0x0001,
128
 	X509_CODE_SIGNING = 0x0001,
129
 };
129
 };
130
 
130
 
131
+/** X.509 certificate OCSP responder */
132
+struct x509_ocsp_responder {
133
+	/** URI */
134
+	struct x509_string uri;
135
+};
136
+
137
+/** X.509 certificate authority information access */
138
+struct x509_authority_info_access {
139
+	/** OCSP responder */
140
+	struct x509_ocsp_responder ocsp;
141
+};
142
+
131
 /** An X.509 certificate extensions set */
143
 /** An X.509 certificate extensions set */
132
 struct x509_extensions {
144
 struct x509_extensions {
133
 	/** Basic constraints */
145
 	/** Basic constraints */
136
 	struct x509_key_usage usage;
148
 	struct x509_key_usage usage;
137
 	/** Extended key usage */
149
 	/** Extended key usage */
138
 	struct x509_extended_key_usage ext_usage;
150
 	struct x509_extended_key_usage ext_usage;
151
+	/** Authority information access */
152
+	struct x509_authority_info_access auth_info;
139
 };
153
 };
140
 
154
 
141
 /** An X.509 certificate */
155
 /** An X.509 certificate */
188
 	unsigned int bits;
202
 	unsigned int bits;
189
 };
203
 };
190
 
204
 
205
+/** An X.509 access method */
206
+struct x509_access_method {
207
+	/** Name */
208
+	const char *name;
209
+	/** Object identifier */
210
+	struct asn1_cursor oid;
211
+	/** Parse access method
212
+	 *
213
+	 * @v cert		X.509 certificate
214
+	 * @v raw		ASN.1 cursor
215
+	 * @ret rc		Return status code
216
+	 */
217
+	int ( * parse ) ( struct x509_certificate *cert,
218
+			  const struct asn1_cursor *raw );
219
+};
220
+
191
 /** An X.509 root certificate store */
221
 /** An X.509 root certificate store */
192
 struct x509_root {
222
 struct x509_root {
193
 	/** Fingerprint digest algorithm */
223
 	/** Fingerprint digest algorithm */

+ 1
- 1
src/net/tls.c View File

1347
 	struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1347
 	struct pubkey_algorithm *pubkey = cipherspec->suite->pubkey;
1348
 	struct tls_certificate_context context;
1348
 	struct tls_certificate_context context;
1349
 	struct x509_certificate cert;
1349
 	struct x509_certificate cert;
1350
-	struct x509_name *name = &cert.subject.name;
1350
+	struct x509_string *name = &cert.subject.name;
1351
 	struct x509_public_key *key = &cert.subject.public_key;
1351
 	struct x509_public_key *key = &cert.subject.public_key;
1352
 	time_t now;
1352
 	time_t now;
1353
 	int rc;
1353
 	int rc;

Loading…
Cancel
Save