#include "config.h"
+#include <curl/curl.h>
#include <errno.h>
#include <getopt.h>
+#include <libxml/xmlversion.h>
+#include <jansson.h>
+#include <openssl/opensslv.h>
#include <syslog.h>
#include "common.h"
struct option_field const *opt;
pr_op_info(PACKAGE_STRING);
+ pr_op_info(" libcrypto: " OPENSSL_VERSION_TEXT);
+ pr_op_info(" jansson: " JANSSON_VERSION);
+ pr_op_info(" libcurl: " LIBCURL_VERSION);
+ pr_op_info(" libxml: " LIBXML_DOTTED_VERSION);
+
pr_op_info("Configuration {");
FOREACH_OPTION(options, opt, 0xFFFF)
#include <openssl/pem.h>
#include <time.h>
+#include "alloc.h"
#include "asn1/asn1c/OBJECT_IDENTIFIER.h"
#include "extension.h"
#include "json_util.h"
+#include "log.h"
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#define BIO_PR_TIME(bio, tm) ASN1_TIME_print_ex(bio, tm, ASN1_DTFLGS_ISO8601)
+#else
+#define BIO_PR_TIME(bio, tm) ASN1_TIME_print(bio, tm)
+#endif
+
+char *
+asn1time2str(ASN1_TIME const *tm)
+{
+ BIO *bio;
+ BUF_MEM *buf;
+ char *res;
+
+ bio = BIO_new(BIO_s_mem());
+ if (bio == NULL)
+ enomem_panic();
+
+ if (BIO_PR_TIME(bio, tm) <= 0)
+ return NULL;
+
+ BIO_flush(bio);
+ BIO_get_mem_ptr(bio, &buf);
+ res = pstrndup(buf->data, buf->length);
+
+ BIO_free_all(bio);
+ return res;
+}
/* Swallows @bio. */
static json_t *
asn1time2json(ASN1_TIME const *time)
{
BIO *bio;
- int success;
if (time == NULL)
return json_null();
if (bio == NULL)
return NULL;
-#if OPENSSL_VERSION_NUMBER >= 0x30000000L
- success = ASN1_TIME_print_ex(bio, time, ASN1_DTFLGS_ISO8601);
-#else
- success = ASN1_TIME_print(bio, time); /* Kill me */
-#endif
- if (!success) {
+ if (BIO_PR_TIME(bio, time) <= 0) {
BIO_free_all(bio);
return NULL;
}
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+char *asn1time2str(ASN1_TIME const *);
+
json_t *oid2json(ASN1_OBJECT const *);
json_t *asn1int2json(ASN1_INTEGER const *);
json_t *asn1str2json(ASN1_STRING const *); /* octet string, bit string, etc */
#include "common.h"
#include "config.h"
#include "extension.h"
+#include "libcrypto_util.h"
#include "log.h"
#include "nid.h"
#include "object/manifest.h"
return 0;
}
+static void
+pr_debug_x509_dates(X509 *x509)
+{
+ char *nb, *na;
+
+ nb = asn1time2str(X509_get0_notBefore(x509));
+ na = asn1time2str(X509_get0_notAfter(x509));
+
+ pr_val_debug("Valid range: [%s, %s]", nb, na);
+
+ free(nb);
+ free(na);
+}
+
/*
* Retry certificate validation without CRL time validation.
*/
else
error = val_crypto_err("Certificate validation failed: %d", ok);
+ if (error && log_val_enabled(LOG_DEBUG))
+ pr_debug_x509_dates(cert);
+
pop_clone:
clone = sk_X509_CRL_pop(crls);
if (clone == NULL)
}
+static int
+complain_crl_stale(STACK_OF(X509_CRL) *crls)
+{
+ X509_CRL *crl;
+ char *lu;
+ char *nu;
+ int ret;
+
+ if (sk_X509_CRL_num(crls) < 1)
+ pr_crit("Empty CRL stack despite validations.");
+ crl = sk_X509_CRL_value(crls, 0);
+ if (crl == NULL)
+ pr_crit("Unable to pop CRL from nonempty stack.");
+
+ lu = asn1time2str(X509_CRL_get0_lastUpdate(crl));
+ nu = asn1time2str(X509_CRL_get0_nextUpdate(crl));
+
+ ret = incidence(INID_CRL_STALE,
+ "CRL is stale/expired. (lastUpdate:%s, nextUpdate:%s)", lu, nu);
+
+ free(lu);
+ free(nu);
+ return ret;
+}
+
int
certificate_validate_chain(X509 *cert, STACK_OF(X509_CRL) *crls)
{
X509_verify_cert_error_string(error));
goto abort;
}
- if (incidence(INID_CRL_STALE, "CRL is stale/expired"))
- goto abort;
+ if (complain_crl_stale(crls))
+ goto abort;
X509_STORE_CTX_free(ctx);
if (incidence_get_action(INID_CRL_STALE) == INAC_WARN)
pr_val_info("Re-validating avoiding CRL time check");