--- src/verify.c.old	2008-05-18 00:03:44.000000000 +0200
+++ src/verify.c	2008-05-18 12:51:12.000000000 +0200
@@ -50,6 +50,9 @@
 static int crl_check(CLI *c, X509_STORE_CTX *, char *);
 static int ocsp_check(CLI *c, X509_STORE_CTX *, char *);
 
+/* utility functions */
+static void log_time(const int, const char *, ASN1_TIME *);
+
 /**************************************** verify initialization */
 
 void verify_init(LOCAL_OPTIONS *section) {
@@ -57,8 +60,8 @@
         return; /* No certificate verification */
 
     if(section->verify_level>1 && !section->ca_file && !section->ca_dir) {
-        s_log(LOG_ERR, "Either CApath or CAfile "
-            "has to be used for authentication");
+        s_log(LOG_ERR,
+            "Either CApath or CAfile has to be used for authentication");
         die(1);
     }
 
@@ -183,7 +186,7 @@
     X509_OBJECT ret;
 
     if(c->opt->verify_level==SSL_VERIFY_NONE) {
-        s_log(LOG_NOTICE, "VERIFY IGNORE: depth=%d, %s",
+        s_log(LOG_INFO, "VERIFY IGNORE: depth=%d, %s",
             callback_ctx->error_depth, subject_name);
         return 1; /* accept connection */
     }
@@ -219,11 +222,9 @@
     X509_REVOKED *revoked;
     EVP_PKEY *pubkey;
     long serial;
-    BIO *bio;
     int i, n, rc;
     char *cp;
-    char *cp2;
-    ASN1_TIME *t;
+    ASN1_TIME *last_update=NULL, *next_update=NULL;
 
     /* determine certificate ingredients in advance */
     cert=X509_STORE_CTX_get_current_cert(callback_ctx);
@@ -238,22 +239,13 @@
     X509_STORE_CTX_cleanup(&store_ctx);
     crl=obj.data.crl;
     if(rc>0 && crl) {
-        /* log information about CRL
-         * (a little bit complicated because of ASN.1 and BIOs...) */
-        bio=BIO_new(BIO_s_mem());
-        BIO_printf(bio, "lastUpdate: ");
-        ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl));
-        BIO_printf(bio, ", nextUpdate: ");
-        ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl));
-        n=BIO_pending(bio);
-        cp=malloc(n+1);
-        n=BIO_read(bio, cp, n);
-        cp[n]='\0';
-        BIO_free(bio);
-        cp2=X509_NAME_oneline(subject, NULL, 0);
-        s_log(LOG_NOTICE, "CA CRL: Issuer: %s, %s", cp2, cp);
-        OPENSSL_free(cp2);
-        free(cp);
+        last_update=X509_CRL_get_lastUpdate(crl);
+        next_update=X509_CRL_get_nextUpdate(crl);
+        cp=X509_NAME_oneline(subject, NULL, 0);
+        s_log(LOG_INFO, "CRL: issuer: %s", cp);
+        OPENSSL_free(cp);
+        log_time(LOG_INFO, "CRL: last update", last_update);
+        log_time(LOG_INFO, "CRL: next update", next_update);
 
         /* verify the signature on this CRL */
         pubkey=X509_get_pubkey(cert);
@@ -270,15 +262,14 @@
             EVP_PKEY_free(pubkey);
 
         /* check date of CRL to make sure it's not expired */
-        t=X509_CRL_get_nextUpdate(crl);
-        if(!t) {
+        if(!next_update) {
             s_log(LOG_WARNING, "Found CRL has invalid nextUpdate field");
             X509_STORE_CTX_set_error(callback_ctx,
                 X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
             X509_OBJECT_free_contents(&obj);
             return 0; /* reject connection */
         }
-        if(X509_cmp_current_time(t)<0) {
+        if(X509_cmp_current_time(next_update)<0) {
             s_log(LOG_WARNING, "Found CRL is expired - "
                 "revoking all certificates until you get updated CRL");
             X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
@@ -312,7 +303,7 @@
                     X509_get_serialNumber(cert)) == 0) {
                 serial=ASN1_INTEGER_get(revoked->serialNumber);
                 cp=X509_NAME_oneline(issuer, NULL, 0);
-                s_log(LOG_NOTICE, "Certificate with serial %ld (0x%lX) "
+                s_log(LOG_WARNING, "Certificate with serial %ld (0x%lX) "
                     "revoked per CRL from issuer %s", serial, serial, cp);
                 OPENSSL_free(cp);
                 X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED);
@@ -322,6 +313,7 @@
         }
         X509_OBJECT_free_contents(&obj);
     }
+    s_log(LOG_NOTICE, "CRL: verification passed");
     return 1; /* accept connection */
 }
 
@@ -339,11 +331,12 @@
     OCSP_REQUEST *request=NULL;
     OCSP_RESPONSE *response=NULL;
     OCSP_BASICRESP *basicResponse=NULL;
-    ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update;
+    ASN1_GENERALIZEDTIME *revoked_at=NULL,
+        *this_update=NULL, *next_update=NULL;
     int status, reason;
 
     /* TODO: check OCSP server specified in the certificate */
-    s_log(LOG_DEBUG, "Starting OCSP verification");
+    s_log(LOG_DEBUG, "OCSP: starting verification");
 
     /* connect specified OCSP server (responder) */
     if((c->fd=
@@ -363,7 +356,7 @@
         if(connect_wait(c))
             goto cleanup;
     }
-    s_log(LOG_DEBUG, "OCSP server connected");
+    s_log(LOG_DEBUG, "OCSP: server connected");
 
     /* get current certificate ID */
     cert=X509_STORE_CTX_get_current_cert(callback_ctx); /* get current cert */
@@ -402,11 +395,11 @@
     }
     error=OCSP_response_status(response);
     if(error!=OCSP_RESPONSE_STATUS_SUCCESSFUL) {
-        s_log(LOG_ERR, "Responder Error: %s (%d)",
-            OCSP_response_status_str(error), error);
+        s_log(LOG_WARNING, "OCSP: responder error: %d: %s",
+            error, OCSP_response_status_str(error));
         goto cleanup;
     }
-    s_log(LOG_INFO, "OCSP response received");
+    s_log(LOG_DEBUG, "OCSP: response received");
 
     /* verify the response */
     basicResponse=OCSP_response_get1_basic(response);
@@ -423,15 +416,32 @@
         sslerror("OCSP_basic_verify");
         goto cleanup;
     }
-    if(OCSP_resp_find_status(basicResponse, certID, &status, &reason,
-            &produced_at, &this_update, &next_update)==0) {
+    if(!OCSP_resp_find_status(basicResponse, certID, &status, &reason,
+            &revoked_at, &this_update, &next_update)) {
         sslerror("OCSP_resp_find_status");
         goto cleanup;
     }
+    s_log(LOG_NOTICE, "OCSP: status: %d: %s",
+        status, OCSP_cert_status_str(status));
+    log_time(LOG_INFO, "OCSP: this update", this_update);
+    log_time(LOG_INFO, "OCSP: next update", next_update);
+    /* check if the response is valid for at least one minute */
+    if(!OCSP_check_validity(this_update, next_update, 60, -1)) {
+        sslerror("OCSP_check_validity");
+        goto cleanup;
+    }
+    if(status==V_OCSP_CERTSTATUS_REVOKED) {
+        if(reason==-1)
+            s_log(LOG_WARNING, "OCSP: certificate revoked");
+        else
+            s_log(LOG_WARNING, "OCSP: certificate revoked: %d: %s",
+                reason, OCSP_crl_reason_str(reason));
+        log_time(LOG_NOTICE, "OCSP: revoked at", revoked_at);
+        goto cleanup;
+    }
 
     /* success */
-    s_log(LOG_INFO, "OCSP verification passed: status=%d, reason=%d",
-        status, reason);
+    s_log(LOG_NOTICE, "OCSP: verification passed");
     retval=1; /* accept connection */
 cleanup:
     if(bio)
@@ -450,4 +460,22 @@
 }
 #endif /* OpenSSL-0.9.7 */
 
+static void log_time(const int level, const char *txt, ASN1_TIME *t) {
+    char *cp;
+    BIO *bio;
+    int n;
+
+    if(!t)
+        return;
+    bio=BIO_new(BIO_s_mem());
+    ASN1_TIME_print(bio, t);
+    n=BIO_pending(bio);
+    cp=malloc(n+1);
+    n=BIO_read(bio, cp, n);
+    cp[n]='\0';
+    BIO_free(bio);
+    s_log(level, "%s: %s", txt, cp);
+    free(cp);
+}
+
 /* End of verify.c */
