Print OCSP single responses
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 8 Dec 2015 20:25:37 +0000 (21:25 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 11 Dec 2015 17:26:53 +0000 (18:26 +0100)
src/libstrongswan/credentials/certificates/certificate_printer.c
src/libstrongswan/credentials/certificates/ocsp_response.h
src/libstrongswan/plugins/x509/x509_ocsp_response.c

index 84dab85..4326950 100644 (file)
@@ -20,6 +20,7 @@
 #include "x509.h"
 #include "crl.h"
 #include "ac.h"
+#include "ocsp_response.h"
 
 #include <asn1/asn1.h>
 #include <asn1/oid.h>
@@ -326,7 +327,6 @@ static void print_crl(private_certificate_printer_t *this, crl_t *crl)
        chunk_t chunk;
        int count = 0;
        bool first;
-       char buf[64];
        x509_cdp_t *cdp;
        FILE *f = this->f;
 
@@ -466,6 +466,63 @@ static void print_ac(private_certificate_printer_t *this, ac_t *ac)
 }
 
 /**
+ * Print OCSP response specific information
+ */
+static void print_ocsp_response(private_certificate_printer_t *this,
+                                                               ocsp_response_t *ocsp_response)
+{
+       enumerator_t *enumerator;
+       chunk_t serialNumber;
+       cert_validation_t status;
+       char *status_text;
+       time_t revocationTime;
+       crl_reason_t *revocationReason;
+       bool first = TRUE;
+       FILE *f = this->f;
+
+       if (this->detailed)
+       {
+               fprintf(f, "  responses: ");
+
+               enumerator = ocsp_response->create_response_enumerator(ocsp_response);
+               while (enumerator->enumerate(enumerator, &serialNumber, &status,
+                                                                        &revocationTime, &revocationReason))
+               {
+                       if (first)
+                       {
+                               first = FALSE;
+                       }
+                       else
+                       {
+                               fprintf(f, "             ");
+                       }
+                       serialNumber = chunk_skip_zero(serialNumber);
+
+                       switch (status)
+                       {
+                               case VALIDATION_GOOD:
+                                       status_text = "good";
+                                       break;
+                               case VALIDATION_REVOKED:
+                                       status_text = "revoked";
+                                       break;
+                               default:
+                                       status_text = "unknown";
+                       }
+                       fprintf(f, "%#B: %s", &serialNumber, status_text);
+
+                       if (status == VALIDATION_REVOKED)
+                       {
+                               fprintf(f, " on %T, %N", &revocationTime, this->utc,
+                                                        crl_reason_names, revocationReason);
+                       }
+                       fprintf(f, "\n");
+               }
+               enumerator->destroy(enumerator);
+       }
+}
+
+/**
  * Print public key information
  */
 static void print_pubkey(private_certificate_printer_t *this, public_key_t *key,
@@ -497,6 +554,7 @@ METHOD(certificate_printer_t, print, void,
        time_t now, notAfter, notBefore;
        certificate_type_t type;
        identification_t *subject;
+       char *t0, *t1, *t2;
        public_key_t *key;
        FILE *f = this->f;
 
@@ -519,7 +577,19 @@ METHOD(certificate_printer_t, print, void,
        cert->get_validity(cert, &now, &notBefore, &notAfter);
        if (notBefore != UNDEFINED_TIME && notAfter != UNDEFINED_TIME)
        {
-               fprintf(f, "  validity:  not before %T, ", &notBefore, this->utc);
+               if (type == CERT_X509_CRL || type == CERT_X509_OCSP_RESPONSE)
+               {
+                       t0 = "update:  ";
+                       t1 = "this on";
+                       t2 = "next on";
+               }
+               else
+               {
+                       t0 = "validity:";
+                       t1 = "not before";
+                       t2 = "not after ";
+               }
+               fprintf(f, "  %s  %s %T, ", t0, t1, &notBefore, this->utc);
                if (now < notBefore)
                {
                        fprintf(f, "not valid yet (valid in %V)\n", &now, &notBefore);
@@ -528,7 +598,7 @@ METHOD(certificate_printer_t, print, void,
                {
                        fprintf(f, "ok\n");
                }
-               fprintf(f, "             not after  %T, ", &notAfter, this->utc);
+               fprintf(f, "             %s %T, ", t2, &notAfter, this->utc);
                if (now > notAfter)
                {
                        fprintf(f, "expired (%V ago)\n", &now, &notAfter);
@@ -551,6 +621,8 @@ METHOD(certificate_printer_t, print, void,
                        print_ac(this, (ac_t*)cert);
                        break;
                case CERT_X509_OCSP_RESPONSE:
+                       print_ocsp_response(this, (ocsp_response_t*)cert);
+                       break;
                case CERT_TRUSTED_PUBKEY:
                default:
                        break;
index 9c5637b..c6a4c12 100644 (file)
@@ -77,6 +77,13 @@ struct ocsp_response_t {
         * @return                                      enumerator over certificate_t*
         */
        enumerator_t* (*create_cert_enumerator)(ocsp_response_t *this);
+
+       /**
+        * Create an enumerator over the contained responses.
+        *
+        * @return                                      enumerator over major response fields
+        */
+       enumerator_t* (*create_response_enumerator)(ocsp_response_t *this);
 };
 
 #endif /** OCSP_RESPONSE_H_ @}*/
index 60133fc..b46af30 100644 (file)
@@ -1,7 +1,8 @@
 /**
  * Copyright (C) 2008-2009 Martin Willi
- * Copyright (C) 2007-2014 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2007-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
  * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -228,6 +229,42 @@ METHOD(ocsp_response_t, create_cert_enumerator, enumerator_t*,
 }
 
 /**
+ * enumerator filter callback for create_response_enumerator
+ */
+static bool filter(void *data, single_response_t **response,
+                                  chunk_t *serialNumber,
+                                  void *p2, cert_validation_t *status,
+                                  void *p3, time_t *revocationTime,
+                                  void *p4, crl_reason_t *revocationReason)
+{
+       if (serialNumber)
+       {
+               *serialNumber = (*response)->serialNumber;
+       }
+       if (status)
+       {
+               *status = (*response)->status;
+       }
+       if (revocationTime)
+       {
+               *revocationTime = (*response)->revocationTime;
+       }
+       if (revocationReason)
+       {
+               *revocationReason = (*response)->revocationReason;
+       }
+       return TRUE;
+}
+
+METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*,
+       private_x509_ocsp_response_t *this)
+{
+       return enumerator_create_filter(
+                               this->responses->create_enumerator(this->responses),
+                               (void*)filter, NULL, NULL);
+}
+
+/**
  * ASN.1 definition of singleResponse
  */
 static const asn1Object_t singleResponseObjects[] = {
@@ -828,6 +865,7 @@ static x509_ocsp_response_t *load(chunk_t blob)
                                },
                                .get_status = _get_status,
                                .create_cert_enumerator = _create_cert_enumerator,
+                               .create_response_enumerator = _create_response_enumerator,
                        },
                },
                .ref = 1,