[rs-commit] r108 - in /redwax-tool/trunk: config.h.in configure.ac redwax_openssl.c
rs-commit at redwax.eu
rs-commit at redwax.eu
Thu Dec 2 16:47:43 CET 2021
Author: minfrin at redwax.eu
Date: Thu Dec 2 16:47:43 2021
New Revision: 108
Log:
Add support for certificate transparency.
Modified:
redwax-tool/trunk/config.h.in
redwax-tool/trunk/configure.ac
redwax-tool/trunk/redwax_openssl.c
Modified: redwax-tool/trunk/config.h.in
==============================================================================
--- redwax-tool/trunk/config.h.in (original)
+++ redwax-tool/trunk/config.h.in Thu Dec 2 16:47:43 2021
@@ -5,6 +5,9 @@
/* Define to 1 if you have the `ASN1_TIME_diff' function. */
#undef HAVE_ASN1_TIME_DIFF
+
+/* Define to 1 if you have the `ASN1_TIME_print_ex' function. */
+#undef HAVE_ASN1_TIME_PRINT_EX
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
@@ -30,6 +33,9 @@
/* Define to 1 if you have the <openssl/core_names.h> header file. */
#undef HAVE_OPENSSL_CORE_NAMES_H
+
+/* Define to 1 if you have the <openssl/ct.h> header file. */
+#undef HAVE_OPENSSL_CT_H
/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
#undef HAVE_OPENSSL_INIT_CRYPTO
Modified: redwax-tool/trunk/configure.ac
==============================================================================
--- redwax-tool/trunk/configure.ac (original)
+++ redwax-tool/trunk/configure.ac Thu Dec 2 16:47:43 2021
@@ -92,11 +92,11 @@
AC_TYPE_UINT32_T
# Checks for headers
-AC_CHECK_HEADERS([unistd.h libgen.h openssl/core_names.h])
+AC_CHECK_HEADERS([unistd.h libgen.h openssl/core_names.h openssl/ct.h])
# Checks for library functions.
AC_FUNC_MALLOC
-AC_CHECK_FUNCS([OPENSSL_init_crypto PKCS12_SAFEBAG_get0_safes PKCS12_SAFEBAG_get_bag_nid PKCS12_SAFEBAG_get_nid PKCS12_SAFEBAG_get0_attr PKCS12_SAFEBAG_get0_p8inf PKCS12_SAFEBAG_get1_cert PKCS12_SAFEBAG_get1_crl OPENSSL_uni2utf8 ASN1_TIME_diff X509_STORE_get0_param X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_get_num_untrusted X509_get0_notBefore X509_get0_notAfter X509_get0_tbs_sigalg X509_get0_uids X509_get0_extensions X509_get0_signature X509_get_extension_flags X509_up_ref EVP_PKEY_get0_description EVP_PKEY_get_bn_param RSA_get0_n RSA_get0_e RSA_get0_d RSA_get0_p RSA_get0_q RSA_get0_dmp1 RSA_get0_dmq1 RSA_get0_iqmp RSA_set0_key RSA_set0_factors RSA_set0_crt_params NSS_Initialize p11_kit_modules_load_and_initialize apr_crypto_clear])
+AC_CHECK_FUNCS([OPENSSL_init_crypto PKCS12_SAFEBAG_get0_safes PKCS12_SAFEBAG_get_bag_nid PKCS12_SAFEBAG_get_nid PKCS12_SAFEBAG_get0_attr PKCS12_SAFEBAG_get0_p8inf PKCS12_SAFEBAG_get1_cert PKCS12_SAFEBAG_get1_crl OPENSSL_uni2utf8 ASN1_TIME_diff ASN1_TIME_print_ex X509_STORE_get0_param X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_get_num_untrusted X509_get0_notBefore X509_get0_notAfter X509_get0_tbs_sigalg X509_get0_uids X509_get0_extensions X509_get0_signature X509_get_extension_flags X509_up_ref EVP_PKEY_get0_description EVP_PKEY_get_bn_param RSA_get0_n RSA_get0_e RSA_get0_d RSA_get0_p RSA_get0_q RSA_get0_dmp1 RSA_get0_dmq1 RSA_get0_iqmp RSA_set0_key RSA_set0_factors RSA_set0_crt_params NSS_Initialize p11_kit_modules_load_and_initialize apr_crypto_clear])
AC_OUTPUT
Modified: redwax-tool/trunk/redwax_openssl.c
==============================================================================
--- redwax-tool/trunk/redwax_openssl.c (original)
+++ redwax-tool/trunk/redwax_openssl.c Thu Dec 2 16:47:43 2021
@@ -44,6 +44,9 @@
#if HAVE_OPENSSL_CORE_NAMES_H
#include <openssl/core_names.h>
#endif
+#if HAVE_OPENSSL_CT_H
+#include <openssl/ct.h>
+#endif
#define REDWAX_OPENSSL_SEARCH "search"
#define REDWAX_OPENSSL_VERIFY "verify"
@@ -117,7 +120,7 @@
#define PKCS12_SAFEBAG_get1_crl PKCS12_certbag2x509crl
#endif
-#if !HAVE_ASN1_TIME_DIFF
+#if !HAVE_ASN1_TIME_DIFF || !HAVE_ASN1_TIME_PRINT_EX
#define SECS_PER_DAY (24 * 60 * 60)
@@ -507,6 +510,10 @@
return 0;
}
+#endif
+
+#if !HAVE_ASN1_TIME_DIFF
+
int redwax_ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm)
{
if (s == NULL) {
@@ -565,6 +572,94 @@
}
#endif
+#if !HAVE_ASN1_TIME_PRINT_EX
+
+/* Lower 8 bits are reserved as an output type specifier */
+# define ASN1_DTFLGS_TYPE_MASK 0x0FUL
+# define ASN1_DTFLGS_RFC822 0x00UL
+# define ASN1_DTFLGS_ISO8601 0x01UL
+
+static const char _asn1_mon[12][4] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static int ossl_ascii_isdigit(const char inchar) {
+ if (inchar > 0x2F && inchar < 0x3A)
+ return 1;
+ return 0;
+}
+
+/* prints the time with the date format of ISO 8601 */
+/* returns 0 on BIO write error, else -1 in case of parse failure, else 1 */
+int ossl_asn1_time_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags)
+{
+ char *v;
+ int gmt = 0, l;
+ struct tm stm;
+ const char upper_z = 0x5A, period = 0x2E;
+
+ /* asn1_time_to_tm will check the time type */
+ if (!asn1_time_to_tm(&stm, tm))
+ return BIO_write(bp, "Bad time value", 14) ? -1 : 0;
+
+ l = tm->length;
+ v = (char *)tm->data;
+ if (v[l - 1] == upper_z)
+ gmt = 1;
+
+ if (tm->type == V_ASN1_GENERALIZEDTIME) {
+ char *f = NULL;
+ int f_len = 0;
+
+ /*
+ * Try to parse fractional seconds. '14' is the place of
+ * 'fraction point' in a GeneralizedTime string.
+ */
+ if (tm->length > 15 && v[14] == period) {
+ f = &v[14];
+ f_len = 1;
+ while (14 + f_len < l && ossl_ascii_isdigit(f[f_len]))
+ ++f_len;
+ }
+
+ if ((flags & ASN1_DTFLGS_TYPE_MASK) == ASN1_DTFLGS_ISO8601) {
+ return BIO_printf(bp, "%4d-%02d-%02d %02d:%02d:%02d%.*s%s",
+ stm.tm_year + 1900, stm.tm_mon + 1,
+ stm.tm_mday, stm.tm_hour,
+ stm.tm_min, stm.tm_sec, f_len, f,
+ (gmt ? "Z" : "")) > 0;
+ }
+ else {
+ return BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
+ _asn1_mon[stm.tm_mon], stm.tm_mday, stm.tm_hour,
+ stm.tm_min, stm.tm_sec, f_len, f, stm.tm_year + 1900,
+ (gmt ? " GMT" : "")) > 0;
+ }
+ } else {
+ if ((flags & ASN1_DTFLGS_TYPE_MASK) == ASN1_DTFLGS_ISO8601) {
+ return BIO_printf(bp, "%4d-%02d-%02d %02d:%02d:%02d%s",
+ stm.tm_year + 1900, stm.tm_mon + 1,
+ stm.tm_mday, stm.tm_hour,
+ stm.tm_min, stm.tm_sec,
+ (gmt ? "Z" : "")) > 0;
+ }
+ else {
+ return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
+ _asn1_mon[stm.tm_mon], stm.tm_mday, stm.tm_hour,
+ stm.tm_min, stm.tm_sec, stm.tm_year + 1900,
+ (gmt ? " GMT" : "")) > 0;
+ }
+ }
+}
+
+/* returns 1 on success, 0 on BIO write error or parse failure */
+int ASN1_TIME_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags)
+{
+ return ossl_asn1_time_print_ex(bp, tm, flags) > 0;
+}
+#endif
+
#if !HAVE_X509_STORE_CTX_GET_NUM_UNTRUSTED
int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx)
{
@@ -729,10 +824,36 @@
return NULL;
}
- if (name != NULL) {
+ if (name) {
X509_NAME_print_ex(bio,
name,
0, XN_FLAG_RFC2253);
+ len = BIO_get_mem_data(bio, &buf);
+ }
+
+ buf = apr_pstrndup(p, buf, len);
+
+ BIO_free(bio);
+
+ return buf;
+}
+
+static const char* redwax_openssl_time(apr_pool_t *p,
+ const ASN1_GENERALIZEDTIME *tm)
+{
+ BIO *bio;
+ char *buf = NULL;
+ int len = 0;
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL) {
+ return NULL;
+ }
+
+ if (tm) {
+
+ ASN1_TIME_print_ex(bio, tm,
+ ASN1_DTFLGS_ISO8601);
+
len = BIO_get_mem_data(bio, &buf);
}
@@ -3377,6 +3498,98 @@
break;
}
+#if HAVE_OPENSSL_CT_H
+ case NID_ct_precert_scts:
+ case NID_ct_cert_scts: {
+
+ STACK_OF(SCT) *sct_list = X509V3_EXT_d2i(ex);
+
+ int i;
+
+ if (sk_SCT_num(sct_list)) {
+
+ redwax_metadata_push_array(m, "SignedCertificateTimestamps", 0);
+
+ for (i = 0; i < sk_SCT_num(sct_list); ++i) {
+
+ SCT *sct;
+ ASN1_GENERALIZEDTIME *gen;
+ char genstr[20];
+ unsigned char *ext, *sig;
+ apr_size_t ext_len, sig_len;
+ uint64_t timestamp;
+ int nid;
+
+ sct = sk_SCT_value(sct_list, i);
+
+ redwax_metadata_push_object(m, "SignedCertificateTimestamp", 0);
+
+ if (SCT_get_version(sct) == SCT_VERSION_V1) {
+ redwax_metadata_add_string(m, "Version", "v1 (0x0)");
+ }
+
+ timestamp = SCT_get_timestamp(sct);
+
+ gen = ASN1_GENERALIZEDTIME_new();
+ if (!gen) {
+ return APR_ENOMEM;
+ }
+
+ ASN1_GENERALIZEDTIME_adj(gen, (time_t)0,
+ (int)(timestamp / 86400000),
+ (timestamp % 86400000) / 1000);
+
+ BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ",
+ ASN1_STRING_get0_data(gen), (unsigned int)(timestamp % 1000));
+ if (ASN1_GENERALIZEDTIME_set_string(gen, genstr)) {
+
+ redwax_metadata_add_string(m, "Timestamp", redwax_openssl_time(m->pool, gen));
+ }
+
+ ASN1_GENERALIZEDTIME_free(gen);
+
+ ext_len = SCT_get0_extensions(sct, &ext);
+ if (ext_len) {
+ redwax_metadata_add_string(m, "Extensions",
+ redwax_pencode_base16_binary(m->pool,
+ ext, ext_len,
+ REDWAX_ENCODE_LOWER | REDWAX_ENCODE_COLON, NULL));
+
+ }
+
+ nid = SCT_get_signature_nid(sct);
+ if (nid != NID_undef) {
+
+ redwax_metadata_push_object(m, "Signature", 0);
+ redwax_metadata_add_string(m, "SignatureAlgorithm", OBJ_nid2sn(nid));
+
+ sig_len = SCT_get0_signature(sct, &sig);
+ if (sig_len) {
+ redwax_metadata_add_string(m, "SignatureValue",
+ redwax_pencode_base16_binary(m->pool,
+ sig, sig_len,
+ REDWAX_ENCODE_LOWER | REDWAX_ENCODE_COLON, NULL));
+
+ }
+
+ redwax_metadata_pop_object(m);
+ }
+
+ redwax_metadata_pop_object(m);
+ }
+
+ redwax_metadata_pop_array(m);
+ }
+
+ break;
+ }
+ case NID_ct_precert_poison: {
+
+ /* no metadata needed */
+
+ break;
+ }
+#endif
default:
/*
@@ -3540,45 +3753,13 @@
tm = X509_get0_notBefore(x);
if (tm) {
- BIO *bio;
- char *buf = NULL;
- int len = 0;
-
- if ((bio = BIO_new(BIO_s_mem())) == NULL) {
- return APR_ENOMEM;
- }
-
- ASN1_TIME_print(bio, tm);
-
- len = BIO_get_mem_data(bio, &buf);
-
- redwax_metadata_add_string(m, "NotBefore",
- apr_psprintf(m->pool, "%.*s", len, buf));
-
- BIO_free(bio);
-
+ redwax_metadata_add_string(m, "NotBefore", redwax_openssl_time(m->pool, tm));
}
tm = X509_get0_notAfter(x);
if (tm) {
- BIO *bio;
- char *buf = NULL;
- int len = 0;
-
- if ((bio = BIO_new(BIO_s_mem())) == NULL) {
- return APR_ENOMEM;
- }
-
- ASN1_TIME_print(bio, tm);
-
- len = BIO_get_mem_data(bio, &buf);
-
- redwax_metadata_add_string(m, "NotAfter",
- apr_psprintf(m->pool, "%.*s", len, buf));
-
- BIO_free(bio);
-
+ redwax_metadata_add_string(m, "NotAfter", redwax_openssl_time(m->pool, tm));
}
redwax_metadata_pop_object(m);
More information about the rs-commit
mailing list