Use native HTTP client with OpenSSL 3.0 or later (#378)

Co-authored-by: olszomal <Malgorzata.Olszowka@stunnel.org>
This commit is contained in:
Michał Trojnara
2024-04-09 19:33:31 +02:00
committed by GitHub
parent 6ad2679f17
commit ded1f7aa67
7 changed files with 427 additions and 118 deletions

View File

@ -208,6 +208,7 @@ IMPLEMENT_ASN1_FUNCTIONS(MsCtlContent)
/* Prototypes */
static ASN1_INTEGER *create_nonce(int bits);
static char *clrdp_url_get_x509(X509 *cert);
static time_t time_t_get_asn1_time(const ASN1_TIME *s);
static time_t time_t_get_si_time(PKCS7_SIGNER_INFO *si);
static ASN1_UTCTIME *asn1_time_get_si_time(PKCS7_SIGNER_INFO *si);
@ -221,10 +222,10 @@ static int X509_attribute_chain_append_object(STACK_OF(X509_ATTRIBUTE) **unauth_
static STACK_OF(PKCS7) *signature_list_create(PKCS7 *p7);
static int PKCS7_compare(const PKCS7 *const *a, const PKCS7 *const *b);
static PKCS7 *pkcs7_get_sigfile(FILE_FORMAT_CTX *ctx);
static void print_cert(X509 *cert, int i);
static int x509_store_load_crlfile(X509_STORE *store, char *cafile, char *crlfile);
static int blob_has_nl = 0;
/*
A timestamp request looks like this:
@ -523,8 +524,6 @@ static int attach_authenticode_response(PKCS7 *p7, PKCS7 *resp, int verbose)
return 0; /* OK */
}
#ifdef ENABLE_CURL
static void print_proxy(char *proxy)
{
if (proxy) {
@ -545,6 +544,11 @@ static void print_proxy(char *proxy)
}
}
#if OPENSSL_VERSION_NUMBER<0x30000000L
#ifdef ENABLE_CURL
static int blob_has_nl = 0;
/*
* Callback for writing received data
*/
@ -565,15 +569,15 @@ static size_t curl_write(void *ptr, size_t sz, size_t nmemb, void *stream)
* Get data from HTTP server.
* [out] http_code: HTTP status
* [in] url: URL of the CRL distribution point or Time-Stamp Authority HTTP server
* [in] bout: timestamp request
* [in] req: timestamp request
* [in] proxy: proxy to getting the timestamp through
* [in] noverifypeer: do not verify the Time-Stamp Authority's SSL certificate
* [in] verbose: additional output mode
* [in] content: CRL distribution point (0), RFC3161 TSA (1), Authenticode TSA (2)
* [returns] pointer to BIO with X509 Certificate Revocation List
* [in] rfc3161: Authenticode / RFC3161 Timestamp switch
* [returns] pointer to BIO with X509 Certificate Revocation List or timestamp response
*/
static BIO *bio_get_http(long *http_code, char *url, BIO *bout, char *proxy,
int noverifypeer, int verbose, int content)
static BIO *bio_get_http_curl(long *http_code, char *url, BIO *req, char *proxy,
int noverifypeer, int verbose, int rfc3161)
{
CURL *curl;
struct curl_slist *slist = NULL;
@ -621,24 +625,23 @@ static BIO *bio_get_http(long *http_code, char *url, BIO *bout, char *proxy,
printf("CURL failure: %s %s\n", curl_easy_strerror(res), url);
}
}
if (content == 1) {
/* RFC3161 Timestamp */
slist = curl_slist_append(slist, "Content-Type: application/timestamp-query");
slist = curl_slist_append(slist, "Accept: application/timestamp-reply");
} else if (content == 2) {
/* Authenticode Timestamp */
slist = curl_slist_append(slist, "Content-Type: application/octet-stream");
slist = curl_slist_append(slist, "Accept: application/octet-stream");
}
if (content > 0) {
/* Timestamp */
if (req) { /* POST */
if (rfc3161) {
/* RFC3161 Timestamp */
slist = curl_slist_append(slist, "Content-Type: application/timestamp-query");
slist = curl_slist_append(slist, "Accept: application/timestamp-reply");
} else {
/* Authenticode Timestamp */
slist = curl_slist_append(slist, "Content-Type: application/octet-stream");
slist = curl_slist_append(slist, "Accept: application/octet-stream");
}
slist = curl_slist_append(slist, "User-Agent: Transport");
slist = curl_slist_append(slist, "Cache-Control: no-cache");
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
if (res != CURLE_OK) {
printf("CURL failure: %s %s\n", curl_easy_strerror(res), url);
}
len = BIO_get_mem_data(bout, &p);
len = BIO_get_mem_data(req, &p);
res = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
if (res != CURLE_OK) {
printf("CURL failure: %s %s\n", curl_easy_strerror(res), url);
@ -679,12 +682,285 @@ static BIO *bio_get_http(long *http_code, char *url, BIO *bout, char *proxy,
}
/* End a libcurl easy handle */
curl_easy_cleanup(curl);
if (req && !rfc3161) {
/* BASE64 encoded Authenticode Timestamp */
BIO *b64 = BIO_new(BIO_f_base64());
if (!blob_has_nl)
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bin = BIO_push(b64, bin);
}
return bin;
}
#endif /* ENABLE_CURL */
#else /* OPENSSL_VERSION_NUMBER<0x30000000L */
/* HTTP callback function that supports TLS connection also via HTTPS proxy */
static BIO *http_tls_cb(BIO *bio, void *arg, int connect, int detail)
{
HTTP_TLS_Info *info = (HTTP_TLS_Info *)arg;
SSL_CTX *ssl_ctx = info->ssl_ctx;
if (ssl_ctx == NULL) {
/* not using TLS */
return bio;
}
if (connect && detail) {
/* connecting with TLS */
SSL *ssl;
BIO *sbio = NULL;
if (info->use_proxy && !OSSL_HTTP_proxy_connect(bio, info->server,
info->port, NULL, NULL, info->timeout, NULL, NULL)) {
return NULL;
}
sbio = BIO_new(BIO_f_ssl());
if (sbio == NULL) {
return NULL;
}
ssl = SSL_new(ssl_ctx);
if (ssl == NULL) {
BIO_free(sbio);
return NULL;
}
SSL_set_tlsext_host_name(ssl, info->server);
SSL_set_connect_state(ssl);
BIO_set_ssl(sbio, ssl, BIO_CLOSE);
bio = BIO_push(sbio, bio);
}
return bio;
}
static int verify_callback(int ok, X509_STORE_CTX *ctx)
{
if (!ok) {
int error = X509_STORE_CTX_get_error(ctx);
print_cert(X509_STORE_CTX_get_current_cert(ctx), 0);
if (error == X509_V_ERR_UNABLE_TO_GET_CRL) {
char *url = clrdp_url_get_x509(X509_STORE_CTX_get_current_cert(ctx));
printf("\tWarning: Ignoring \'%s\' error for CRL validation\n",
X509_verify_cert_error_string(error));
printf("\nUse the \"-HTTPS-CRLfile\" option to verify CRL\n");
if (url) {
printf("HTTPS's CRL distribution point: %s\n", url);
OPENSSL_free(url);
}
return 1;
} else {
printf("\tError: %s\n", X509_verify_cert_error_string(error));
}
}
return ok;
}
/*
* Decode a curl response from BIO and write it into the PKCS7 structure
* Read data from socket BIO
* [in] s_bio: socket BIO
* [in] rctx: open connection context
* [in] use_ssl: HTTPS request switch
* [returns] memory BIO
*/
static BIO *socket_bio_read(BIO *s_bio, OSSL_HTTP_REQ_CTX *rctx, int use_ssl)
{
int retry = 1, ok = 0, written = 0, resp_len = 0;
char *buf = OPENSSL_malloc(OSSL_HTTP_DEFAULT_MAX_RESP_LEN);
BIO *resp = BIO_new(BIO_s_mem());
if (rctx) {
resp_len = (int)OSSL_HTTP_REQ_CTX_get_resp_len(rctx);
}
if (resp_len == 0) {
if (use_ssl)
BIO_ssl_shutdown(s_bio);
else {
int fd = (int)BIO_get_fd(s_bio, NULL);
if (fd >= 0) {
#ifdef WIN32
(void)shutdown(fd, SD_SEND);
#else /* WIN32 */
(void)shutdown(fd, SHUT_WR);
#endif /* WIN32 */
}
}
}
ERR_clear_error();
while (retry) {
int n;
errno = 0;
n = BIO_read(s_bio, buf, OSSL_HTTP_DEFAULT_MAX_RESP_LEN);
if (n > 0) {
written += BIO_write(resp, buf, n);
} else if (BIO_eof(s_bio) == 1) {
ok = 1;
retry = 0; /* EOF */
} else if (BIO_should_retry(s_bio)) {
} else {
unsigned long err = ERR_get_error();
if (err == 0) {
ok = 1;
retry = 0; /* use_ssl EOF */
} else {
printf("\nHTTP failure: error %ld: %s\n", err, ERR_reason_error_string(err));
retry = 0; /* FAILED */
}
}
if (resp_len > 0 && resp_len == written) {
ok = 1;
retry = 0; /* all response has been read */
}
}
OSSL_HTTP_close(rctx, ok);
OPENSSL_free(buf);
if (!ok) {
BIO_free_all(resp);
resp = NULL;
}
return resp;
}
/*
* pkcs7-signedData bytes found indicates DER form
* in otherwise BASE64 encoded
* '\n' newline character means BASE64 line with newline at the end
* in otherwise BIO_FLAGS_BASE64_NO_NL flag must me set
* [in, out] resp: memory BIO with Authenticode Timestamp data
* [returns] none
*/
static void check_authenticode_timestamp(BIO **resp)
{
u_char *ptr = NULL;
const u_char pkcs7_signed[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02};
int i, len, pkcs7_signed_len, found = 0;
len = (int)BIO_get_mem_data(*resp, &ptr);
if (len <= 0) {
return;
}
pkcs7_signed_len = (int)sizeof pkcs7_signed;
for (i = 0; i <= len - pkcs7_signed_len; i++) {
if (memcmp(ptr + i, pkcs7_signed, (size_t)pkcs7_signed_len) == 0) {
found = 1;
break;
}
}
if (!found) {
/* BASE64 encoded Authenticode Timestamp */
BIO *b64 = BIO_new(BIO_f_base64());
if (!memchr(ptr, '\n', (size_t)len)) {
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
} else {
BIO *bio_mem = BIO_new_mem_buf(ptr, len);
BIO_push(b64, bio_mem);
}
*resp = BIO_push(b64, *resp);
}
}
/*
* Get data from HTTP server.
* [in] url: URL of the CRL distribution point or Time-Stamp Authority HTTP server
* [in] req: timestamp request
* [in] proxy: proxy to getting the timestamp through
* [in] rfc3161: Authenticode / RFC3161 Timestamp switch
* [in] cafile: file contains concatenated CA certificates in PEM format
* [in] crlfile: file contains Certificate Revocation List (CRLs)
* [returns] pointer to BIO with X509 Certificate Revocation List or timestamp response
*/
static BIO *bio_get_http(char *url, BIO *req, char *proxy, int rfc3161, char *cafile, char *crlfile)
{
BIO *tmp_bio = NULL, *s_bio = NULL, *resp = NULL;
OSSL_HTTP_REQ_CTX *rctx = NULL;
HTTP_TLS_Info info;
SSL_CTX *ssl_ctx = NULL;
char *server = NULL, *port = NULL, *path = NULL;
int timeout = -1; /* blocking mode, exactly one try, see BIO_do_connect_retry() */
int keep_alive = 1; /* prefer */
int use_ssl = 0;
if (!url) {
return NULL; /* FAILED */
}
print_proxy(proxy);
printf("Connecting to %s\n", url);
if (!OSSL_HTTP_parse_url(url, &use_ssl, NULL, &server, &port, NULL, &path, NULL, NULL)) {
return NULL; /* FAILED */
}
if (use_ssl) {
X509_STORE *store = NULL;
ssl_ctx = SSL_CTX_new(TLS_client_method());
if (cafile) {
printf("HTTPS-CAfile: %s\n", cafile);
if (crlfile)
printf("HTTPS-CRLfile: %s\n", crlfile);
store = SSL_CTX_get_cert_store(ssl_ctx);
if (x509_store_load_crlfile(store, cafile, crlfile))
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, verify_callback);
else
printf("Warning: HTTPS verification was skipped\n");
} else {
printf("Warning: HTTPS verification was skipped\n");
}
}
info.server = server;
info.port = port;
info.use_proxy = OSSL_HTTP_adapt_proxy(proxy, NULL, server, use_ssl) != NULL;
info.timeout = timeout;
info.ssl_ctx = ssl_ctx;
if (!req) { /* GET */
const char *expected_content_type = "application/pkix-crl";
s_bio = OSSL_HTTP_get(url, proxy, NULL, NULL, NULL, http_tls_cb, &info, 0,
NULL, expected_content_type, 0, 0, timeout);
} else { /* POST */
const char *content_type = "application/timestamp-query"; /* RFC3161 Timestamp */
const char *expected_content_type = "application/timestamp-reply";
if (!rfc3161) {
u_char *p = NULL;
long len = BIO_get_mem_data(req, &p);
tmp_bio = BIO_new(BIO_s_mem());
BIO_write(tmp_bio, p, (int)len);
req = BIO_push(tmp_bio, req);
content_type = "application/octet-stream"; /* Authenticode Timestamp */
expected_content_type = "application/octet-stream";
}
s_bio = OSSL_HTTP_transfer(&rctx, server, port, path, use_ssl, proxy, NULL,
NULL, NULL, http_tls_cb, &info, 0, NULL, content_type, req,
expected_content_type, 0, 0, timeout, keep_alive);
BIO_free(tmp_bio);
}
OPENSSL_free(server);
OPENSSL_free(port);
OPENSSL_free(path);
SSL_CTX_free(ssl_ctx);
if (s_bio) {
resp = socket_bio_read(s_bio, rctx, use_ssl);
BIO_free_all(s_bio);
if (resp && req && !rfc3161)
check_authenticode_timestamp(&resp);
} else {
printf("\nHTTP failure: Failed to get data from %s\n", url);
}
return resp;
}
#endif /* OPENSSL_VERSION_NUMBER<0x30000000L */
/*
* Decode a HTTP response from BIO and write it into the PKCS7 structure
* Add timestamp to the PKCS7 SignerInfo structure:
* sig->d.sign->signer_info->unauth_attr
* [in, out] p7: new PKCS#7 signature
@ -695,54 +971,58 @@ static BIO *bio_get_http(long *http_code, char *url, BIO *bout, char *proxy,
*/
static int add_timestamp(PKCS7 *p7, FILE_FORMAT_CTX *ctx, char *url, int rfc3161)
{
BIO *bout, *bin;
BIO *req, *resp;
int verbose = ctx->options->verbose || ctx->options->ntsurl == 1;
int res = 1;
long http_code = -1;
/* Encode timestamp request */
if (rfc3161) {
bout = bio_encode_rfc3161_request(p7, ctx->options->md);
req = bio_encode_rfc3161_request(p7, ctx->options->md);
} else {
bout = bio_encode_authenticode_request(p7);
req = bio_encode_authenticode_request(p7);
}
if (!bout) {
if (!req) {
return 1; /* FAILED */
}
#ifdef ENABLE_CURL
#if OPENSSL_VERSION_NUMBER<0x30000000L
#ifndef ENABLE_CURL
(void)url;
(void)rfc3161;
printf("Could NOT find CURL\n");
BIO_free_all(req);
return NULL; /* FAILED */
#else /* ENABLE_CURL */
if (rfc3161) {
bin = bio_get_http(&http_code, url, bout, ctx->options->proxy,
resp = bio_get_http_curl(&http_code, url, req, ctx->options->proxy,
ctx->options->noverifypeer, verbose, 1);
} else {
bin = bio_get_http(&http_code, url, bout, ctx->options->proxy,
ctx->options->noverifypeer, verbose, 2);
resp = bio_get_http_curl(&http_code, url, req, ctx->options->proxy,
ctx->options->noverifypeer, verbose, 0);
}
BIO_free_all(bout);
#else /* ENABLE_CURL */
/* TODO implement an HTTP session */
printf("Could NOT find CURL\n");
return 1; /* FAILED */
#endif /* ENABLE_CURL */
if (bin) {
#else /* OPENSSL_VERSION_NUMBER<0x30000000L */
if (rfc3161) {
resp = bio_get_http(url, req, ctx->options->proxy, 1,
ctx->options->noverifypeer ? NULL : ctx->options->https_cafile,
ctx->options->noverifypeer ? NULL : ctx->options->https_crlfile);
} else {
resp = bio_get_http(url, req, ctx->options->proxy, 0,
ctx->options->noverifypeer ? NULL : ctx->options->https_cafile,
ctx->options->noverifypeer ? NULL : ctx->options->https_crlfile);
}
#endif /* OPENSSL_VERSION_NUMBER<0x30000000L */
BIO_free_all(req);
if (resp != NULL) {
if (rfc3161) {
/* decode a RFC 3161 response from BIO */
TS_RESP *response = d2i_TS_RESP_bio(bin, NULL);
BIO_free_all(bin);
TS_RESP *response = d2i_TS_RESP_bio(resp, NULL);
res = attach_rfc3161_response(p7, response, verbose);
TS_RESP_free(response);
} else {
/* decode an authenticode response from BIO */
PKCS7 *response;
BIO *b64, *b64_bin;
b64 = BIO_new(BIO_f_base64());
if (!blob_has_nl)
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
b64_bin = BIO_push(b64, bin);
response = d2i_PKCS7_bio(b64_bin, NULL);
BIO_free_all(b64_bin);
PKCS7 *response = d2i_PKCS7_bio(resp, NULL);
res = attach_authenticode_response(p7, response, verbose);
}
@ -751,11 +1031,11 @@ static int add_timestamp(PKCS7 *p7, FILE_FORMAT_CTX *ctx, char *url, int rfc3161
printf("Failed to convert timestamp reply from %s; "
"HTTP status %ld\n", url, http_code);
} else {
printf("Failed to convert timestamp reply from %s; "
"no HTTP status available", url);
printf("Failed to convert timestamp reply from %s\n", url);
}
ERR_print_errors_fp(stdout);
}
BIO_free_all(resp);
}
return res;
}
@ -1445,7 +1725,7 @@ static int trusted_cert(X509 *cert, int error) {
return 0; /* FAILED */
}
if (on_list(hex, fingerprints)) {
printf("\tWarning: Ignoring %s error for Windows certificate whitelist\n",
printf("\tWarning: Ignoring \'%s\' error for Windows certificate whitelist\n",
X509_verify_cert_error_string(error));
OPENSSL_free(hex);
return 1; /* trusted */
@ -1468,7 +1748,7 @@ static int verify_ca_callback(int ok, X509_STORE_CTX *ctx)
if (trusted_cert(current_cert, error)) {
return 1;
} else if (error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
printf("\tError: Unable to get local CA certificate; %s\n",
printf("\tError: Certificate not found in local repository: %s\n",
X509_verify_cert_error_string(error));
} else {
printf("\tError: %s\n", X509_verify_cert_error_string(error));
@ -1488,11 +1768,11 @@ static int verify_crl_callback(int ok, X509_STORE_CTX *ctx)
if (trusted_cert(current_cert, error)) {
return 1;
} else if (error == X509_V_ERR_CERT_HAS_EXPIRED) {
printf("\tWarning: Ignoring %s error for CRL validation\n",
printf("\tWarning: Ignoring \'%s\' error for CRL validation\n",
X509_verify_cert_error_string(error));
return 1;
} else if (error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
printf("\tError: Unable to get local CA certificate; %s\n",
printf("\tError: Certificate not found in local repository: %s\n",
X509_verify_cert_error_string(error));
}
else {
@ -1661,24 +1941,28 @@ out:
/*
* Get Certificate Revocation List from a CRL distribution point
* and write it into the X509_CRL structure.
* [in] proxy: proxy to getting CRL through
* [in] ctx: structure holds input and output data
* [in] url: URL of the CRL distribution point server
* [returns] X509 Certificate Revocation List
*/
static X509_CRL *x509_crl_get(char *proxy, char *url)
static X509_CRL *x509_crl_get(FILE_FORMAT_CTX *ctx, char *url)
{
X509_CRL *crl;
BIO *bio = NULL;
#ifdef ENABLE_CURL
long http_code = -1;
bio = bio_get_http(&http_code, url, NULL, proxy, 0, 1, 0);
#else /* ENABLE_CURL */
/* TODO implement an HTTP session */
(void)proxy;
#if OPENSSL_VERSION_NUMBER<0x30000000L
#ifndef ENABLE_CURL
printf("Could NOT find CURL\n");
return NULL; /* FAILED */
#else /* ENABLE_CURL */
long http_code = -1;
bio = bio_get_http_curl(&http_code, url, NULL, ctx->options->proxy, 0, 1, 0);
#endif /* ENABLE_CURL */
#else /* OPENSSL_VERSION_NUMBER<0x30000000L */
bio = bio_get_http(url, NULL, ctx->options->proxy, 0,
ctx->options->noverifypeer ? NULL : ctx->options->https_cafile,
ctx->options->noverifypeer ? NULL : ctx->options->https_crlfile);
#endif /* OPENSSL_VERSION_NUMBER<0x30000000L */
if (!bio) {
printf("Warning: Faild to get CRL from %s\n\n", url);
return NULL; /* FAILED */
@ -1879,7 +2163,7 @@ static int verify_timestamp(FILE_FORMAT_CTX *ctx, PKCS7 *p7, CMS_ContentInfo *ti
printf("Ignored TSA's CRL distribution point: %s\n", url);
} else {
printf("TSA's CRL distribution point: %s\n", url);
crl = x509_crl_get(ctx->options->proxy, url);
crl = x509_crl_get(ctx, url);
}
OPENSSL_free(url);
if (!crl && !ctx->options->tsa_crlfile) {
@ -2041,7 +2325,7 @@ static int verify_authenticode(FILE_FORMAT_CTX *ctx, PKCS7 *p7, time_t time, X50
printf("Ignored CRL distribution point: %s\n", url);
} else {
printf("CRL distribution point: %s\n", url);
crl = x509_crl_get(ctx->options->proxy, url);
crl = x509_crl_get(ctx, url);
}
OPENSSL_free(url);
if (!crl && !ctx->options->crlfile) {
@ -2737,7 +3021,7 @@ static int verify_signature(FILE_FORMAT_CTX *ctx, PKCS7 *p7)
time = INVALID_TIME;
} else {
int timeok = verify_timestamp(ctx, p7, timestamp, time);
printf("Timestamp Server Signature verification: %s\n", timeok ? "ok" : "failed");
printf("\nTimestamp Server Signature verification: %s\n", timeok ? "ok" : "failed");
if (!timeok) {
time = INVALID_TIME;
}
@ -3035,8 +3319,10 @@ static void free_options(GLOBAL_OPTIONS *options)
{
/* If memory has not been allocated nothing is done */
OPENSSL_free(options->cafile);
OPENSSL_free(options->tsa_cafile);
OPENSSL_free(options->crlfile);
OPENSSL_free(options->https_cafile);
OPENSSL_free(options->https_crlfile);
OPENSSL_free(options->tsa_cafile);
OPENSSL_free(options->tsa_crlfile);
/* If key is NULL nothing is done */
EVP_PKEY_free(options->pkey);
@ -3095,6 +3381,8 @@ static void usage(const char *argv0, const char *cmd)
printf("%12s[ -ts <timestampurl> [ -ts ... ] [ -p <proxy> ] [ -noverifypeer ] ]\n", "");
printf("%12s[ -TSA-certs <TSA-certfile> ] [ -TSA-key <TSA-keyfile> ]\n", "");
printf("%12s[ -TSA-time <unix-time> ]\n", "");
printf("%12s[ -HTTPS-CAfile <infile> ]\n", "");
printf("%12s[ -HTTPS-CRLfile <infile> ]\n", "");
printf("%12s[ -time <unix-time> ]\n", "");
printf("%12s[ -addUnauthenticatedBlob ]\n", "");
printf("%12s[ -nest ]\n", "");
@ -3116,6 +3404,8 @@ static void usage(const char *argv0, const char *cmd)
printf("%12s[ -ts <timestampurl> [ -ts ... ] [ -p <proxy> ] [ -noverifypeer ] ]\n", "");
printf("%12s[ -TSA-certs <TSA-certfile> ] [ -TSA-key <TSA-keyfile> ]\n", "");
printf("%12s[ -TSA-time <unix-time> ]\n", "");
printf("%12s[ -HTTPS-CAfile <infile> ]\n", "");
printf("%12s[ -HTTPS-CRLfile <infile> ]\n", "");
printf("%12s[ -h {md5,sha1,sha2(56),sha384,sha512} ]\n", "");
printf("%12s[ -index <index> ]\n", "");
printf("%12s[ -verbose ]\n", "");
@ -3146,6 +3436,8 @@ static void usage(const char *argv0, const char *cmd)
printf("%12s[ -c | -catalog <infile> ]\n", "");
printf("%12s[ -CAfile <infile> ]\n", "");
printf("%12s[ -CRLfile <infile> ]\n", "");
printf("%12s[ -HTTPS-CAfile <infile> ]\n", "");
printf("%12s[ -HTTPS-CRLfile <infile> ]\n", "");
printf("%12s[ -TSA-CAfile <infile> ]\n", "");
printf("%12s[ -TSA-CRLfile <infile> ]\n", "");
printf("%12s[ -p <proxy> ]\n", "");
@ -3183,6 +3475,7 @@ static void help_for(const char *argv0, const char *cmd)
const char *cmds_certs[] = {"sign", NULL};
const char *cmds_comm[] = {"sign", NULL};
const char *cmds_CRLfile[] = {"attach-signature", "verify", NULL};
const char *cmds_CRLfileHTTPS[] = {"add", "sign", "verify", NULL};
const char *cmds_CRLfileTSA[] = {"attach-signature", "verify", NULL};
const char *cmds_h[] = {"add", "attach-signature", "sign", "extract-data", NULL};
const char *cmds_i[] = {"sign", NULL};
@ -3215,6 +3508,7 @@ static void help_for(const char *argv0, const char *cmd)
const char *cmds_ignore_cdp[] = {"verify", NULL};
const char *cmds_t[] = {"add", "sign", NULL};
const char *cmds_ts[] = {"add", "sign", NULL};
const char *cmds_CAfileHTTPS[] = {"add", "sign", "verify", NULL};
const char *cmds_CAfileTSA[] = {"attach-signature", "verify", NULL};
const char *cmds_certsTSA[] = {"add", "sign", NULL};
const char *cmds_keyTSA[] = {"add", "sign", NULL};
@ -3366,6 +3660,10 @@ static void help_for(const char *argv0, const char *cmd)
}
if (on_list(cmd, cmds_time))
printf("%-24s= the unix-time to set the signing and/or verifying time\n", "-time");
if (on_list(cmd, cmds_CAfileHTTPS))
printf("%-24s= the file containing one or more HTTPS certificates in PEM format\n", "-HTTPS-CAfile");
if (on_list(cmd, cmds_CRLfileHTTPS))
printf("%-24s= the file containing one or more HTTPS CRLs in PEM format\n", "-HTTPS-CRLfile");
if (on_list(cmd, cmds_CAfileTSA))
printf("%-24s= the file containing one or more Time-Stamp Authority certificates in PEM format\n", "-TSA-CAfile");
if (on_list(cmd, cmds_CRLfileTSA))
@ -3932,11 +4230,13 @@ static void print_version(void)
printf("%s, using:\n", "osslsigncode custom build");
#endif /* PACKAGE_STRING */
printf("\t%s (Library: %s)\n", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
#if OPENSSL_VERSION_NUMBER<0x30000000L
#ifdef ENABLE_CURL
printf("\t%s\n", curl_version());
#else /* ENABLE_CURL */
printf("\t%s\n", "no libcurl available");
#endif /* ENABLE_CURL */
#endif /* OPENSSL_VERSION_NUMBER<0x30000000L */
if (cafile) {
printf("Default -CAfile location: %s\n", cafile);
OPENSSL_free(cafile);
@ -4073,8 +4373,9 @@ static int main_configure(int argc, char **argv, GLOBAL_OPTIONS *options)
if (cmd == CMD_HELP) {
return 0; /* FAILED */
}
if (cmd == CMD_VERIFY || cmd == CMD_ATTACH) {
if (cmd == CMD_SIGN || cmd == CMD_VERIFY || cmd == CMD_ATTACH) {
options->cafile = get_cafile();
options->https_cafile = get_cafile();
options->tsa_cafile = get_cafile();
}
for (argc--,argv++; argc >= 1; argc--,argv++) {
@ -4283,11 +4584,26 @@ static int main_configure(int argc, char **argv, GLOBAL_OPTIONS *options)
return 0; /* FAILED */
}
options->crlfile = OPENSSL_strdup(*++argv);
} else if ((cmd == CMD_SIGN || cmd == CMD_ADD || cmd == CMD_VERIFY)
&& !strcmp(*argv, "-HTTPS-CAfile")) {
if (--argc < 1) {
usage(argv0, "all");
return 0; /* FAILED */
}
OPENSSL_free(options->https_cafile);
options->https_cafile = OPENSSL_strdup(*++argv);
} else if ((cmd == CMD_SIGN || cmd == CMD_ADD || cmd == CMD_VERIFY)
&& !strcmp(*argv, "-HTTPS-CRLfile")) {
if (--argc < 1) {
usage(argv0, "all");
return 0; /* FAILED */
}
options->https_crlfile = OPENSSL_strdup(*++argv);
} else if ((cmd == CMD_VERIFY || cmd == CMD_ATTACH) && (!strcmp(*argv, "-untrusted") || !strcmp(*argv, "-TSA-CAfile"))) {
if (--argc < 1) {
usage(argv0, "all");
return 0; /* FAILED */
}
}
OPENSSL_free(options->tsa_cafile);
options->tsa_cafile = OPENSSL_strdup(*++argv);
} else if ((cmd == CMD_VERIFY || cmd == CMD_ATTACH) && (!strcmp(*argv, "-CRLuntrusted") || !strcmp(*argv, "-TSA-CRLfile"))) {