diff options
author | Jan Venekamp <1422460+jan2000@users.noreply.github.com> | 2021-12-06 18:36:01 +0100 |
---|---|---|
committer | Jay Satiro <raysatiro@yahoo.com> | 2022-02-20 02:47:50 -0500 |
commit | 8af1cef29e58544c30b32220bc98b5a8e7c35407 (patch) | |
tree | a420ffcb08ebe3ed92c5c79ee5608d429ff70ba6 /lib/vtls/bearssl.c | |
parent | b84437194c3e79831b6795128f90c957e459779f (diff) | |
download | curl-8af1cef29e58544c30b32220bc98b5a8e7c35407.tar.gz |
bearssl: fix connect error on expired cert and no verify
- When peer verification is disabled use the x509_decode engine instead
of the x509_minimal engine to parse and extract the public key from
the first cert of the chain.
Prior to this change in such a case no key was extracted and that caused
CURLE_SSL_CONNECT_ERROR. The x509_minimal engine will stop parsing if
any validity check fails but the x509_decode won't.
Ref: https://github.com/curl/curl/pull/8106
Closes https://github.com/curl/curl/pull/8475
Diffstat (limited to 'lib/vtls/bearssl.c')
-rw-r--r-- | lib/vtls/bearssl.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c index 83a0e9665..54cf9840b 100644 --- a/lib/vtls/bearssl.c +++ b/lib/vtls/bearssl.c @@ -39,8 +39,10 @@ struct x509_context { const br_x509_class *vtable; br_x509_minimal_context minimal; + br_x509_decoder_context decoder; bool verifyhost; bool verifypeer; + int cert_num; }; struct ssl_backend_data { @@ -260,6 +262,11 @@ static void x509_start_chain(const br_x509_class **ctx, { struct x509_context *x509 = (struct x509_context *)ctx; + if(!x509->verifypeer) { + x509->cert_num = 0; + return; + } + if(!x509->verifyhost) server_name = NULL; x509->minimal.vtable->start_chain(&x509->minimal.vtable, server_name); @@ -269,6 +276,13 @@ static void x509_start_cert(const br_x509_class **ctx, uint32_t length) { struct x509_context *x509 = (struct x509_context *)ctx; + if(!x509->verifypeer) { + /* Only decode the first cert in the chain to obtain the public key */ + if(x509->cert_num == 0) + br_x509_decoder_init(&x509->decoder, NULL, NULL); + return; + } + x509->minimal.vtable->start_cert(&x509->minimal.vtable, length); } @@ -277,6 +291,12 @@ static void x509_append(const br_x509_class **ctx, const unsigned char *buf, { struct x509_context *x509 = (struct x509_context *)ctx; + if(!x509->verifypeer) { + if(x509->cert_num == 0) + br_x509_decoder_push(&x509->decoder, buf, len); + return; + } + x509->minimal.vtable->append(&x509->minimal.vtable, buf, len); } @@ -284,21 +304,23 @@ static void x509_end_cert(const br_x509_class **ctx) { struct x509_context *x509 = (struct x509_context *)ctx; + if(!x509->verifypeer) { + x509->cert_num++; + return; + } + x509->minimal.vtable->end_cert(&x509->minimal.vtable); } static unsigned x509_end_chain(const br_x509_class **ctx) { struct x509_context *x509 = (struct x509_context *)ctx; - unsigned err; - err = x509->minimal.vtable->end_chain(&x509->minimal.vtable); - if(err && !x509->verifypeer) { - /* ignore any X.509 errors */ - err = BR_ERR_OK; + if(!x509->verifypeer) { + return br_x509_decoder_last_error(&x509->decoder); } - return err; + return x509->minimal.vtable->end_chain(&x509->minimal.vtable); } static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx, @@ -306,6 +328,15 @@ static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx, { struct x509_context *x509 = (struct x509_context *)ctx; + if(!x509->verifypeer) { + /* Nothing in the chain is verified, just return the public key of the + first certificate and allow its usage for both TLS_RSA_* and + TLS_ECDHE_* */ + if(usages) + *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; + return br_x509_decoder_get_pkey(&x509->decoder); + } + return x509->minimal.vtable->get_pkey(&x509->minimal.vtable, usages); } |