openssl: make certinfo available for QUIC

Curl_ossl_certchain() is now an exported function in lib/vtls/openssl.c that
can also be used from quiche.c and ngtcp2.c to get the cert chain for QUIC
connections as well.

The *certchain function was moved to the top of the file for this reason.

Reported-by: Eloy Degen
Fixes #9584
Closes #9597
This commit is contained in:
Daniel Stenberg 2022-09-26 16:19:50 +02:00
parent 35cb4e0997
commit 58acc69e10
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 353 additions and 339 deletions

View File

@ -1703,6 +1703,11 @@ static CURLcode ng_has_connected(struct Curl_easy *data,
}
else
infof(data, "Skipped certificate verification");
#ifdef USE_OPENSSL
if(data->set.ssl.certinfo)
/* asked to gather certificate info */
(void)Curl_ossl_certchain(data, conn->quic->ssl);
#endif
return result;
}

View File

@ -416,6 +416,10 @@ static CURLcode quiche_has_connected(struct Curl_easy *data,
qs->cfg = NULL;
qs->conn = NULL;
}
if(data->set.ssl.certinfo)
/* asked to gather certificate info */
(void)Curl_ossl_certchain(data, qs->ssl);
return CURLE_OK;
fail:
quiche_h3_config_free(qs->h3config);

View File

@ -29,7 +29,7 @@
#include "curl_setup.h"
#ifdef USE_OPENSSL
#if defined(USE_QUICHE) || defined(USE_OPENSSL)
#include <limits.h>
@ -271,6 +271,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);
@ -3392,342 +3730,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
@ -3822,8 +3824,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) {

View File

@ -31,6 +31,7 @@
* This header should only be needed to get included by vtls.c, openssl.c
* and ngtcp2.c
*/
#include <openssl/ssl.h>
#include "urldata.h"
@ -53,5 +54,7 @@ CURLcode Curl_ossl_set_client_cert(struct Curl_easy *data,
const struct curl_blob *key_blob,
const char *key_type, char *key_passwd);
CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl);
#endif /* USE_OPENSSL */
#endif /* HEADER_CURL_SSLUSE_H */