summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/vtls/openssl.c
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2022-10-31 20:11:41 (GMT)
committerBrad King <brad.king@kitware.com>2022-10-31 20:11:41 (GMT)
commit9ffe6b0969fc270cc2a1aac2b2c1bf986af291d5 (patch)
tree75711965f7fd24679383853a840f42efff676e31 /Utilities/cmcurl/lib/vtls/openssl.c
parentfa9bbb8627e8af5153367721eb037b6e094670d1 (diff)
parentec122fff08ab9a8e56fb90126ecedb99c759011b (diff)
downloadCMake-9ffe6b0969fc270cc2a1aac2b2c1bf986af291d5.zip
CMake-9ffe6b0969fc270cc2a1aac2b2c1bf986af291d5.tar.gz
CMake-9ffe6b0969fc270cc2a1aac2b2c1bf986af291d5.tar.bz2
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2022-10-26 (cd95ee9f)
Diffstat (limited to 'Utilities/cmcurl/lib/vtls/openssl.c')
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.c820
1 files changed, 369 insertions, 451 deletions
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index 5d1203b..0dc695d 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -18,6 +18,8 @@
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
+ * SPDX-License-Identifier: curl
+ *
***************************************************************************/
/*
@@ -27,7 +29,7 @@
#include "curl_setup.h"
-#ifdef USE_OPENSSL
+#if defined(USE_QUICHE) || defined(USE_OPENSSL)
#include <limits.h>
@@ -53,6 +55,7 @@
#include "slist.h"
#include "select.h"
#include "vtls.h"
+#include "vauth/vauth.h"
#include "keylog.h"
#include "strcase.h"
#include "hostcheck.h"
@@ -76,10 +79,6 @@
#include <openssl/buffer.h>
#include <openssl/pkcs12.h>
-#ifdef USE_AMISSL
-#include "amigaos.h"
-#endif
-
#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP)
#include <openssl/ocsp.h>
#endif
@@ -275,6 +274,344 @@ struct ssl_backend_data {
#endif
};
+#define push_certinfo(_label, _num) \
+do { \
+ long info_len = BIO_get_mem_data(mem, &ptr); \
+ Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \
+ if(1 != BIO_reset(mem)) \
+ break; \
+} while(0)
+
+static void pubkey_show(struct Curl_easy *data,
+ BIO *mem,
+ int num,
+ const char *type,
+ const char *name,
+ const BIGNUM *bn)
+{
+ char *ptr;
+ char namebuf[32];
+
+ msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
+
+ if(bn)
+ BN_print(mem, bn);
+ push_certinfo(namebuf, num);
+}
+
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#define print_pubkey_BN(_type, _name, _num) \
+ pubkey_show(data, mem, _num, #_type, #_name, _name)
+
+#else
+#define print_pubkey_BN(_type, _name, _num) \
+do { \
+ if(_type->_name) { \
+ pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
+ } \
+} while(0)
+#endif
+
+static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
+{
+ int i, ilen;
+
+ ilen = (int)len;
+ if(ilen < 0)
+ return 1; /* buffer too big */
+
+ i = i2t_ASN1_OBJECT(buf, ilen, a);
+
+ if(i >= ilen)
+ return 1; /* buffer too small */
+
+ return 0;
+}
+
+static void X509V3_ext(struct Curl_easy *data,
+ int certnum,
+ CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
+{
+ int i;
+
+ if((int)sk_X509_EXTENSION_num(exts) <= 0)
+ /* no extensions, bail out */
+ return;
+
+ for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) {
+ ASN1_OBJECT *obj;
+ X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+ BUF_MEM *biomem;
+ char namebuf[128];
+ BIO *bio_out = BIO_new(BIO_s_mem());
+
+ if(!bio_out)
+ return;
+
+ obj = X509_EXTENSION_get_object(ext);
+
+ asn1_object_dump(obj, namebuf, sizeof(namebuf));
+
+ if(!X509V3_EXT_print(bio_out, ext, 0, 0))
+ ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
+
+ BIO_get_mem_ptr(bio_out, &biomem);
+ Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data,
+ biomem->length);
+ BIO_free(bio_out);
+ }
+}
+
+#ifdef OPENSSL_IS_BORINGSSL
+typedef size_t numcert_t;
+#else
+typedef int numcert_t;
+#endif
+
+CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl)
+{
+ CURLcode result;
+ STACK_OF(X509) *sk;
+ int i;
+ numcert_t numcerts;
+ BIO *mem;
+
+ DEBUGASSERT(ssl);
+
+ sk = SSL_get_peer_cert_chain(ssl);
+ if(!sk) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ numcerts = sk_X509_num(sk);
+
+ result = Curl_ssl_init_certinfo(data, (int)numcerts);
+ if(result) {
+ return result;
+ }
+
+ mem = BIO_new(BIO_s_mem());
+ if(!mem) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ for(i = 0; i < (int)numcerts; i++) {
+ ASN1_INTEGER *num;
+ X509 *x = sk_X509_value(sk, i);
+ EVP_PKEY *pubkey = NULL;
+ int j;
+ char *ptr;
+ const ASN1_BIT_STRING *psig = NULL;
+
+ X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
+ push_certinfo("Subject", i);
+
+ X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
+ push_certinfo("Issuer", i);
+
+ BIO_printf(mem, "%lx", X509_get_version(x));
+ push_certinfo("Version", i);
+
+ num = X509_get_serialNumber(x);
+ if(num->type == V_ASN1_NEG_INTEGER)
+ BIO_puts(mem, "-");
+ for(j = 0; j < num->length; j++)
+ BIO_printf(mem, "%02x", num->data[j]);
+ push_certinfo("Serial Number", i);
+
+#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
+ {
+ const X509_ALGOR *sigalg = NULL;
+ X509_PUBKEY *xpubkey = NULL;
+ ASN1_OBJECT *pubkeyoid = NULL;
+
+ X509_get0_signature(&psig, &sigalg, x);
+ if(sigalg) {
+ i2a_ASN1_OBJECT(mem, sigalg->algorithm);
+ push_certinfo("Signature Algorithm", i);
+ }
+
+ xpubkey = X509_get_X509_PUBKEY(x);
+ if(xpubkey) {
+ X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey);
+ if(pubkeyoid) {
+ i2a_ASN1_OBJECT(mem, pubkeyoid);
+ push_certinfo("Public Key Algorithm", i);
+ }
+ }
+
+ X509V3_ext(data, i, X509_get0_extensions(x));
+ }
+#else
+ {
+ /* before OpenSSL 1.0.2 */
+ X509_CINF *cinf = x->cert_info;
+
+ i2a_ASN1_OBJECT(mem, cinf->signature->algorithm);
+ push_certinfo("Signature Algorithm", i);
+
+ i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm);
+ push_certinfo("Public Key Algorithm", i);
+
+ X509V3_ext(data, i, cinf->extensions);
+
+ psig = x->signature;
+ }
+#endif
+
+ ASN1_TIME_print(mem, X509_get0_notBefore(x));
+ push_certinfo("Start date", i);
+
+ ASN1_TIME_print(mem, X509_get0_notAfter(x));
+ push_certinfo("Expire date", i);
+
+ pubkey = X509_get_pubkey(x);
+ if(!pubkey)
+ infof(data, " Unable to load public key");
+ else {
+ int pktype;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+ pktype = EVP_PKEY_id(pubkey);
+#else
+ pktype = pubkey->type;
+#endif
+ switch(pktype) {
+ case EVP_PKEY_RSA:
+ {
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ RSA *rsa;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+ rsa = EVP_PKEY_get0_RSA(pubkey);
+#else
+ rsa = pubkey->pkey.rsa;
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
+
+ {
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(n);
+ DECLARE_PKEY_PARAM_BIGNUM(e);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e);
+#else
+ RSA_get0_key(rsa, &n, &e, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
+ BIO_printf(mem, "%d", BN_num_bits(n));
+#else
+ BIO_printf(mem, "%d", BN_num_bits(rsa->n));
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
+ push_certinfo("RSA Public Key", i);
+ print_pubkey_BN(rsa, n, i);
+ print_pubkey_BN(rsa, e, i);
+ FREE_PKEY_PARAM_BIGNUM(n);
+ FREE_PKEY_PARAM_BIGNUM(e);
+ }
+
+ break;
+ }
+ case EVP_PKEY_DSA:
+ {
+#ifndef OPENSSL_NO_DSA
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ DSA *dsa;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+ dsa = EVP_PKEY_get0_DSA(pubkey);
+#else
+ dsa = pubkey->pkey.dsa;
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
+ {
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(p);
+ DECLARE_PKEY_PARAM_BIGNUM(q);
+ DECLARE_PKEY_PARAM_BIGNUM(g);
+ DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
+ DSA_get0_pqg(dsa, &p, &q, &g);
+ DSA_get0_key(dsa, &pub_key, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
+ print_pubkey_BN(dsa, p, i);
+ print_pubkey_BN(dsa, q, i);
+ print_pubkey_BN(dsa, g, i);
+ print_pubkey_BN(dsa, pub_key, i);
+ FREE_PKEY_PARAM_BIGNUM(p);
+ FREE_PKEY_PARAM_BIGNUM(q);
+ FREE_PKEY_PARAM_BIGNUM(g);
+ FREE_PKEY_PARAM_BIGNUM(pub_key);
+ }
+#endif /* !OPENSSL_NO_DSA */
+ break;
+ }
+ case EVP_PKEY_DH:
+ {
+#ifndef HAVE_EVP_PKEY_GET_PARAMS
+ DH *dh;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+ dh = EVP_PKEY_get0_DH(pubkey);
+#else
+ dh = pubkey->pkey.dh;
+#endif /* HAVE_OPAQUE_EVP_PKEY */
+#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
+ {
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ DECLARE_PKEY_PARAM_BIGNUM(p);
+ DECLARE_PKEY_PARAM_BIGNUM(q);
+ DECLARE_PKEY_PARAM_BIGNUM(g);
+ DECLARE_PKEY_PARAM_BIGNUM(pub_key);
+#ifdef HAVE_EVP_PKEY_GET_PARAMS
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
+ EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
+ DH_get0_pqg(dh, &p, &q, &g);
+ DH_get0_key(dh, &pub_key, NULL);
+#endif /* HAVE_EVP_PKEY_GET_PARAMS */
+ print_pubkey_BN(dh, p, i);
+ print_pubkey_BN(dh, q, i);
+ print_pubkey_BN(dh, g, i);
+#else
+ print_pubkey_BN(dh, p, i);
+ print_pubkey_BN(dh, g, i);
+#endif /* HAVE_OPAQUE_RSA_DSA_DH */
+ print_pubkey_BN(dh, pub_key, i);
+ FREE_PKEY_PARAM_BIGNUM(p);
+ FREE_PKEY_PARAM_BIGNUM(q);
+ FREE_PKEY_PARAM_BIGNUM(g);
+ FREE_PKEY_PARAM_BIGNUM(pub_key);
+ }
+ break;
+ }
+ }
+ EVP_PKEY_free(pubkey);
+ }
+
+ if(psig) {
+ for(j = 0; j < psig->length; j++)
+ BIO_printf(mem, "%02x:", psig->data[j]);
+ push_certinfo("Signature", i);
+ }
+
+ PEM_write_bio_X509(mem, x);
+ push_certinfo("Cert", i);
+ }
+
+ BIO_free(mem);
+
+ return CURLE_OK;
+}
+
+#endif /* quiche or OpenSSL */
+
+#ifdef USE_OPENSSL
+
static bool ossl_associate_connection(struct Curl_easy *data,
struct connectdata *conn,
int sockindex);
@@ -486,36 +823,19 @@ static CURLcode ossl_seed(struct Curl_easy *data)
return CURLE_SSL_CONNECT_ERROR;
#else
-#ifndef RANDOM_FILE
- /* if RANDOM_FILE isn't defined, we only perform this if an option tells
- us to! */
- if(data->set.str[STRING_SSL_RANDOM_FILE])
-#define RANDOM_FILE "" /* doesn't matter won't be used */
+#ifdef RANDOM_FILE
+ RAND_load_file(RANDOM_FILE, RAND_LOAD_LENGTH);
+ if(rand_enough())
+ return CURLE_OK;
#endif
- {
- /* let the option override the define */
- RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
- data->set.str[STRING_SSL_RANDOM_FILE]:
- RANDOM_FILE),
- RAND_LOAD_LENGTH);
- if(rand_enough())
- return CURLE_OK;
- }
-#if defined(HAVE_RAND_EGD)
- /* only available in OpenSSL 0.9.5 and later */
+#if defined(HAVE_RAND_EGD) && defined(EGD_SOCKET)
+ /* available in OpenSSL 0.9.5 and later */
/* EGD_SOCKET is set at configure time or not at all */
-#ifndef EGD_SOCKET
- /* If we don't have the define set, we only do this if the egd-option
- is set */
- if(data->set.str[STRING_SSL_EGDSOCKET])
-#define EGD_SOCKET "" /* doesn't matter won't be used */
-#endif
{
/* If there's an option and a define, the option overrides the
define */
- int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
- data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
+ int ret = RAND_egd(EGD_SOCKET);
if(-1 != ret) {
if(rand_enough())
return CURLE_OK;
@@ -814,9 +1134,10 @@ int cert_stuff(struct Curl_easy *data,
SSL_CTX_use_certificate_chain_file(ctx, cert_file);
if(cert_use_result != 1) {
failf(data,
- "could not load PEM client certificate, " OSSL_PACKAGE
+ "could not load PEM client certificate from %s, " OSSL_PACKAGE
" error %s, "
"(no key found, wrong pass phrase, or wrong file format?)",
+ (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file),
ossl_strerror(ERR_get_error(), error_buffer,
sizeof(error_buffer)) );
return 0;
@@ -834,9 +1155,10 @@ int cert_stuff(struct Curl_easy *data,
SSL_CTX_use_certificate_file(ctx, cert_file, file_type);
if(cert_use_result != 1) {
failf(data,
- "could not load ASN1 client certificate, " OSSL_PACKAGE
+ "could not load ASN1 client certificate from %s, " OSSL_PACKAGE
" error %s, "
"(no key found, wrong pass phrase, or wrong file format?)",
+ (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file),
ossl_strerror(ERR_get_error(), error_buffer,
sizeof(error_buffer)) );
return 0;
@@ -889,8 +1211,9 @@ int cert_stuff(struct Curl_easy *data,
}
if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
- failf(data, "unable to set client certificate");
- X509_free(params.cert);
+ failf(data, "unable to set client certificate [%s]",
+ ossl_strerror(ERR_get_error(), error_buffer,
+ sizeof(error_buffer)));
return 0;
}
X509_free(params.cert); /* we don't need the handle any more... */
@@ -1013,11 +1336,7 @@ int cert_stuff(struct Curl_easy *data,
fail:
EVP_PKEY_free(pri);
X509_free(x509);
-#ifdef USE_AMISSL
- sk_X509_pop_free(ca, Curl_amiga_X509_free);
-#else
sk_X509_pop_free(ca, X509_free);
-#endif
if(!cert_done)
return 0; /* failure! */
break;
@@ -2276,14 +2595,6 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
# define HAS_ALPN 1
#endif
-/* Check for OpenSSL 1.0.1 which has NPN support. */
-#undef HAS_NPN
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L \
- && !defined(OPENSSL_NO_TLSEXT) \
- && !defined(OPENSSL_NO_NEXTPROTONEG)
-# define HAS_NPN 1
-#endif
-
/* Check for OpenSSL 1.1.0 which has set_{min,max}_proto_version(). */
#undef HAS_MODERN_SET_PROTO_VER
#if OPENSSL_VERSION_NUMBER >= 0x10100000L \
@@ -2292,64 +2603,6 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
# define HAS_MODERN_SET_PROTO_VER 1
#endif
-#ifdef HAS_NPN
-
-/*
- * in is a list of length prefixed strings. this function has to select
- * the protocol we want to use from the list and write its string into out.
- */
-
-static int
-select_next_protocol(unsigned char **out, unsigned char *outlen,
- const unsigned char *in, unsigned int inlen,
- const char *key, unsigned int keylen)
-{
- unsigned int i;
- for(i = 0; i + keylen <= inlen; i += in[i] + 1) {
- if(memcmp(&in[i + 1], key, keylen) == 0) {
- *out = (unsigned char *) &in[i + 1];
- *outlen = in[i];
- return 0;
- }
- }
- return -1;
-}
-
-static int
-select_next_proto_cb(SSL *ssl,
- unsigned char **out, unsigned char *outlen,
- const unsigned char *in, unsigned int inlen,
- void *arg)
-{
- struct Curl_easy *data = (struct Curl_easy *)arg;
- struct connectdata *conn = data->conn;
- (void)ssl;
-
-#ifdef USE_HTTP2
- if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
- !select_next_protocol(out, outlen, in, inlen, ALPN_H2, ALPN_H2_LENGTH)) {
- infof(data, "NPN, negotiated HTTP2 (%s)", ALPN_H2);
- conn->negnpn = CURL_HTTP_VERSION_2;
- return SSL_TLSEXT_ERR_OK;
- }
-#endif
-
- if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1,
- ALPN_HTTP_1_1_LENGTH)) {
- infof(data, "NPN, negotiated HTTP1.1");
- conn->negnpn = CURL_HTTP_VERSION_1_1;
- return SSL_TLSEXT_ERR_OK;
- }
-
- infof(data, "NPN, no overlap, use HTTP1.1");
- *out = (unsigned char *)ALPN_HTTP_1_1;
- *outlen = ALPN_HTTP_1_1_LENGTH;
- conn->negnpn = CURL_HTTP_VERSION_1_1;
-
- return SSL_TLSEXT_ERR_OK;
-}
-#endif /* HAS_NPN */
-
#ifdef HAS_MODERN_SET_PROTO_VER
static CURLcode
set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
@@ -2840,11 +3093,6 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
SSL_CTX_set_options(backend->ctx, ctx_options);
-#ifdef HAS_NPN
- if(conn->bits.tls_enable_npn)
- SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, data);
-#endif
-
#ifdef HAS_ALPN
if(conn->bits.tls_enable_alpn) {
int cur = 0;
@@ -2934,7 +3182,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
#ifdef USE_OPENSSL_SRP
if((ssl_authtype == CURL_TLSAUTH_SRP) &&
- Curl_allow_auth_to_host(data)) {
+ Curl_auth_allowed_to_host(data)) {
char * const ssl_username = SSL_SET_OPTION(primary.username);
char * const ssl_password = SSL_SET_OPTION(primary.password);
infof(data, "Using TLS-SRP username: %s", ssl_username);
@@ -3472,19 +3720,19 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
#ifdef USE_HTTP2
if(len == ALPN_H2_LENGTH &&
!memcmp(ALPN_H2, neg_protocol, len)) {
- conn->negnpn = CURL_HTTP_VERSION_2;
+ conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(len == ALPN_HTTP_1_1_LENGTH &&
!memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
+ conn->alpn = CURL_HTTP_VERSION_1_1;
}
}
else
infof(data, VTLS_INFOF_NO_ALPN);
- Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
}
#endif
@@ -3493,342 +3741,6 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data,
}
}
-static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
-{
- int i, ilen;
-
- ilen = (int)len;
- if(ilen < 0)
- return 1; /* buffer too big */
-
- i = i2t_ASN1_OBJECT(buf, ilen, a);
-
- if(i >= ilen)
- return 1; /* buffer too small */
-
- return 0;
-}
-
-#define push_certinfo(_label, _num) \
-do { \
- long info_len = BIO_get_mem_data(mem, &ptr); \
- Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \
- if(1 != BIO_reset(mem)) \
- break; \
-} while(0)
-
-static void pubkey_show(struct Curl_easy *data,
- BIO *mem,
- int num,
- const char *type,
- const char *name,
- const BIGNUM *bn)
-{
- char *ptr;
- char namebuf[32];
-
- msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
-
- if(bn)
- BN_print(mem, bn);
- push_certinfo(namebuf, num);
-}
-
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
-#define print_pubkey_BN(_type, _name, _num) \
- pubkey_show(data, mem, _num, #_type, #_name, _name)
-
-#else
-#define print_pubkey_BN(_type, _name, _num) \
-do { \
- if(_type->_name) { \
- pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
- } \
-} while(0)
-#endif
-
-static void X509V3_ext(struct Curl_easy *data,
- int certnum,
- CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
-{
- int i;
-
- if((int)sk_X509_EXTENSION_num(exts) <= 0)
- /* no extensions, bail out */
- return;
-
- for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) {
- ASN1_OBJECT *obj;
- X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
- BUF_MEM *biomem;
- char namebuf[128];
- BIO *bio_out = BIO_new(BIO_s_mem());
-
- if(!bio_out)
- return;
-
- obj = X509_EXTENSION_get_object(ext);
-
- asn1_object_dump(obj, namebuf, sizeof(namebuf));
-
- if(!X509V3_EXT_print(bio_out, ext, 0, 0))
- ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
-
- BIO_get_mem_ptr(bio_out, &biomem);
- Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data,
- biomem->length);
- BIO_free(bio_out);
- }
-}
-
-#ifdef OPENSSL_IS_BORINGSSL
-typedef size_t numcert_t;
-#else
-typedef int numcert_t;
-#endif
-
-static CURLcode get_cert_chain(struct Curl_easy *data,
- struct ssl_connect_data *connssl)
-{
- CURLcode result;
- STACK_OF(X509) *sk;
- int i;
- numcert_t numcerts;
- BIO *mem;
- struct ssl_backend_data *backend = connssl->backend;
-
- DEBUGASSERT(backend);
-
- sk = SSL_get_peer_cert_chain(backend->handle);
- if(!sk) {
- return CURLE_OUT_OF_MEMORY;
- }
-
- numcerts = sk_X509_num(sk);
-
- result = Curl_ssl_init_certinfo(data, (int)numcerts);
- if(result) {
- return result;
- }
-
- mem = BIO_new(BIO_s_mem());
- if(!mem) {
- return CURLE_OUT_OF_MEMORY;
- }
-
- for(i = 0; i < (int)numcerts; i++) {
- ASN1_INTEGER *num;
- X509 *x = sk_X509_value(sk, i);
- EVP_PKEY *pubkey = NULL;
- int j;
- char *ptr;
- const ASN1_BIT_STRING *psig = NULL;
-
- X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
- push_certinfo("Subject", i);
-
- X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
- push_certinfo("Issuer", i);
-
- BIO_printf(mem, "%lx", X509_get_version(x));
- push_certinfo("Version", i);
-
- num = X509_get_serialNumber(x);
- if(num->type == V_ASN1_NEG_INTEGER)
- BIO_puts(mem, "-");
- for(j = 0; j < num->length; j++)
- BIO_printf(mem, "%02x", num->data[j]);
- push_certinfo("Serial Number", i);
-
-#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
- {
- const X509_ALGOR *sigalg = NULL;
- X509_PUBKEY *xpubkey = NULL;
- ASN1_OBJECT *pubkeyoid = NULL;
-
- X509_get0_signature(&psig, &sigalg, x);
- if(sigalg) {
- i2a_ASN1_OBJECT(mem, sigalg->algorithm);
- push_certinfo("Signature Algorithm", i);
- }
-
- xpubkey = X509_get_X509_PUBKEY(x);
- if(xpubkey) {
- X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey);
- if(pubkeyoid) {
- i2a_ASN1_OBJECT(mem, pubkeyoid);
- push_certinfo("Public Key Algorithm", i);
- }
- }
-
- X509V3_ext(data, i, X509_get0_extensions(x));
- }
-#else
- {
- /* before OpenSSL 1.0.2 */
- X509_CINF *cinf = x->cert_info;
-
- i2a_ASN1_OBJECT(mem, cinf->signature->algorithm);
- push_certinfo("Signature Algorithm", i);
-
- i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm);
- push_certinfo("Public Key Algorithm", i);
-
- X509V3_ext(data, i, cinf->extensions);
-
- psig = x->signature;
- }
-#endif
-
- ASN1_TIME_print(mem, X509_get0_notBefore(x));
- push_certinfo("Start date", i);
-
- ASN1_TIME_print(mem, X509_get0_notAfter(x));
- push_certinfo("Expire date", i);
-
- pubkey = X509_get_pubkey(x);
- if(!pubkey)
- infof(data, " Unable to load public key");
- else {
- int pktype;
-#ifdef HAVE_OPAQUE_EVP_PKEY
- pktype = EVP_PKEY_id(pubkey);
-#else
- pktype = pubkey->type;
-#endif
- switch(pktype) {
- case EVP_PKEY_RSA:
- {
-#ifndef HAVE_EVP_PKEY_GET_PARAMS
- RSA *rsa;
-#ifdef HAVE_OPAQUE_EVP_PKEY
- rsa = EVP_PKEY_get0_RSA(pubkey);
-#else
- rsa = pubkey->pkey.rsa;
-#endif /* HAVE_OPAQUE_EVP_PKEY */
-#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
-
- {
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
- DECLARE_PKEY_PARAM_BIGNUM(n);
- DECLARE_PKEY_PARAM_BIGNUM(e);
-#ifdef HAVE_EVP_PKEY_GET_PARAMS
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e);
-#else
- RSA_get0_key(rsa, &n, &e, NULL);
-#endif /* HAVE_EVP_PKEY_GET_PARAMS */
- BIO_printf(mem, "%d", BN_num_bits(n));
-#else
- BIO_printf(mem, "%d", BN_num_bits(rsa->n));
-#endif /* HAVE_OPAQUE_RSA_DSA_DH */
- push_certinfo("RSA Public Key", i);
- print_pubkey_BN(rsa, n, i);
- print_pubkey_BN(rsa, e, i);
- FREE_PKEY_PARAM_BIGNUM(n);
- FREE_PKEY_PARAM_BIGNUM(e);
- }
-
- break;
- }
- case EVP_PKEY_DSA:
- {
-#ifndef OPENSSL_NO_DSA
-#ifndef HAVE_EVP_PKEY_GET_PARAMS
- DSA *dsa;
-#ifdef HAVE_OPAQUE_EVP_PKEY
- dsa = EVP_PKEY_get0_DSA(pubkey);
-#else
- dsa = pubkey->pkey.dsa;
-#endif /* HAVE_OPAQUE_EVP_PKEY */
-#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
- {
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
- DECLARE_PKEY_PARAM_BIGNUM(p);
- DECLARE_PKEY_PARAM_BIGNUM(q);
- DECLARE_PKEY_PARAM_BIGNUM(g);
- DECLARE_PKEY_PARAM_BIGNUM(pub_key);
-#ifdef HAVE_EVP_PKEY_GET_PARAMS
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
-#else
- DSA_get0_pqg(dsa, &p, &q, &g);
- DSA_get0_key(dsa, &pub_key, NULL);
-#endif /* HAVE_EVP_PKEY_GET_PARAMS */
-#endif /* HAVE_OPAQUE_RSA_DSA_DH */
- print_pubkey_BN(dsa, p, i);
- print_pubkey_BN(dsa, q, i);
- print_pubkey_BN(dsa, g, i);
- print_pubkey_BN(dsa, pub_key, i);
- FREE_PKEY_PARAM_BIGNUM(p);
- FREE_PKEY_PARAM_BIGNUM(q);
- FREE_PKEY_PARAM_BIGNUM(g);
- FREE_PKEY_PARAM_BIGNUM(pub_key);
- }
-#endif /* !OPENSSL_NO_DSA */
- break;
- }
- case EVP_PKEY_DH:
- {
-#ifndef HAVE_EVP_PKEY_GET_PARAMS
- DH *dh;
-#ifdef HAVE_OPAQUE_EVP_PKEY
- dh = EVP_PKEY_get0_DH(pubkey);
-#else
- dh = pubkey->pkey.dh;
-#endif /* HAVE_OPAQUE_EVP_PKEY */
-#endif /* !HAVE_EVP_PKEY_GET_PARAMS */
- {
-#ifdef HAVE_OPAQUE_RSA_DSA_DH
- DECLARE_PKEY_PARAM_BIGNUM(p);
- DECLARE_PKEY_PARAM_BIGNUM(q);
- DECLARE_PKEY_PARAM_BIGNUM(g);
- DECLARE_PKEY_PARAM_BIGNUM(pub_key);
-#ifdef HAVE_EVP_PKEY_GET_PARAMS
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g);
- EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
-#else
- DH_get0_pqg(dh, &p, &q, &g);
- DH_get0_key(dh, &pub_key, NULL);
-#endif /* HAVE_EVP_PKEY_GET_PARAMS */
- print_pubkey_BN(dh, p, i);
- print_pubkey_BN(dh, q, i);
- print_pubkey_BN(dh, g, i);
-#else
- print_pubkey_BN(dh, p, i);
- print_pubkey_BN(dh, g, i);
-#endif /* HAVE_OPAQUE_RSA_DSA_DH */
- print_pubkey_BN(dh, pub_key, i);
- FREE_PKEY_PARAM_BIGNUM(p);
- FREE_PKEY_PARAM_BIGNUM(q);
- FREE_PKEY_PARAM_BIGNUM(g);
- FREE_PKEY_PARAM_BIGNUM(pub_key);
- }
- break;
- }
- }
- EVP_PKEY_free(pubkey);
- }
-
- if(psig) {
- for(j = 0; j < psig->length; j++)
- BIO_printf(mem, "%02x:", psig->data[j]);
- push_certinfo("Signature", i);
- }
-
- PEM_write_bio_X509(mem, x);
- push_certinfo("Cert", i);
- }
-
- BIO_free(mem);
-
- return CURLE_OK;
-}
-
/*
* Heavily modified from:
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
@@ -3923,8 +3835,8 @@ static CURLcode servercert(struct Curl_easy *data,
}
if(data->set.ssl.certinfo)
- /* we've been asked to gather certificate info! */
- (void)get_cert_chain(data, connssl);
+ /* asked to gather certificate info */
+ (void)Curl_ossl_certchain(data, connssl->backend->handle);
backend->server_cert = SSL_get1_peer_certificate(backend->handle);
if(!backend->server_cert) {
@@ -4467,7 +4379,7 @@ static size_t ossl_version(char *buffer, size_t size)
}
count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver);
for(p = buffer; *p; ++p) {
- if(ISSPACE(*p))
+ if(ISBLANK(*p))
*p = '_';
}
return count;
@@ -4479,7 +4391,13 @@ static size_t ossl_version(char *buffer, size_t size)
(LIBRESSL_VERSION_NUMBER>>12)&0xff);
#endif
#elif defined(OPENSSL_IS_BORINGSSL)
+#ifdef CURL_BORINGSSL_VERSION
+ return msnprintf(buffer, size, "%s/%s",
+ OSSL_PACKAGE,
+ CURL_BORINGSSL_VERSION);
+#else
return msnprintf(buffer, size, OSSL_PACKAGE);
+#endif
#elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING)
return msnprintf(buffer, size, "%s/%s",
OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING));