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,6 +85,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
85 85
 	__einfo_error ( EINFO_EACCES_KEY_USAGE )
86 86
 #define EINFO_EACCES_KEY_USAGE \
87 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 93
 /** "commonName" object identifier */
90 94
 static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
@@ -1036,14 +1040,14 @@ static int x509_check_signature ( struct x509_certificate *cert,
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 1045
  * @v cert		X.509 certificate
1042 1046
  * @v issuer		X.509 issuer certificate
1043 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 1051
 	struct x509_public_key *public_key = &issuer->subject.public_key;
1048 1052
 	int rc;
1049 1053
 
@@ -1139,19 +1143,45 @@ int x509_validate_root ( struct x509_certificate *cert,
1139 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 1173
  * Validate X.509 certificate chain
1144 1174
  *
1145 1175
  * @v parse_next	Parse next X.509 certificate in chain
1146 1176
  * @v context		Context for parse_next()
1177
+ * @v time		Time at which to validate certificates
1147 1178
  * @v root		Root certificate store, or NULL to use default
1148 1179
  * @v first		Initial X.509 certificate to fill in, or NULL
1149 1180
  * @ret rc		Return status code
1150 1181
  */
1151 1182
 int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert,
1152 1183
 						 void *context ),
1153
-			  void *context,
1154
-			  struct x509_root *root,
1184
+			  void *context, time_t time, struct x509_root *root,
1155 1185
 			  struct x509_certificate *first ) {
1156 1186
 	struct x509_certificate temp[2];
1157 1187
 	struct x509_certificate *current = &temp[0];
@@ -1177,6 +1207,10 @@ int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert,
1177 1207
 	/* Process chain */
1178 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 1214
 		/* Succeed if we have reached a root certificate */
1181 1215
 		if ( x509_validate_root ( current, root ) == 0 )
1182 1216
 			return 0;
@@ -1188,8 +1222,8 @@ int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert,
1188 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 1227
 			return rc;
1194 1228
 
1195 1229
 		/* Move to next certificate in chain */

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

@@ -204,17 +204,19 @@ struct x509_root {
204 204
 
205 205
 extern int x509_parse ( struct x509_certificate *cert,
206 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 209
 extern void x509_fingerprint ( struct x509_certificate *cert,
210 210
 			       struct digest_algorithm *digest,
211 211
 			       void *fingerprint );
212 212
 extern int x509_validate_root ( struct x509_certificate *cert,
213 213
 				struct x509_root *root );
214
+extern int x509_validate_time ( struct x509_certificate *cert, time_t time );
214 215
 extern int x509_validate_chain ( int ( * parse_next )
215 216
 				 ( struct x509_certificate *cert,
216 217
 				   void *context ),
217
-				 void *context, struct x509_root *root,
218
+				 void *context, time_t time,
219
+				 struct x509_root *root,
218 220
 				 struct x509_certificate *first );
219 221
 
220 222
 #endif /* _IPXE_X509_H */

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

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

Loading…
Cancel
Save