From 7c283d9e9727e9e2b85cb5f780384c3a74f7dd3f Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 2 Dec 2012 14:00:22 +0000 Subject: [PATCH] add option to get a certificate or CRL from a URL --- apps/apps.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ apps/apps.h | 3 +++ apps/crl.c | 6 +++++ 3 files changed, 79 insertions(+) diff --git a/apps/apps.c b/apps/apps.c index bd5c71eac8..391a4d10b5 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -275,6 +275,8 @@ int str2fmt(char *s) return(FORMAT_PKCS12); else if ((*s == 'E') || (*s == 'e')) return(FORMAT_ENGINE); + else if ((*s == 'H') || (*s == 'h')) + return FORMAT_HTTP; else if ((*s == 'P') || (*s == 'p')) { if (s[1] == 'V' || s[1] == 'v') @@ -783,12 +785,80 @@ static int load_pkcs12(BIO *err, BIO *in, const char *desc, return ret; } +int load_cert_crl_http(const char *url, BIO *err, + X509 **pcert, X509_CRL **pcrl) + { + char *host = NULL, *port = NULL, *path = NULL; + BIO *bio = NULL; + OCSP_REQ_CTX *rctx = NULL; + int use_ssl, rv = 0; + if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl)) + goto err; + if (use_ssl) + { + if (err) + BIO_puts(err, "https not supported\n"); + goto err; + } + bio = BIO_new_connect(host); + if (!bio || !BIO_set_conn_port(bio, port)) + goto err; + rctx = OCSP_REQ_CTX_new(bio, 1024); + if (!rctx) + goto err; + if (!OCSP_REQ_CTX_http(rctx, "GET", path)) + goto err; + if (!OCSP_REQ_CTX_add1_header(rctx, "Host", host)) + goto err; + if (pcert) + { + do + { + rv = X509_http_nbio(rctx, pcert); + } + while (rv == -1); + } + else + { + do + { + rv = X509_CRL_http_nbio(rctx, pcrl); + } while (rv == -1); + } + + err: + if (host) + OPENSSL_free(host); + if (path) + OPENSSL_free(path); + if (port) + OPENSSL_free(port); + if (bio) + BIO_free_all(bio); + if (rctx) + OCSP_REQ_CTX_free(rctx); + if (rv != 1) + { + if (bio && err) + BIO_printf(bio_err, "Error loading %s from %s\n", + pcert ? "certificate" : "CRL", url); + ERR_print_errors(bio_err); + } + return rv; + } + X509 *load_cert(BIO *err, const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip) { X509 *x=NULL; BIO *cert; + if (format == FORMAT_HTTP) + { + load_cert_crl_http(file, err, &x, NULL); + return x; + } + if ((cert=BIO_new(BIO_s_file())) == NULL) { ERR_print_errors(err); diff --git a/apps/apps.h b/apps/apps.h index 4c9f95a1ce..165e45562d 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -245,6 +245,8 @@ int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2); int add_oid_section(BIO *err, CONF *conf); X509 *load_cert(BIO *err, const char *file, int format, const char *pass, ENGINE *e, const char *cert_descrip); +int load_cert_crl_http(const char *url, BIO *err, + X509 **pcert, X509_CRL **pcrl); EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *key_descrip); EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin, @@ -354,6 +356,7 @@ void print_cert_checks(BIO *bio, X509 *x, #define FORMAT_ASN1RSA 10 /* DER RSAPubicKey format */ #define FORMAT_MSBLOB 11 /* MS Key blob format */ #define FORMAT_PVK 12 /* MS PVK file format */ +#define FORMAT_HTTP 13 /* Dowload using HTTP */ #define EXT_COPY_NONE 0 #define EXT_COPY_ADD 1 diff --git a/apps/crl.c b/apps/crl.c index c395b2afd5..888cf7ff8d 100644 --- a/apps/crl.c +++ b/apps/crl.c @@ -407,6 +407,12 @@ static X509_CRL *load_crl(char *infile, int format) X509_CRL *x=NULL; BIO *in=NULL; + if (format == FORMAT_HTTP) + { + load_cert_crl_http(infile, bio_err, NULL, &x); + return x; + } + in=BIO_new(BIO_s_file()); if (in == NULL) { -- 2.25.1