[xmlsec] support expired certs check



commit 2615bc3d850d44efb795990431dfa8f6e368d173
Author: Aleksey Sanin <aleksey aleksey com>
Date:   Mon May 24 15:39:13 2010 -0700

    support expired certs check

 TODO                 |    9 +-
 src/gnutls/x509vfy.c |  286 +++++++++++++++-----------------------------------
 2 files changed, 90 insertions(+), 205 deletions(-)
---
diff --git a/TODO b/TODO
index c5d0bd5..1790957 100644
--- a/TODO
+++ b/TODO
@@ -68,18 +68,16 @@ aleksey-xmldsig-01/enveloped-gost
 * xmlsec-gnutls (May 24, 2010 using GnuTLS)
 -------------------------------------------------
 
-** Skipped tests due to missing transforms: RSA, DSA, RSA PKCS/OAEP, GOST
+** Skipped tests due to missing transforms: RSA PKCS/OAEP, GOST
 
 aleksey-xmldsig-01/enveloping-sha224-hmac-sha224
 aleksey-xmldsig-01/enveloping-sha224-hmac-sha224-64
 aleksey-xmldsig-01/enveloping-sha224-rsa-sha224
+merlin-xmlenc-five/encrypt-element-aes128-cbc-rsa-1_5
+merlin-xmlenc-five/encrypt-data-tripledes-cbc-rsa-oaep-mgf1p
 aleksey-xmldsig-01/enveloped-gost
-
-aleksey-xmldsig-01/enveloping-expired-cert
 phaos-xmldsig-three/signature-rsa-manifest-x509-data-crl
 
-merlin-xmlenc-five/encrypt-element-aes128-cbc-rsa-1_5
-merlin-xmlenc-five/encrypt-data-tripledes-cbc-rsa-oaep-mgf1p
 01-phaos-xmlenc-3/enc-element-3des-kt-rsa1_5
 01-phaos-xmlenc-3/enc-element-3des-kt-rsa_oaep_sha1
 01-phaos-xmlenc-3/enc-element-aes128-kt-rsa1_5
@@ -90,6 +88,7 @@ merlin-xmlenc-five/encrypt-data-tripledes-cbc-rsa-oaep-mgf1p
 01-phaos-xmlenc-3/enc-text-aes256-kt-rsa_oaep_sha1
 
 ** Failed tests due to no support for CRLs in XML document
+
 merlin-xmldsig-twenty-three/signature-x509-crt-crl
 
 -------------------------------------------------
diff --git a/src/gnutls/x509vfy.c b/src/gnutls/x509vfy.c
index e9ac28d..27f83f0 100644
--- a/src/gnutls/x509vfy.c
+++ b/src/gnutls/x509vfy.c
@@ -140,6 +140,65 @@ xmlSecGnuTLSX509StoreFindCert(xmlSecKeyDataStorePtr store,
     return(res);
 }
 
+static int
+xmlSecGnuTLSX509CheckTime(const gnutls_x509_crt_t * cert_list,
+                          xmlSecSize cert_list_length,
+                          time_t ts)
+{
+    time_t notValidBefore, notValidAfter;
+    xmlSecSize ii;
+
+    xmlSecAssert2(cert_list != NULL, -1);
+
+    for(ii = 0; ii < cert_list_length; ++ii) {
+        const gnutls_x509_crt_t cert = cert_list[ii];
+        if(cert == NULL) {
+            continue;
+        }
+
+        /* get expiration times */
+        notValidBefore = gnutls_x509_crt_get_activation_time(cert);
+        if(notValidBefore == (time_t)-1) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "gnutls_x509_crt_get_activation_time",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        XMLSEC_ERRORS_NO_MESSAGE);
+            return(-1);
+        }
+        notValidAfter = gnutls_x509_crt_get_expiration_time(cert);
+        if(notValidAfter == (time_t)-1) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "gnutls_x509_crt_get_expiration_time",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        XMLSEC_ERRORS_NO_MESSAGE);
+            return(-1);
+       }
+
+        /* check */
+        if(ts < notValidBefore) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        NULL,
+                        XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,
+                        XMLSEC_ERRORS_NO_MESSAGE);
+            return(0);
+        }
+        if(ts > notValidAfter) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        NULL,
+                        XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,
+                        XMLSEC_ERRORS_NO_MESSAGE);
+            return(0);
+        }
+    }
+
+    /* GOOD! */
+    return(1);
+}
+
 /**
  * xmlSecGnuTLSX509StoreVerify:
  * @store:              the pointer to X509 key data store klass.
@@ -161,7 +220,10 @@ xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store,
     xmlSecSize cert_list_length;
     gnutls_x509_crt_t * ca_list = NULL;
     xmlSecSize ca_list_length;
+    time_t verification_time;
+    unsigned int flags = 0;
     xmlSecSize ii;
+    int ret;
     int err;
 
     xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), NULL);
@@ -214,6 +276,13 @@ xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store,
         }
     }
 
+    /* gnutls doesn't allow to specify "verification" timestamp so
+       we have to do it ourselves */
+    verification_time = (keyInfoCtx->certsVerificationTime > 0) ?
+                        keyInfoCtx->certsVerificationTime :
+                        time(0);
+    flags |= GNUTLS_VERIFY_DISABLE_TIME_CHECKS;
+
     /* We are going to build all possible cert chains and try to verify them */
     for(ii = 0; (ii < certs_size) && (res == NULL); ++ii) {
         gnutls_x509_crt_t cert, cert2;
@@ -258,45 +327,37 @@ xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store,
                 cert_list, (int)cert_list_cur_length, /* certs chain */
                 ca_list, (int)ca_list_length, /* trusted cas */
                 NULL, 0, /* crls */
-                0, /* flags */
+                flags, /* flags */
                 &verify);
-        if(err == GNUTLS_E_SUCCESS) {
-            /* TODO: check the timestamp */
-            res = cert;
-        } else {
+        if(err != GNUTLS_E_SUCCESS) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
                         "gnutls_x509_crt_list_verify",
                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
                         XMLSEC_GNUTLS_REPORT_ERROR(err));
             /* don't stop, continue! */
+            continue;
         }
-    }
 
-    /*
-    for(ii = 0; ii < certs.size; ++ii) {
-        cert = certs[ii];
-        if(find(certs, where issuer = cert.subj)) {
-            continue; // this is not the "leaf" of a certs chain!
-        }
-        // build chain
-        for(cert2 = cert; ; ) {
-            put cert2 into certsChain;
-            cert2 = find(certs, where subject = cert2.issuer);
-            if(cert2 == NULL) {
-                cert2 = find(untrusted certs from store, where subject = cert2.issuer);
-            }
+        /* gnutls doesn't allow to specify "verification" timestamp so
+           we have to do it ourselves */
+        ret = xmlSecGnuTLSX509CheckTime(cert_list, cert_list_cur_length, verification_time);
+        if(ret != 1) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        "Time verification failed");
+            /* don't stop, continue! */
+            continue;
         }
-        if(gnutls_x509_crt_list_verify(certsChain, trusted certs from store)) {
-            // we found it!
-            cert is the key cert;
 
-            // manually check certs time if specified 
-        }
+        /* DONE! */
+        res = cert;
     }
-    */
 
 done:
+    /* cleanup */
     if(ca_list != NULL) {
         xmlFree(ca_list);
     }
@@ -305,181 +366,6 @@ done:
     }
 
     return(res);
-
-#ifdef TODO
-    STACK_OF(X509)* certs2 = NULL;
-    X509 * res = NULL;
-    X509 * cert;
-    X509 * err_cert = NULL;
-    char buf[256];
-    int err = 0, depth;
-    int i;
-    int ret;
-
-    /* dup certs */
-    certs2 = sk_X509_dup(certs);
-    if(certs2 == NULL) {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
-                    "sk_X509_dup",
-                    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
-        goto done;
-    }
-
-    /* add untrusted certs from the store */
-    for(i = 0; i < sk_X509_num(ctx->certsUntrusted); ++i) {
-        ret = sk_X509_push(certs2, sk_X509_value(ctx->certsUntrusted, i));
-        if(ret < 1) {
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
-                        "sk_X509_push",
-                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                        XMLSEC_ERRORS_NO_MESSAGE);
-            goto done;
-        }
-    }
-
-    /* TODO: remove all revoked certs */
-
-    /* get one cert after another and try to verify */
-    for(i = 0; i < sk_X509_num(certs2); ++i) {
-        cert = sk_X509_value(certs2, i);
-        if(xmlSecGnuTLSX509FindNextChainCert(certs2, cert) == NULL) {
-            X509_STORE_CTX xsc;
-
-#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
-            X509_VERIFY_PARAM * vpm = NULL;
-            unsigned long vpm_flags = 0;
-
-            vpm = X509_VERIFY_PARAM_new();
-            if(vpm == NULL) {
-                xmlSecError(XMLSEC_ERRORS_HERE,
-                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
-                            "X509_VERIFY_PARAM_new",
-                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                            XMLSEC_ERRORS_NO_MESSAGE);
-                goto done;
-            }
-            vpm_flags = vpm->flags;
-/*
-            vpm_flags &= (~X509_V_FLAG_X509_STRICT);
-*/
-
-            X509_VERIFY_PARAM_set_depth(vpm, 9);
-            X509_VERIFY_PARAM_set_flags(vpm, vpm_flags);
-#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
-
-
-            X509_STORE_CTX_init (&xsc, ctx->xst, cert, certs2);
-
-            if(keyInfoCtx->certsVerificationTime > 0) {
-#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
-                vpm_flags |= X509_V_FLAG_USE_CHECK_TIME;
-                X509_VERIFY_PARAM_set_time(vpm, keyInfoCtx->certsVerificationTime);
-#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
-                X509_STORE_CTX_set_time(&xsc, 0, keyInfoCtx->certsVerificationTime);
-            }
-
-#if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097)
-            X509_STORE_CTX_set0_param(&xsc, vpm);
-#endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */
-
-
-            ret         = X509_verify_cert(&xsc);
-            err_cert    = X509_STORE_CTX_get_current_cert(&xsc);
-            err         = X509_STORE_CTX_get_error(&xsc);
-            depth       = X509_STORE_CTX_get_error_depth(&xsc);
-
-            X509_STORE_CTX_cleanup (&xsc);
-
-            if(ret == 1) {
-                res = cert;
-                goto done;
-            } else if(ret < 0) {
-                const char* err_msg;
-
-                buf[0] = '\0';
-                X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf);
-                err_msg = X509_verify_cert_error_string(err);
-                xmlSecError(XMLSEC_ERRORS_HERE,
-                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
-                            "X509_verify_cert",
-                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                            "subj=%s;err=%d;msg=%s",
-                            xmlSecErrorsSafeString(buf),
-                            err,
-                            xmlSecErrorsSafeString(err_msg));
-                goto done;
-            } else if(ret == 0) {
-                const char* err_msg;
-
-                buf[0] = '\0';
-                X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf);
-                err_msg = X509_verify_cert_error_string(err);
-                xmlSecError(XMLSEC_ERRORS_HERE,
-                            xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
-                            "X509_verify_cert",
-                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                            "subj=%s;err=%d;msg=%s",
-                            xmlSecErrorsSafeString(buf),
-                            err,
-                            xmlSecErrorsSafeString(err_msg));
-            }
-        }
-    }
-
-    /* if we came here then we found nothing. do we have any error? */
-    if((err != 0) && (err_cert != NULL)) {
-        const char* err_msg;
-
-        err_msg = X509_verify_cert_error_string(err);
-        switch (err) {
-        case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
-            X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof buf);
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
-                        NULL,
-                        XMLSEC_ERRORS_R_CERT_ISSUER_FAILED,
-                        "err=%d;msg=%s;issuer=%s",
-                        err,
-                        xmlSecErrorsSafeString(err_msg),
-                        xmlSecErrorsSafeString(buf));
-            break;
-        case X509_V_ERR_CERT_NOT_YET_VALID:
-        case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
-                        NULL,
-                        XMLSEC_ERRORS_R_CERT_NOT_YET_VALID,
-                        "err=%d;msg=%s", err,
-                        xmlSecErrorsSafeString(err_msg));
-            break;
-        case X509_V_ERR_CERT_HAS_EXPIRED:
-        case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
-                        NULL,
-                        XMLSEC_ERRORS_R_CERT_HAS_EXPIRED,
-                        "err=%d;msg=%s", err,
-                        xmlSecErrorsSafeString(err_msg));
-            break;
-        default:
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)),
-                        NULL,
-                        XMLSEC_ERRORS_R_CERT_VERIFY_FAILED,
-                        "err=%d;msg=%s", err,
-                        xmlSecErrorsSafeString(err_msg));
-        }
-    }
-
-done:
-    if(certs2 != NULL) {
-        sk_X509_free(certs2);
-    }
-    return(res);
-#endif /* TODO */
 }
 
 /**



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]