From: Dr. David von Oheimb Date: Tue, 4 Feb 2025 13:12:23 +0000 (+0100) Subject: OSSL_CMP_MSG_http_perform(): support using BIO from OSSL_CMP_CTX_set_transfer_cb_arg() X-Git-Tag: openssl-3.5.0-alpha1~174 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5cba3629098a55a559a9bb177c095fc77b1e8b88;p=thirdparty%2Fopenssl.git OSSL_CMP_MSG_http_perform(): support using BIO from OSSL_CMP_CTX_set_transfer_cb_arg() Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/26628) --- diff --git a/crypto/cmp/cmp_http.c b/crypto/cmp/cmp_http.c index d08c362a702..bf5860f03c5 100644 --- a/crypto/cmp/cmp_http.c +++ b/crypto/cmp/cmp_http.c @@ -26,9 +26,9 @@ #include #include -static int keep_alive(int keep_alive, int body_type) +static int keep_alive(int keep_alive, int body_type, BIO **bios) { - if (keep_alive != 0 + if (keep_alive != 0 && bios == NULL /* * Ask for persistent connection only if may need more round trips. * Do so even with disableConfirm because polling might be needed. @@ -54,6 +54,7 @@ OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, int tls_used; const ASN1_ITEM *it = ASN1_ITEM_rptr(OSSL_CMP_MSG); BIO *req_mem, *rsp; + BIO **bios; /* optionally used as bio and rbio */ OSSL_CMP_MSG *res = NULL; if (ctx == NULL || req == NULL) { @@ -66,25 +67,40 @@ OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, if ((req_mem = ASN1_item_i2d_mem_bio(it, (const ASN1_VALUE *)req)) == NULL) goto err; + bios = OSSL_CMP_CTX_get_transfer_cb_arg(ctx); if (ctx->serverPort != 0) BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort); tls_used = ctx->tls_used >= 0 ? ctx->tls_used != 0 : OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL; /* backward compat */ - if (ctx->http_ctx == NULL) - ossl_cmp_log3(DEBUG, ctx, "connecting to CMP server %s:%s%s", - ctx->server, server_port, tls_used ? " using TLS" : ""); + if (ctx->http_ctx == NULL) { /* using existing connection or yet not set up own connection */ + const char *path = ctx->serverPath; + + if (path == NULL) + path = ""; + if (*path == '/') + path++; + if (bios == NULL) + ossl_cmp_log4(DEBUG, ctx, + "connecting to CMP server via http%s://%s:%s%s/%s", + tls_used ? "s" : "", ctx->server, server_port, path); + else + ossl_cmp_log3(DEBUG, ctx, + "using existing connection with CMP server %s%s and HTTP path /%s", + ctx->server, server_port, path); + } rsp = OSSL_HTTP_transfer(&ctx->http_ctx, ctx->server, server_port, ctx->serverPath, tls_used, ctx->proxy, ctx->no_proxy, - NULL /* bio */, NULL /* rbio */, + bios == NULL ? NULL : bios[0] /* bio */, + bios == NULL ? NULL : bios[1] /* rbio */, ctx->http_cb, OSSL_CMP_CTX_get_http_cb_arg(ctx), 0 /* buf_size */, headers, content_type_pkix, req_mem, content_type_pkix, 1 /* expect_asn1 */, OSSL_HTTP_DEFAULT_MAX_RESP_LEN, ctx->msg_timeout, - keep_alive(ctx->keep_alive, req->body->type)); + keep_alive(ctx->keep_alive, req->body->type, bios)); BIO_free(req_mem); res = (OSSL_CMP_MSG *)ASN1_item_d2i_bio(it, rsp, NULL); BIO_free(rsp); @@ -92,9 +108,11 @@ OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, if (ctx->http_ctx == NULL) ossl_cmp_debug(ctx, "disconnected from CMP server"); /* - * Note that on normal successful end of the transaction the connection - * is not closed at this level, but this will be done by the CMP client - * application via OSSL_CMP_CTX_free() or OSSL_CMP_CTX_reinit(). + * Note that on normal successful end of the transaction the + * HTTP connection is not closed at this level if keep_alive(...) != 0. + * It should be closed by the CMP client application + * using OSSL_CMP_CTX_free() or OSSL_CMP_CTX_reinit(). + * Any pre-existing bio (== ctx->transfer_cb_arg) is not freed. */ if (res != NULL) ossl_cmp_debug(ctx, "finished reading response from CMP server"); diff --git a/doc/man3/OSSL_CMP_CTX_new.pod b/doc/man3/OSSL_CMP_CTX_new.pod index 483524981a5..58540e73cca 100644 --- a/doc/man3/OSSL_CMP_CTX_new.pod +++ b/doc/man3/OSSL_CMP_CTX_new.pod @@ -381,10 +381,14 @@ The default is C. OSSL_CMP_CTX_set1_server() sets the given server I
(which may be a hostname or IP address or NULL) in the given I. +If OSSL_CMP_CTX_get_transfer_cb_arg() sets a non-NULL argument, +this server address information is used for diagnostic output only. OSSL_CMP_CTX_set_serverPort() sets the port of the CMP server to connect to. If not used or the I argument is 0 the default port applies, which is 80 for HTTP and 443 for HTTPS. +If OSSL_CMP_CTX_get_transfer_cb_arg() sets a non-NULL argument, +this server port information is used for diagnostic output only. 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). @@ -419,6 +423,8 @@ a structure containing arguments such as an B structure, optionally to be used by the http connect/disconnect callback function. I is not consumed, and it must therefore explicitly be freed when not needed any more. I may be NULL to clear the entry. +If a non-NULL argument is set, it is an error to use OSSL_CMP_CTX_set1_proxy() +or OSSL_CMP_CTX_set1_no_proxy() for setting non-NULL strings. OSSL_CMP_CTX_get_http_cb_arg() gets the argument, respectively the pointer to a structure containing arguments, previously set by diff --git a/doc/man3/OSSL_CMP_MSG_http_perform.pod b/doc/man3/OSSL_CMP_MSG_http_perform.pod index d675da91143..6cdfbedbe10 100644 --- a/doc/man3/OSSL_CMP_MSG_http_perform.pod +++ b/doc/man3/OSSL_CMP_MSG_http_perform.pod @@ -14,11 +14,21 @@ OSSL_CMP_MSG_http_perform =head1 DESCRIPTION -OSSL_CMP_MSG_http_perform() sends the given PKIMessage I -to the CMP server specified in I via L -and optionally L, using -any "CMP alias" optionally specified via L. -The default port is 80 for HTTP and 443 for HTTPS; the default path is "/". +OSSL_CMP_MSG_http_perform() sends the given PKIMessage I to the +CMP server specified in I and returns the result obtained from it. + +If L has been used to set the transfer +callback argument then the provided pointer I is taken as +a two-element B array to use for the exchange with the server +as described for the I and I parameters of L. +For instance, the two BIO pointers may be equal and refer to a TLS connection, +such as in BRSKI-AE where a pre-established TLS channel is reused for CMP. + +Otherwise the server specified via L +and optionally L is contacted, +where the default port is 80 for HTTP and 443 for HTTPS. +The HTTP path (aka "CMP alias" in this context) to use is by default C, +otherwise the string specified via L. On success the function returns the server's response PKIMessage. The function makes use of any HTTP callback function @@ -38,16 +48,19 @@ HTTP transfer for CMP is defined in RFC 6712. =head1 RETURN VALUES -OSSL_CMP_MSG_http_perform() returns a CMP message on success, else NULL. +OSSL_CMP_MSG_http_perform() +returns the received CMP response message on success, else NULL. =head1 SEE ALSO -L, L. +L, L, and L. =head1 HISTORY The OpenSSL CMP support was added in OpenSSL 3.0. +The OSSL_CMP_MSG_http_perform() use of transfer_cb_arg was added in OpenSSL 3.5. + =head1 COPYRIGHT Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved.