]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[tls] Check certificate validity period against current date and time
authorMichael Brown <mcb30@ipxe.org>
Mon, 19 Mar 2012 23:04:05 +0000 (23:04 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 19 Mar 2012 23:14:17 +0000 (23:14 +0000)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/crypto/x509.c
src/include/ipxe/x509.h
src/net/tls.c

index 3303ae226fffa9dab61aca684f5083e197020bd5..a11eee6f91f33f05031152305aaa4fb2e6eb6b25 100644 (file)
@@ -85,6 +85,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
        __einfo_error ( EINFO_EACCES_KEY_USAGE )
 #define EINFO_EACCES_KEY_USAGE \
        __einfo_uniqify ( EINFO_EACCES, 0x03, "Incorrect key usage" )
+#define EACCES_EXPIRED \
+       __einfo_error ( EINFO_EACCES_EXPIRED )
+#define EINFO_EACCES_EXPIRED \
+       __einfo_uniqify ( EINFO_EACCES, 0x04, "Expired (or not yet valid)" )
 
 /** "commonName" object identifier */
 static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
@@ -1036,14 +1040,14 @@ static int x509_check_signature ( struct x509_certificate *cert,
 }
 
 /**
- * Validate X.509 certificate against signing certificate
+ * Validate X.509 certificate against issuer certificate
  *
  * @v cert             X.509 certificate
  * @v issuer           X.509 issuer certificate
  * @ret rc             Return status code
  */
-int x509_validate ( struct x509_certificate *cert,
-                   struct x509_certificate *issuer ) {
+int x509_validate_issuer ( struct x509_certificate *cert,
+                          struct x509_certificate *issuer ) {
        struct x509_public_key *public_key = &issuer->subject.public_key;
        int rc;
 
@@ -1139,19 +1143,45 @@ int x509_validate_root ( struct x509_certificate *cert,
        return -ENOENT;
 }
 
+/**
+ * Validate X.509 certificate validity period
+ *
+ * @v cert             X.509 certificate
+ * @v time             Time at which to validate certificate
+ * @ret rc             Return status code
+ */
+int x509_validate_time ( struct x509_certificate *cert, time_t time ) {
+       struct x509_validity *validity = &cert->validity;
+
+       /* Check validity period */
+       if ( time < validity->not_before.time ) {
+               DBGC ( cert, "X509 %p is not yet valid (at time %lld)\n",
+                      cert, time );
+               return -EACCES_EXPIRED;
+       }
+       if ( time > validity->not_after.time ) {
+               DBGC ( cert, "X509 %p has expired (at time %lld)\n",
+                      cert, time );
+               return -EACCES_EXPIRED;
+       }
+
+       DBGC ( cert, "X509 %p is valid (at time %lld)\n", cert, time );
+       return 0;
+}
+
 /**
  * Validate X.509 certificate chain
  *
  * @v parse_next       Parse next X.509 certificate in chain
  * @v context          Context for parse_next()
+ * @v time             Time at which to validate certificates
  * @v root             Root certificate store, or NULL to use default
  * @v first            Initial X.509 certificate to fill in, or NULL
  * @ret rc             Return status code
  */
 int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert,
                                                 void *context ),
-                         void *context,
-                         struct x509_root *root,
+                         void *context, time_t time, struct x509_root *root,
                          struct x509_certificate *first ) {
        struct x509_certificate temp[2];
        struct x509_certificate *current = &temp[0];
@@ -1177,6 +1207,10 @@ int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert,
        /* Process chain */
        while ( 1 ) {
 
+               /* Check that certificate is valid at specified time */
+               if ( ( rc = x509_validate_time ( current, time ) ) != 0 )
+                       return rc;
+
                /* Succeed if we have reached a root certificate */
                if ( x509_validate_root ( current, root ) == 0 )
                        return 0;
@@ -1188,8 +1222,8 @@ int x509_validate_chain ( int ( * parse_next ) ( struct x509_certificate *cert,
                        return rc;
                }
 
-               /* Validate current certificate */
-               if ( ( rc = x509_validate ( current, next ) ) != 0 )
+               /* Validate current certificate against next certificate */
+               if ( ( rc = x509_validate_issuer ( current, next ) ) != 0 )
                        return rc;
 
                /* Move to next certificate in chain */
index f290a76e34067dcf092db5658791fd9373a22a07..925e23f7d3e150af5865dd38de5bfe1e32cae656 100644 (file)
@@ -204,17 +204,19 @@ struct x509_root {
 
 extern int x509_parse ( struct x509_certificate *cert,
                        const void *data, size_t len );
-extern int x509_validate ( struct x509_certificate *cert,
-                          struct x509_certificate *issuer );
+extern int x509_validate_issuer ( struct x509_certificate *cert,
+                                 struct x509_certificate *issuer );
 extern void x509_fingerprint ( struct x509_certificate *cert,
                               struct digest_algorithm *digest,
                               void *fingerprint );
 extern int x509_validate_root ( struct x509_certificate *cert,
                                struct x509_root *root );
+extern int x509_validate_time ( struct x509_certificate *cert, time_t time );
 extern int x509_validate_chain ( int ( * parse_next )
                                 ( struct x509_certificate *cert,
                                   void *context ),
-                                void *context, struct x509_root *root,
+                                void *context, time_t time,
+                                struct x509_root *root,
                                 struct x509_certificate *first );
 
 #endif /* _IPXE_X509_H */
index 276b23577a59b4a1ed1a2227400283bba21b784b..3aefb19de1838640348e553858abd23084c23aab 100644 (file)
@@ -1093,6 +1093,7 @@ static int tls_new_certificate ( struct tls_session *tls,
        struct x509_certificate cert;
        struct x509_name *name = &cert.subject.name;
        struct x509_public_key *key = &cert.subject.public_key;
+       time_t now;
        int rc;
 
        /* Sanity check */
@@ -1107,8 +1108,9 @@ static int tls_new_certificate ( struct tls_session *tls,
        context.tls = tls;
        context.current = certificate->certificates;
        context.end = end;
+       now = time ( NULL );
        if ( ( rc = x509_validate_chain ( tls_parse_next, &context,
-                                         NULL, &cert ) ) != 0 ) {
+                                         now, NULL, &cert ) ) != 0 ) {
                DBGC ( tls, "TLS %p could not validate certificate chain: %s\n",
                       tls, strerror ( rc ) );
                return rc;