mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-04-27 10:14:36 +00:00
HTTP client: make server/proxy and port params more consistent; minor other improvements
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> (Merged from https://github.com/openssl/openssl/pull/11404)
This commit is contained in:
parent
afe554c2d2
commit
4b1fe471ac
@ -95,7 +95,6 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
|
||||
ctx->status = -1;
|
||||
ctx->failInfoCode = -1;
|
||||
|
||||
ctx->serverPort = OSSL_CMP_DEFAULT_PORT;
|
||||
ctx->msg_timeout = 2 * 60;
|
||||
|
||||
if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL)
|
||||
@ -146,7 +145,7 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
|
||||
return;
|
||||
|
||||
OPENSSL_free(ctx->serverPath);
|
||||
OPENSSL_free(ctx->serverName);
|
||||
OPENSSL_free(ctx->server);
|
||||
OPENSSL_free(ctx->proxy);
|
||||
OPENSSL_free(ctx->no_proxy);
|
||||
|
||||
@ -775,7 +774,7 @@ int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
DEFINE_OSSL_CMP_CTX_set1(proxy, char)
|
||||
|
||||
/* Set the (HTTP) host name of the CMP server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(serverName, char)
|
||||
DEFINE_OSSL_CMP_CTX_set1(server, char)
|
||||
|
||||
/* Set the server exclusion list of the HTTP proxy server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(no_proxy, char)
|
||||
|
@ -35,24 +35,24 @@
|
||||
OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
char server_port[32];
|
||||
char server_port[32] = { '\0' };
|
||||
STACK_OF(CONF_VALUE) *headers = NULL;
|
||||
OSSL_CMP_MSG *res = NULL;
|
||||
const char *const content_type_pkix = "application/pkixcmp";
|
||||
OSSL_CMP_MSG *res;
|
||||
|
||||
if (ctx == NULL || req == NULL
|
||||
|| ctx->serverName == NULL || ctx->serverPort == 0) {
|
||||
if (ctx == NULL || req == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!X509V3_add_value("Pragma", "no-cache", &headers))
|
||||
return NULL;
|
||||
|
||||
BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort);
|
||||
if (ctx->serverPort != 0)
|
||||
BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort);
|
||||
|
||||
res = (OSSL_CMP_MSG *)
|
||||
OSSL_HTTP_post_asn1(ctx->serverName, server_port, ctx->serverPath,
|
||||
OSSL_HTTP_post_asn1(ctx->server, server_port, ctx->serverPath,
|
||||
OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL,
|
||||
ctx->proxy, ctx->no_proxy, NULL, NULL,
|
||||
ctx->http_cb, OSSL_CMP_CTX_get_http_cb_arg(ctx),
|
||||
|
@ -36,7 +36,7 @@ struct ossl_cmp_ctx_st {
|
||||
void *transfer_cb_arg; /* allows to store optional argument to cb */
|
||||
/* HTTP-based transfer */
|
||||
char *serverPath;
|
||||
char *serverName;
|
||||
char *server;
|
||||
int serverPort;
|
||||
char *proxy;
|
||||
char *no_proxy;
|
||||
|
@ -2606,6 +2606,7 @@ HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http
|
||||
HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled
|
||||
HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long
|
||||
HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error
|
||||
HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported
|
||||
HTTP_R_STATUS_CODE_UNSUPPORTED:114:status code unsupported
|
||||
HTTP_R_TLS_NOT_ENABLED:107:tls not enabled
|
||||
HTTP_R_TOO_MANY_REDIRECTIONS:115:too many redirections
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/http.h>
|
||||
#include "internal/sockets.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/cryptlib.h" /* for ossl_assert() */
|
||||
|
||||
#include "http_local.h"
|
||||
|
||||
@ -157,7 +157,7 @@ int OSSL_HTTP_REQ_CTX_header(OSSL_HTTP_REQ_CTX *rctx, const char *server,
|
||||
* Section 5.1.2 of RFC 1945 states that the absoluteURI form is only
|
||||
* allowed when using a proxy
|
||||
*/
|
||||
if (BIO_printf(rctx->mem, "http://%s", server) <= 0)
|
||||
if (BIO_printf(rctx->mem, OSSL_HTTP_PREFIX"%s", server) <= 0)
|
||||
return 0;
|
||||
if (port != NULL && BIO_printf(rctx->mem, ":%s", port) <= 0)
|
||||
return 0;
|
||||
@ -701,10 +701,8 @@ static BIO *HTTP_new_bio(const char *server /* optionally includes ":port" */,
|
||||
const char *port = server_port;
|
||||
BIO *cbio;
|
||||
|
||||
if (server == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
if (!ossl_assert(server != NULL))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (proxy != NULL) {
|
||||
host = proxy;
|
||||
@ -714,7 +712,7 @@ static BIO *HTTP_new_bio(const char *server /* optionally includes ":port" */,
|
||||
host_end = strchr(host, '/');
|
||||
if (host_end != NULL && (size_t)(host_end - host) < sizeof(host_name)) {
|
||||
/* chop trailing string starting with '/' */
|
||||
strncpy(host_name, host, host_end - host);
|
||||
strncpy(host_name, host, host_end - host + 1);
|
||||
host = host_name;
|
||||
}
|
||||
|
||||
@ -849,18 +847,28 @@ BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
|
||||
HTTPerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
/* remaining parameters are checked indirectly by the functions called */
|
||||
|
||||
proxy = http_adapt_proxy(proxy, no_proxy, server, use_ssl);
|
||||
if (bio != NULL)
|
||||
if (bio != NULL) {
|
||||
cbio = bio;
|
||||
else
|
||||
} else {
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
if (server == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if (*port == '\0')
|
||||
port = NULL;
|
||||
if (port == NULL && strchr(server, ':') == NULL)
|
||||
port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT;
|
||||
proxy = http_adapt_proxy(proxy, no_proxy, server, use_ssl);
|
||||
if ((cbio = HTTP_new_bio(server, port, proxy)) == NULL)
|
||||
return NULL;
|
||||
#else
|
||||
HTTPerr(0, HTTP_R_SOCK_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
/* remaining parameters are checked indirectly by the functions called */
|
||||
|
||||
(void)ERR_set_mark(); /* prepare removing any spurious libssl errors */
|
||||
if (rbio == NULL && BIO_connect_retry(cbio, timeout) <= 0)
|
||||
@ -902,10 +910,10 @@ BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
|
||||
if (lib == ERR_LIB_SSL || lib == ERR_LIB_HTTP
|
||||
|| (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_TIMEOUT)
|
||||
|| (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_ERROR)
|
||||
# ifndef OPENSSL_NO_CMP
|
||||
#ifndef OPENSSL_NO_CMP
|
||||
|| (lib == ERR_LIB_CMP
|
||||
&& reason == CMP_R_POTENTIALLY_INVALID_CERTIFICATE)
|
||||
# endif
|
||||
#endif
|
||||
) {
|
||||
BIO_snprintf(buf, 200, "server=%s:%s", server, port);
|
||||
ERR_add_error_data(1, buf);
|
||||
@ -949,8 +957,7 @@ BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
|
||||
|
||||
static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
|
||||
{
|
||||
static const char https[] = "https:";
|
||||
int https_len = 6; /* strlen(https) */
|
||||
size_t https_len = strlen(OSSL_HTTPS_NAME":");
|
||||
|
||||
if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) {
|
||||
HTTPerr(0, HTTP_R_TOO_MANY_REDIRECTIONS);
|
||||
@ -958,8 +965,8 @@ static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
|
||||
}
|
||||
if (*new_url == '/') /* redirection to same server => same protocol */
|
||||
return 1;
|
||||
if (strncmp(old_url, https, https_len) == 0 &&
|
||||
strncmp(new_url, https, https_len) != 0) {
|
||||
if (strncmp(old_url, OSSL_HTTPS_NAME":", https_len) == 0 &&
|
||||
strncmp(new_url, OSSL_HTTPS_NAME":", https_len) != 0) {
|
||||
HTTPerr(0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP);
|
||||
return 0;
|
||||
}
|
||||
@ -1122,8 +1129,8 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
const char *proxyuser, const char *proxypass,
|
||||
int timeout, BIO *bio_err, const char *prog)
|
||||
{
|
||||
# undef BUF_SIZE
|
||||
# define BUF_SIZE (8 * 1024)
|
||||
#undef BUF_SIZE
|
||||
#define BUF_SIZE (8 * 1024)
|
||||
char *mbuf = OPENSSL_malloc(BUF_SIZE);
|
||||
char *mbufp;
|
||||
int read_len = 0;
|
||||
@ -1132,11 +1139,13 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
int rv;
|
||||
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
||||
|
||||
if (bio == NULL || server == NULL || port == NULL
|
||||
if (bio == NULL || server == NULL
|
||||
|| (bio_err != NULL && prog == NULL)) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
goto end;
|
||||
}
|
||||
if (port == NULL || *port == '\0')
|
||||
port = OSSL_HTTPS_PORT;
|
||||
|
||||
if (mbuf == NULL || fbio == NULL) {
|
||||
BIO_printf(bio_err /* may be NULL */, "%s: out of memory", prog);
|
||||
@ -1256,6 +1265,5 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
}
|
||||
OPENSSL_free(mbuf);
|
||||
return ret;
|
||||
# undef BUF_SIZE
|
||||
#undef BUF_SIZE
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,8 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = {
|
||||
"response line too long"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_PARSE_ERROR),
|
||||
"response parse error"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SOCK_NOT_SUPPORTED),
|
||||
"sock not supported"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_STATUS_CODE_UNSUPPORTED),
|
||||
"status code unsupported"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TLS_NOT_ENABLED), "tls not enabled"},
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <openssl/httperr.h>
|
||||
#include <openssl/err.h>
|
||||
#include <string.h>
|
||||
#include "internal/cryptlib.h" /* for ossl_assert() */
|
||||
|
||||
#include "http_local.h"
|
||||
|
||||
@ -24,8 +25,11 @@ int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport,
|
||||
{
|
||||
char *p, *buf;
|
||||
char *host;
|
||||
char *port = "80";
|
||||
const char *port = OSSL_HTTP_PORT;
|
||||
size_t https_len = strlen(OSSL_HTTPS_NAME);
|
||||
|
||||
if (!ossl_assert(https_len >= strlen(OSSL_HTTP_NAME)))
|
||||
return 0;
|
||||
if (url == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
@ -46,16 +50,16 @@ int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport,
|
||||
|
||||
/* Check for initial colon */
|
||||
p = strchr(buf, ':');
|
||||
if (p == NULL || p - buf > 5 /* strlen("https") */) {
|
||||
if (p == NULL || (size_t)(p - buf) > https_len) {
|
||||
p = buf;
|
||||
} else {
|
||||
*(p++) = '\0';
|
||||
|
||||
if (strcmp(buf, "https") == 0) {
|
||||
if (strcmp(buf, OSSL_HTTPS_NAME) == 0) {
|
||||
if (pssl != NULL)
|
||||
*pssl = 1;
|
||||
port = "443";
|
||||
} else if (strcmp(buf, "http") != 0) {
|
||||
port = OSSL_HTTPS_PORT;
|
||||
} else if (strcmp(buf, OSSL_HTTP_NAME) != 0) {
|
||||
goto parse_err;
|
||||
}
|
||||
|
||||
@ -119,13 +123,21 @@ int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport,
|
||||
|
||||
int http_use_proxy(const char *no_proxy, const char *server)
|
||||
{
|
||||
size_t sl = strlen(server);
|
||||
size_t sl;
|
||||
const char *found = NULL;
|
||||
|
||||
if (!ossl_assert(server != NULL))
|
||||
return 0;
|
||||
sl = strlen(server);
|
||||
|
||||
/*
|
||||
* using environment variable names, both lowercase and uppercase variants,
|
||||
* compatible with other HTTP client implementations like wget, curl and git
|
||||
*/
|
||||
if (no_proxy == NULL)
|
||||
no_proxy = getenv("no_proxy");
|
||||
if (no_proxy == NULL)
|
||||
no_proxy = getenv("NO_PROXY");
|
||||
no_proxy = getenv(OPENSSL_NO_PROXY);
|
||||
if (no_proxy != NULL)
|
||||
found = strstr(no_proxy, server);
|
||||
while (found != NULL
|
||||
@ -138,17 +150,28 @@ int http_use_proxy(const char *no_proxy, const char *server)
|
||||
const char *http_adapt_proxy(const char *proxy, const char *no_proxy,
|
||||
const char *server, int use_ssl)
|
||||
{
|
||||
int prefix_len = strlen(HTTP_URL_PREFIX);
|
||||
const int http_len = strlen(OSSL_HTTP_PREFIX);
|
||||
const int https_len = strlen(OSSL_HTTPS_PREFIX);
|
||||
|
||||
/*
|
||||
* using environment variable names, both lowercase and uppercase variants,
|
||||
* compatible with other HTTP client implementations like wget, curl and git
|
||||
*/
|
||||
if (proxy == NULL)
|
||||
proxy = getenv(use_ssl ? "https_proxy" : "http_proxy");
|
||||
if (proxy == NULL)
|
||||
proxy = getenv(use_ssl ? "HTTPS_PROXY" : "HTTP_PROXY");
|
||||
if (proxy != NULL && strncmp(proxy, HTTP_URL_PREFIX, prefix_len) == 0)
|
||||
proxy += prefix_len; /* skip any leading "http://" */
|
||||
if (proxy != NULL && *proxy == '\0')
|
||||
proxy = NULL;
|
||||
if (proxy != NULL && !http_use_proxy(no_proxy, server))
|
||||
proxy = NULL;
|
||||
proxy = getenv(use_ssl ? OPENSSL_HTTP_PROXY :
|
||||
OPENSSL_HTTPS_PROXY);
|
||||
if (proxy == NULL)
|
||||
return NULL;
|
||||
|
||||
/* skip any leading "http://" or "https://" */
|
||||
if (strncmp(proxy, OSSL_HTTP_PREFIX, http_len) == 0)
|
||||
proxy += http_len;
|
||||
else if (strncmp(proxy, OSSL_HTTPS_PREFIX, https_len) == 0)
|
||||
proxy += https_len;
|
||||
|
||||
if (*proxy == '\0' || !http_use_proxy(no_proxy, server))
|
||||
return NULL;
|
||||
return proxy;
|
||||
}
|
||||
|
@ -27,8 +27,6 @@ typedef OCSP_REQ_CTX OSSL_HTTP_REQ_CTX;
|
||||
# define OSSL_HTTP_REQ_CTX_get0_mem_bio OCSP_REQ_CTX_get0_mem_bio /* undoc'd */
|
||||
# define OSSL_HTTP_REQ_CTX_set_max_response_length OCSP_set_max_response_length
|
||||
|
||||
# define HTTP_URL_PREFIX "http://"
|
||||
|
||||
BIO *HTTP_asn1_item2bio(const ASN1_ITEM *it, ASN1_VALUE *val);
|
||||
OSSL_HTTP_REQ_CTX *HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int use_http_proxy,
|
||||
const char *server, const char *port,
|
||||
|
@ -11,11 +11,10 @@ OSSL_CMP_CTX_set_log_cb,
|
||||
OSSL_CMP_CTX_set_log_verbosity,
|
||||
OSSL_CMP_CTX_print_errors,
|
||||
OSSL_CMP_CTX_set1_serverPath,
|
||||
OSSL_CMP_CTX_set1_serverName,
|
||||
OSSL_CMP_CTX_set1_server,
|
||||
OSSL_CMP_CTX_set_serverPort,
|
||||
OSSL_CMP_CTX_set1_proxy,
|
||||
OSSL_CMP_CTX_set1_no_proxy,
|
||||
OSSL_CMP_DEFAULT_PORT,
|
||||
OSSL_CMP_CTX_set_http_cb,
|
||||
OSSL_CMP_CTX_set_http_cb_arg,
|
||||
OSSL_CMP_CTX_get_http_cb_arg,
|
||||
@ -78,11 +77,10 @@ OSSL_CMP_CTX_set1_senderNonce
|
||||
|
||||
/* message transfer: */
|
||||
int OSSL_CMP_CTX_set1_serverPath(OSSL_CMP_CTX *ctx, const char *path);
|
||||
int OSSL_CMP_CTX_set1_serverName(OSSL_CMP_CTX *ctx, const char *name);
|
||||
int OSSL_CMP_CTX_set1_server(OSSL_CMP_CTX *ctx, const char *address);
|
||||
int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port);
|
||||
int OSSL_CMP_CTX_set1_proxy(OSSL_CMP_CTX *ctx, const char *name);
|
||||
int OSSL_CMP_CTX_set1_no_proxy(OSSL_CMP_CTX *ctx, const char *names);
|
||||
#define OSSL_CMP_DEFAULT_PORT 80
|
||||
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, HTTP_bio_cb_t cb);
|
||||
int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg);
|
||||
void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx);
|
||||
@ -306,19 +304,26 @@ It is similar to B<ERR_print_errors_cb()> but uses the CMP log callback function
|
||||
if set in the C<ctx> for uniformity with CMP logging if given. Otherwise it uses
|
||||
B<ERR_print_errors(3)> to print to STDERR (unless OPENSSL_NO_STDIO is defined).
|
||||
|
||||
OSSL_CMP_CTX_set1_serverPath() sets the HTTP path of the CMP server on the host.
|
||||
OSSL_CMP_CTX_set1_serverPath() sets the HTTP path of the CMP server on the host,
|
||||
also known as "CMP alias".
|
||||
The default is "/".
|
||||
|
||||
OSSL_CMP_CTX_set1_serverName() sets the given server Address (as IP or name)
|
||||
in the given OSSL_CMP_CTX structure.
|
||||
OSSL_CMP_CTX_set1_server() sets the given server B<address>
|
||||
(which may be a hostname or IP address or NULL) in the given B<ctx>.
|
||||
|
||||
OSSL_CMP_CTX_set_serverPort() sets the port of the CMP server to connect to.
|
||||
Port defaults to OSSL_CMP_DEFAULT_PORT = 80 if not set explicitly.
|
||||
If not used or the B<port> argument is 0
|
||||
the default port applies, which is 80 for HTTP and 443 for HTTPS.
|
||||
|
||||
OSSL_CMP_CTX_set1_proxy() sets the HTTP proxy to be used for connecting to the
|
||||
CMP server.
|
||||
Defaults to the environment variable B<http_proxy> if set, else B<HTTP_PROXY>
|
||||
in case no TLS is used, otherwise B<https_proxy> if set, else B<HTTPS_PROXY>.
|
||||
The format is [http://]address[:port][/path] where the optional path is ignored.
|
||||
OSSL_CMP_CTX_set1_proxy() sets the HTTP proxy to be used for connecting to
|
||||
the given CMP server unless overruled by any "no_proxy" settings (see below).
|
||||
If TLS is not used this defaults to the value of
|
||||
the environment variable B<http_proxy> if set, else B<HTTP_PROXY>.
|
||||
Otherwise defaults to the value of B<https_proxy> if set, else B<HTTPS_PROXY>.
|
||||
An empty proxy string specifies not to use a proxy.
|
||||
Else the format is I<[http[s]://]address[:port][/path]>,
|
||||
where any path given is ignored.
|
||||
The default port number is 80, or 443 in case "https:" is given.
|
||||
|
||||
OSSL_CMP_CTX_set1_no_proxy() sets the list of server hostnames not to use
|
||||
an HTTP proxy for. The names may be separated by commas and/or whitespace.
|
||||
@ -606,7 +611,7 @@ All other functions return 1 on success, 0 on error.
|
||||
The following code does an Initialization Request:
|
||||
|
||||
cmp_ctx = OSSL_CMP_CTX_new();
|
||||
OSSL_CMP_CTX_set1_serverName(cmp_ctx, opt_serverName);
|
||||
OSSL_CMP_CTX_set1_server(cmp_ctx, address);
|
||||
OSSL_CMP_CTX_set1_referenceValue(cmp_ctx, ref, ref_len);
|
||||
OSSL_CMP_CTX_set1_secretValue(cmp_ctx, sec, sec_len);
|
||||
OSSL_CMP_CTX_set0_newPkey(cmp_ctx, new_pkey, 1);
|
||||
@ -618,7 +623,7 @@ The following code does an Initialization Request using an
|
||||
external identity certificate (RFC 4210, Appendix E.7):
|
||||
|
||||
cmp_ctx = OSSL_CMP_CTX_new();
|
||||
OSSL_CMP_CTX_set1_serverName(cmp_ctx, sname);
|
||||
OSSL_CMP_CTX_set1_server(cmp_ctx, sname);
|
||||
OSSL_CMP_CTX_set1_clCert(cmp_ctx, cl_cert);
|
||||
OSSL_CMP_CTX_set1_pkey(cmp_ctx, pkey);
|
||||
OSSL_CMP_CTX_set0_newPkey(cmp_ctx, new_pkey, 1);
|
||||
@ -633,7 +638,7 @@ which is trusted by the current CA the code will connect to.
|
||||
The following code does a Key Update Request:
|
||||
|
||||
cmp_ctx = OSSL_CMP_CTX_new();
|
||||
OSSL_CMP_CTX_set1_serverName(cmp_ctx, sname);
|
||||
OSSL_CMP_CTX_set1_server(cmp_ctx, url);
|
||||
OSSL_CMP_CTX_set1_pkey(cmp_ctx, pkey);
|
||||
OSSL_CMP_CTX_set0_newPkey(cmp_ctx, new_pkey, 1);
|
||||
OSSL_CMP_CTX_set1_clCert(cmp_ctx, cl_cert);
|
||||
@ -646,7 +651,7 @@ including, as an example, the id-it-signKeyPairTypes OID and prints info on
|
||||
the General Response contents.
|
||||
|
||||
cmp_ctx = OSSL_CMP_CTX_new();
|
||||
OSSL_CMP_CTX_set1_serverName(cmp_ctx, sname);
|
||||
OSSL_CMP_CTX_set1_server(cmp_ctx, sname);
|
||||
OSSL_CMP_CTX_set1_referenceValue(cmp_ctx, ref, ref_len);
|
||||
OSSL_CMP_CTX_set1_secretValue(cmp_ctx, sec, sec_len);
|
||||
|
||||
|
@ -3,35 +3,46 @@
|
||||
=head1 NAME
|
||||
|
||||
OSSL_CMP_MSG_http_perform
|
||||
- implementation of HTTP transfer for CMP messages
|
||||
- client-side HTTP(S) transfer of a CMP request-response pair
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/cmp.h>
|
||||
|
||||
SSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req);
|
||||
OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is the API for creating a BIO for CMP (Certificate Management
|
||||
Protocol) over HTTP(S) with OpenSSL.
|
||||
OSSL_CMP_MSG_http_perform() sends the given PKIMessage B<req>
|
||||
to the CMP server specified in B<ctx> via L<OSSL_CMP_CTX_set1_server(3)>
|
||||
and optionally L<OSSL_CMP_CTX_set_serverPort(3)>, using
|
||||
any "CMP alias" optionally specified via L<OSSL_CMP_CTX_set1_serverPath(3)>.
|
||||
The default port is 80 for HTTP and 443 for HTTPS; the default path is "/".
|
||||
On success the function returns the server's response PKIMessage.
|
||||
|
||||
OSSL_CMP_MSG_http_perform() sends the given PKIMessage req to the CMP server
|
||||
specified in ctx. On success it returns the server's response.
|
||||
The function makes use of any HTTP callback function
|
||||
set via L<OSSL_CMP_CTX_set_http_cb(3)>.
|
||||
It respects any timeout value set via L<OSSL_CMP_CTX_set_option(3)>
|
||||
with an B<OSSL_CMP_OPT_MSG_TIMEOUT> argument.
|
||||
It also respects any HTTP(S) proxy options set via L<OSSL_CMP_CTX_set1_proxy(3)>
|
||||
and L<OSSL_CMP_CTX_set1_no_proxy(3)> and the respective environment variables.
|
||||
Proxying plain HTTP is supported directly,
|
||||
while using a proxy for HTTPS connections requires a suitable callback function
|
||||
such as L<OSSL_HTTP_proxy_connect(3)>.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
CMP is defined in RFC 4210 (and CRMF in RFC 4211).
|
||||
CMP is defined in RFC 4210.
|
||||
HTTP transfer for CMP is defined in RFC 6712.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
OSSL_CMP_MSG_http_perform() returns a message on success or else NULL.
|
||||
It uses ctx->http_cb if set and respects ctx->msgTimeOut.
|
||||
OSSL_CMP_MSG_http_perform() returns a CMP message on success, else NULL.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<OSSL_CMP_CTX_new(3)>, L<OSSL_CMP_exec_IR_ses(3)>
|
||||
L<OSSL_CMP_CTX_new(3)>, L<OSSL_HTTP_proxy_connect(3)>.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
|
@ -69,17 +69,18 @@ and returns it on success as a pointer to I<ASN1_VALUE>.
|
||||
|
||||
OSSL_HTTP_post_asn1() uses the HTTP POST method to send a request B<req>
|
||||
with the ASN.1 structure defined in B<req_it> and the given B<content_type> to
|
||||
the given B<server> and optional B<port> and B<path>, which defaults to "/".
|
||||
the given B<server> and optional B<port> and B<path>.
|
||||
If B<use_ssl> is nonzero a TLS connection is requested and the B<bio_update_fn>
|
||||
parameter, described below, must be provided.
|
||||
The optional list B<headers> may contain additional custom HTTP header lines.
|
||||
The expected structure of the response is specified by B<rsp_it>.
|
||||
On success it returns the response as a pointer to B<ASN1_VALUE>.
|
||||
|
||||
OSSL_HTTP_transfer() exchanges an HTTP request and response with
|
||||
the given B<server> and optional B<port> and B<path>, which defaults to "/".
|
||||
If B<use_ssl> is nonzero a TLS connection is requested and the B<bio_update_fn>
|
||||
parameter, described below, must be provided.
|
||||
OSSL_HTTP_transfer() exchanges any form of HTTP request and response.
|
||||
It implements the core of the functions described above.
|
||||
If B<path> parameter is NULL it defaults to "/".
|
||||
If B<use_ssl> is nonzero a TLS connection is requested
|
||||
and the B<bio_update_fn> parameter, described below, must be provided.
|
||||
If B<req_mem> is NULL it uses the HTTP GET method, else it uses HTTP POST to
|
||||
send a request with the contents of the memory BIO and optional B<content_type>.
|
||||
The optional list B<headers> may contain additional custom HTTP header lines.
|
||||
@ -91,30 +92,36 @@ L<OPENSSL_free(3)>.
|
||||
|
||||
The above functions have the following parameters in common.
|
||||
|
||||
If the optional B<proxy> parameter contains a non-empty string or
|
||||
it is NULL and one of the environment variables B<http_proxy> and B<HTTP_PROXY>
|
||||
(or B<https_proxy> and B<HTTPS_PROXY>, respectively, in case B<use_ssl> != 0)
|
||||
is set and contains a non-empty string this is used as the candidate address
|
||||
of HTTP(S) proxy to use.
|
||||
The address may include a port specification separated by ':'.
|
||||
Any prefix "http://" and any trailing string starting with '/' is ignored.
|
||||
The HTTP client functions connect via the given proxy unless the B<server>
|
||||
is found in the optional list B<no_proxy> of proxy hostnames (if it is not NULL,
|
||||
else in the environment variable B<no_proxy> if set or else in B<HTTP_PROXY>).
|
||||
Proxying plain HTTP is supported directly,
|
||||
while using a proxy for HTTPS connections requires a suitable callback function
|
||||
such as OSSL_HTTP_proxy_connect(), described below.
|
||||
|
||||
Typically the B<bio> and B<rbio> parameters are NULL and the client creates a
|
||||
network BIO internally for connecting to the given server and port (optionally
|
||||
via a proxy and its port), and uses it for exchanging the request and response.
|
||||
If B<bio> is given and B<rbio> is NULL then the client uses this BIO instead.
|
||||
Typically the OpenSSL build supports sockets
|
||||
and the B<bio> and B<rbio> parameters are both NULL.
|
||||
In this case the client creates a network BIO internally
|
||||
for connecting to the given B<server>
|
||||
at the specified B<port> (if any, defaulting to 80 for HTTP or 443 for HTTPS),
|
||||
optionally via a B<proxy> (respecting B<no_proxy>) as described below.
|
||||
Then the client uses this internal BIO for exchanging the request and response.
|
||||
If B<bio> is given and B<rbio> is NULL then the client uses this B<bio> instead.
|
||||
If both B<bio> and B<rbio> are given (which may be memory BIOs for instance)
|
||||
then no explicit connection is attempted,
|
||||
B<bio> is used for writing the request, and B<rbio> for reading the response.
|
||||
As soon as the client has flushed B<bio> the server must be ready to provide
|
||||
a response or indicate a waiting condition via B<rbio>.
|
||||
|
||||
The optional B<proxy> parameter can be used to set the address of the an
|
||||
HTTP(S) proxy to use (unless overridden by "no_proxy" settings).
|
||||
If TLS is not used this defaults to the environment variable B<http_proxy>
|
||||
if set, else B<HTTP_PROXY>.
|
||||
If B<use_ssl> != 0 it defaults to B<https_proxy> if set, else B<HTTPS_PROXY>.
|
||||
An empty proxy string specifies not to use a proxy.
|
||||
Else the format is I<[http[s]://]address[:port][/path]>,
|
||||
where any path given is ignored.
|
||||
The default proxy port number is 80, or 443 in case "https:" is given.
|
||||
The HTTP client functions connect via the given proxy unless the B<server>
|
||||
is found in the optional list B<no_proxy> of proxy hostnames (if not NULL;
|
||||
default is the environment variable B<no_proxy> if set, else B<NO_PROXY>).
|
||||
Proxying plain HTTP is supported directly,
|
||||
while using a proxy for HTTPS connections requires a suitable callback function
|
||||
such as B<OSSL_HTTP_proxy_connect()>, described below.
|
||||
|
||||
The B<maxline> parameter specifies the response header maximum line length,
|
||||
where 0 indicates the default value, which currently is 4k.
|
||||
The B<max_resp_len> parameter specifies the maximum response length,
|
||||
@ -123,7 +130,7 @@ where 0 indicates the default value, which currently is 100k.
|
||||
An ASN.1-encoded response is expected by OSSL_HTTP_get_asn1() and
|
||||
OSSL_HTTP_post_asn1(), while for OSSL_HTTP_get() or OSSL_HTTP_transfer()
|
||||
this is only the case if the B<expect_asn1> parameter is nonzero.
|
||||
If the response header contains one or more Content-Length header lines and/or
|
||||
If the response header contains one or more "Content-Length" header lines and/or
|
||||
an ASN.1-encoded response is expected, which should include a total length,
|
||||
the length indications received are checked for consistency
|
||||
and for not exceeding the maximum response length.
|
||||
@ -172,11 +179,12 @@ Here is a simple example that supports TLS connections (but not via a proxy):
|
||||
After disconnect the modified BIO will be deallocated using BIO_free_all().
|
||||
|
||||
OSSL_HTTP_proxy_connect() may be used by an above BIO connect callback function
|
||||
to set up an SSL/TLS connection via an HTTP proxy.
|
||||
to set up an SSL/TLS connection via an HTTPS proxy.
|
||||
It promotes the given BIO B<bio> representing a connection
|
||||
pre-established with a TLS proxy using the HTTP CONNECT method,
|
||||
optionally using proxy client credentials B<proxyuser> and B<proxypass>,
|
||||
to connect with TLS protection ultimately to B<server> and B<port>.
|
||||
If the B<port> argument is NULL or the empty string it defaults to "443".
|
||||
The B<timeout> parameter is used as described above.
|
||||
Since this function is typically called by appplications such as
|
||||
L<openssl-s_client(1)> it uses the B<bio_err> and B<prog> parameters (unless
|
||||
@ -192,6 +200,13 @@ them copies of the respective string components.
|
||||
The strings returned this way must be deallocated by the caller using
|
||||
L<OPENSSL_free(3)> unless they are NULL, which is their default value on error.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
The names of the environment variables used by this implementation:
|
||||
B<http_proxy>, B<HTTP_PROXY>, B<https_proxy>, B<HTTPS_PROXY>, B<no_proxy>, and
|
||||
B<NO_PROXY>, have been chosen for maximal compatibility with
|
||||
other HTTP client implementations such as wget, curl, and git.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
OSSL_HTTP_get(), OSSL_HTTP_get_asn1(), OSSL_HTTP_post_asn1(), and
|
||||
|
@ -274,9 +274,8 @@ int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb);
|
||||
void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx);
|
||||
/* message transfer: */
|
||||
int OSSL_CMP_CTX_set1_serverPath(OSSL_CMP_CTX *ctx, const char *path);
|
||||
int OSSL_CMP_CTX_set1_serverName(OSSL_CMP_CTX *ctx, const char *name);
|
||||
int OSSL_CMP_CTX_set1_server(OSSL_CMP_CTX *ctx, const char *address);
|
||||
int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port);
|
||||
# define OSSL_CMP_DEFAULT_PORT 80
|
||||
int OSSL_CMP_CTX_set1_proxy(OSSL_CMP_CTX *ctx, const char *name);
|
||||
int OSSL_CMP_CTX_set1_no_proxy(OSSL_CMP_CTX *ctx, const char *names);
|
||||
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb);
|
||||
|
@ -25,6 +25,16 @@ extern "C" {
|
||||
|
||||
typedef BIO *(*OSSL_HTTP_bio_cb_t)(BIO *bio, void *arg, int connect, int detail);
|
||||
|
||||
# define OSSL_HTTP_NAME "http"
|
||||
# define OSSL_HTTPS_NAME "https"
|
||||
# define OSSL_HTTP_PREFIX OSSL_HTTP_NAME"://"
|
||||
# define OSSL_HTTPS_PREFIX OSSL_HTTPS_NAME"://"
|
||||
# define OSSL_HTTP_PORT "80"
|
||||
# define OSSL_HTTPS_PORT "443"
|
||||
# define OPENSSL_NO_PROXY "NO_PROXY"
|
||||
# define OPENSSL_HTTP_PROXY "HTTP_PROXY"
|
||||
# define OPENSSL_HTTPS_PROXY "HTTPS_PROXY"
|
||||
|
||||
BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,
|
||||
BIO *bio, BIO *rbio,
|
||||
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@ -47,6 +47,7 @@ int ERR_load_HTTP_strings(void);
|
||||
# define HTTP_R_REDIRECTION_NOT_ENABLED 116
|
||||
# define HTTP_R_RESPONSE_LINE_TOO_LONG 113
|
||||
# define HTTP_R_RESPONSE_PARSE_ERROR 104
|
||||
# define HTTP_R_SOCK_NOT_SUPPORTED 122
|
||||
# define HTTP_R_STATUS_CODE_UNSUPPORTED 114
|
||||
# define HTTP_R_TLS_NOT_ENABLED 107
|
||||
# define HTTP_R_TOO_MANY_REDIRECTIONS 115
|
||||
|
@ -51,7 +51,7 @@ IF[{- !$disabled{tests} -}]
|
||||
x509_time_test x509_dup_cert_test x509_check_cert_pkey_test \
|
||||
recordlentest drbgtest drbg_cavs_test drbg_extra_test sslbuffertest \
|
||||
time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \
|
||||
servername_test ocspapitest fatalerrtest tls13ccstest \
|
||||
http_test servername_test ocspapitest fatalerrtest tls13ccstest \
|
||||
sysdefaulttest errtest ssl_ctx_test gosttest \
|
||||
context_internal_test aesgcmtest params_test evp_pkey_dparams_test \
|
||||
keymgmt_internal_test
|
||||
@ -380,6 +380,10 @@ IF[{- !$disabled{tests} -}]
|
||||
INCLUDE[ciphername_test]=../include ../apps/include
|
||||
DEPEND[ciphername_test]=../libcrypto ../libssl libtestutil.a
|
||||
|
||||
SOURCE[http_test]=http_test.c
|
||||
INCLUDE[http_test]=../include ../apps/include
|
||||
DEPEND[http_test]=../libcrypto libtestutil.a
|
||||
|
||||
SOURCE[servername_test]=servername_test.c ssltestlib.c
|
||||
INCLUDE[servername_test]=../include ../apps/include
|
||||
DEPEND[servername_test]=../libcrypto ../libssl libtestutil.a
|
||||
|
@ -492,7 +492,6 @@ static X509_STORE *X509_STORE_new_1(void)
|
||||
|
||||
#define IS_NEG(x) ((x) < 0)
|
||||
#define IS_0(x) ((x) == 0) /* for any type */
|
||||
#define IS_DEFAULT_PORT(x) ((x) == OSSL_CMP_DEFAULT_PORT)
|
||||
#define DROP(x) (void)(x) /* dummy free() for non-pointer and function types */
|
||||
|
||||
#define ERR(x) (CMPerr(0, CMP_R_NULL_ARGUMENT), x)
|
||||
@ -555,12 +554,12 @@ typedef OSSL_HTTP_bio_cb_t OSSL_CMP_http_cb_t;
|
||||
DEFAULT, 1, DROP)
|
||||
#define DEFINE_SET_GET_INT_TEST(OSSL_CMP, CTX, FIELD) \
|
||||
DEFINE_SET_GET_INT_TEST_DEFAULT(OSSL_CMP, CTX, FIELD, IS_NEG)
|
||||
#define DEFINE_SET_PORT_TEST(FIELD) \
|
||||
#define DEFINE_SET_INT_TEST(FIELD) \
|
||||
static int OSSL_CMP_CTX_get_##FIELD(const CMP_CTX *ctx) \
|
||||
{ \
|
||||
return ctx == NULL ? ERR(-1) : ctx->FIELD; \
|
||||
} \
|
||||
DEFINE_SET_GET_INT_TEST_DEFAULT(OSSL_CMP, CTX, FIELD, IS_DEFAULT_PORT)
|
||||
DEFINE_SET_GET_INT_TEST_DEFAULT(OSSL_CMP, CTX, FIELD, IS_0)
|
||||
|
||||
#define DEFINE_SET_GET_ARG_FN(SETN, GETN, FIELD, ARG, T) \
|
||||
static int OSSL_CMP_CTX_##SETN##_##FIELD##_##ARG(CMP_CTX *ctx, T val) \
|
||||
@ -716,8 +715,8 @@ DEFINE_SET_GET_BASE_TEST(OSSL_CMP_CTX, set, get, 0, option_16, int, -1, IS_0, \
|
||||
DEFINE_SET_CB_TEST(log_cb)
|
||||
|
||||
DEFINE_SET_TEST_DEFAULT(OSSL_CMP, CTX, 1, 1, serverPath, char, IS_0)
|
||||
DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, serverName, char)
|
||||
DEFINE_SET_PORT_TEST(serverPort)
|
||||
DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, server, char)
|
||||
DEFINE_SET_INT_TEST(serverPort)
|
||||
DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, proxy, char)
|
||||
DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, no_proxy, char)
|
||||
DEFINE_SET_CB_TEST(http_cb)
|
||||
@ -801,7 +800,7 @@ int setup_tests(void)
|
||||
#endif
|
||||
/* message transfer: */
|
||||
ADD_TEST(test_CTX_set1_get0_serverPath);
|
||||
ADD_TEST(test_CTX_set1_get0_serverName);
|
||||
ADD_TEST(test_CTX_set1_get0_server);
|
||||
ADD_TEST(test_CTX_set_get_serverPort);
|
||||
ADD_TEST(test_CTX_set1_get0_proxy);
|
||||
ADD_TEST(test_CTX_set1_get0_no_proxy);
|
||||
|
@ -4755,7 +4755,7 @@ OSSL_CMP_CTX_get_option ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_CTX_set_log_cb ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_CTX_print_errors ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_CTX_set1_serverPath ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_CTX_set1_serverName ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_CTX_set1_server ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_CTX_set_serverPort ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_CTX_set1_proxy ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_CTX_set1_no_proxy ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
@ -4990,9 +4990,9 @@ OSSL_CMP_exec_CR_ses ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_exec_P10CR_ses ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_exec_KUR_ses ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_try_certreq ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_certConf_cb ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_exec_RR_ses ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_exec_GENM_ses ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_certConf_cb ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
OSSL_CMP_MSG_http_perform ? 3_0_0 EXIST::FUNCTION:CMP
|
||||
EVP_PKEY_gen ? 3_0_0 EXIST::FUNCTION:
|
||||
EVP_PKEY_CTX_set_rsa_keygen_bits ? 3_0_0 EXIST::FUNCTION:RSA
|
||||
|
@ -353,7 +353,6 @@ OpenSSL_add_all_digests define deprecated 1.1.0
|
||||
OpenSSL_add_ssl_algorithms define
|
||||
OSSL_CMP_CTX_set_log_verbosity define
|
||||
OSSL_CMP_CR define
|
||||
OSSL_CMP_DEFAULT_PORT define
|
||||
OSSL_CMP_IR define
|
||||
OSSL_CMP_KUR define
|
||||
OSSL_CMP_LOG_ALERT define
|
||||
|
Loading…
x
Reference in New Issue
Block a user