Browse Source

[tls] Check certificate validity period against current date and time

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
8583c323a2
3 changed files with 49 additions and 11 deletions
  1. 41
    7
      src/crypto/x509.c
  2. 5
    3
      src/include/ipxe/x509.h
  3. 3
    1
      src/net/tls.c

+ 41
- 7
src/crypto/x509.c View File

85
 	__einfo_error ( EINFO_EACCES_KEY_USAGE )
85
 	__einfo_error ( EINFO_EACCES_KEY_USAGE )
86
 #define EINFO_EACCES_KEY_USAGE \
86
 #define EINFO_EACCES_KEY_USAGE \
87
 	__einfo_uniqify ( EINFO_EACCES, 0x03, "Incorrect key usage" )
87
 	__einfo_uniqify ( EINFO_EACCES, 0x03, "Incorrect key usage" )
88
+#define EACCES_EXPIRED \
89
+	__einfo_error ( EINFO_EACCES_EXPIRED )
90
+#define EINFO_EACCES_EXPIRED \
91
+	__einfo_uniqify ( EINFO_EACCES, 0x04, "Expired (or not yet valid)" )
88
 
92
 
89
 /** "commonName" object identifier */
93
 /** "commonName" object identifier */
90
 static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
94
 static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
1036
 }
1040
 }
1037
 
1041
 
1038
 /**
1042
 /**
1039
- * Validate X.509 certificate against signing certificate
1043
+ * Validate X.509 certificate against issuer certificate
1040
  *
1044
  *
1041
  * @v cert		X.509 certificate
1045
  * @v cert		X.509 certificate
1042
  * @v issuer		X.509 issuer certificate
1046
  * @v issuer		X.509 issuer certificate
1043
  * @ret rc		Return status code
1047
  * @ret rc		Return status code
1044
  */
1048
  */
1045
-int x509_validate ( struct x509_certificate *cert,
1046
-		    struct x509_certificate *issuer ) {
1049
+int x509_validate_issuer ( struct x509_certificate *cert,
1050
+			   struct x509_certificate *issuer ) {
1047
 	struct x509_public_key *public_key = &issuer->subject.public_key;
1051
 	struct x509_public_key *public_key = &issuer->subject.public_key;
1048
 	int rc;
1052
 	int rc;
1049
 
1053
 
1139
 	return -ENOENT;
1143
 	return -ENOENT;
1140
 }
1144
 }
1141
 
1145
 
1146
+/**
1147
+ * Validate X.509 certificate validity period
1148
+ *
1149
+ * @v cert		X.509 certificate
1150
+ * @v time		Time at which to validate certificate
1151
+ * @ret rc		Return status code
1152
+ */
1153
+int x509_validate_time ( struct x509_certificate *cert, time_t time ) {
1154
+	struct x509_validity *validity = &cert->validity;
1155
+
1156
+	/* Check validity period */
1157
+	if ( time < validity->not_before.time ) {
1158
+		DBGC ( cert, "X509 %p is not yet valid (at time %lld)\n",
1159
+		       cert, time );
1160
+		return -EACCES_EXPIRED;
1161
+	}
1162
+	if ( time > validity->not_after.time ) {
1163
+		DBGC ( cert, "X509 %p has expired (at time %lld)\n",
1164
+		       cert, time );
1165
+		return -EACCES_EXPIRED;
1166
+	}
1167
+
1168
+	DBGC ( cert, "X509 %p is valid (at time %lld)\n", cert, time );
1169
+	return 0;
1170
+}
1171
+
1142
 /**
1172
 /**
1143
  * Validate X.509 certificate chain
1173
  * Validate X.509 certificate chain
1144
  *
1174
  *
1145
  * @v parse_next	Parse next X.509 certificate in chain
1175
  * @v parse_next	Parse next X.509 certificate in chain
1146
  * @v context		Context for parse_next()
1176
  * @v context		Context for parse_next()
1177
+ * @v time		Time at which to validate certificates
1147
  * @v root		Root certificate store, or NULL to use default
1178
  * @v root		Root certificate store, or NULL to use default
1148
  * @v first		Initial X.509 certificate to fill in, or NULL
1179
  * @v first		Initial X.509 certificate to fill in, or NULL
1149
  * @ret rc		Return status code
1180
  * @ret rc		Return status code
1150
  */
1181
  */
1151
 int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert,
1182
 int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert,
1152
 						 void *context ),
1183
 						 void *context ),
1153
-			  void *context,
1154
-			  struct x509_root *root,
1184
+			  void *context, time_t time, struct x509_root *root,
1155
 			  struct x509_certificate *first ) {
1185
 			  struct x509_certificate *first ) {
1156
 	struct x509_certificate temp[2];
1186
 	struct x509_certificate temp[2];
1157
 	struct x509_certificate *current = &temp[0];
1187
 	struct x509_certificate *current = &temp[0];
1177
 	/* Process chain */
1207
 	/* Process chain */
1178
 	while ( 1 ) {
1208
 	while ( 1 ) {
1179
 
1209
 
1210
+		/* Check that certificate is valid at specified time */
1211
+		if ( ( rc = x509_validate_time ( current, time ) ) != 0 )
1212
+			return rc;
1213
+
1180
 		/* Succeed if we have reached a root certificate */
1214
 		/* Succeed if we have reached a root certificate */
1181
 		if ( x509_validate_root ( current, root ) == 0 )
1215
 		if ( x509_validate_root ( current, root ) == 0 )
1182
 			return 0;
1216
 			return 0;
1188
 			return rc;
1222
 			return rc;
1189
 		}
1223
 		}
1190
 
1224
 
1191
-		/* Validate current certificate */
1192
-		if ( ( rc = x509_validate ( current, next ) ) != 0 )
1225
+		/* Validate current certificate against next certificate */
1226
+		if ( ( rc = x509_validate_issuer ( current, next ) ) != 0 )
1193
 			return rc;
1227
 			return rc;
1194
 
1228
 
1195
 		/* Move to next certificate in chain */
1229
 		/* Move to next certificate in chain */

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

204
 
204
 
205
 extern int x509_parse ( struct x509_certificate *cert,
205
 extern int x509_parse ( struct x509_certificate *cert,
206
 			const void *data, size_t len );
206
 			const void *data, size_t len );
207
-extern int x509_validate ( struct x509_certificate *cert,
208
-			   struct x509_certificate *issuer );
207
+extern int x509_validate_issuer ( struct x509_certificate *cert,
208
+				  struct x509_certificate *issuer );
209
 extern void x509_fingerprint ( struct x509_certificate *cert,
209
 extern void x509_fingerprint ( struct x509_certificate *cert,
210
 			       struct digest_algorithm *digest,
210
 			       struct digest_algorithm *digest,
211
 			       void *fingerprint );
211
 			       void *fingerprint );
212
 extern int x509_validate_root ( struct x509_certificate *cert,
212
 extern int x509_validate_root ( struct x509_certificate *cert,
213
 				struct x509_root *root );
213
 				struct x509_root *root );
214
+extern int x509_validate_time ( struct x509_certificate *cert, time_t time );
214
 extern int x509_validate_chain ( int ( * parse_next )
215
 extern int x509_validate_chain ( int ( * parse_next )
215
 				 ( struct x509_certificate *cert,
216
 				 ( struct x509_certificate *cert,
216
 				   void *context ),
217
 				   void *context ),
217
-				 void *context, struct x509_root *root,
218
+				 void *context, time_t time,
219
+				 struct x509_root *root,
218
 				 struct x509_certificate *first );
220
 				 struct x509_certificate *first );
219
 
221
 
220
 #endif /* _IPXE_X509_H */
222
 #endif /* _IPXE_X509_H */

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

1093
 	struct x509_certificate cert;
1093
 	struct x509_certificate cert;
1094
 	struct x509_name *name = &cert.subject.name;
1094
 	struct x509_name *name = &cert.subject.name;
1095
 	struct x509_public_key *key = &cert.subject.public_key;
1095
 	struct x509_public_key *key = &cert.subject.public_key;
1096
+	time_t now;
1096
 	int rc;
1097
 	int rc;
1097
 
1098
 
1098
 	/* Sanity check */
1099
 	/* Sanity check */
1107
 	context.tls = tls;
1108
 	context.tls = tls;
1108
 	context.current = certificate->certificates;
1109
 	context.current = certificate->certificates;
1109
 	context.end = end;
1110
 	context.end = end;
1111
+	now = time ( NULL );
1110
 	if ( ( rc = x509_validate_chain ( tls_parse_next, &context,
1112
 	if ( ( rc = x509_validate_chain ( tls_parse_next, &context,
1111
-					  NULL, &cert ) ) != 0 ) {
1113
+					  now, NULL, &cert ) ) != 0 ) {
1112
 		DBGC ( tls, "TLS %p could not validate certificate chain: %s\n",
1114
 		DBGC ( tls, "TLS %p could not validate certificate chain: %s\n",
1113
 		       tls, strerror ( rc ) );
1115
 		       tls, strerror ( rc ) );
1114
 		return rc;
1116
 		return rc;

Loading…
Cancel
Save