mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-13 01:29:02 -05:00
curl: Backport upstream fix for SecureTransport on macOS
Backport upstream curl commit `16bb32e104d` (sectransp: fix for incomplete read/writes, 2023-01-05) to fix TLS support on macOS. Fixes: #24398
This commit is contained in:
@@ -136,6 +136,15 @@
|
|||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define DEBUG_CF 0
|
||||||
|
|
||||||
|
#if DEBUG_CF
|
||||||
|
#define CF_DEBUGF(x) x
|
||||||
|
#else
|
||||||
|
#define CF_DEBUGF(x) do { } while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* From MacTypes.h (which we can't include because it isn't present in iOS: */
|
/* From MacTypes.h (which we can't include because it isn't present in iOS: */
|
||||||
#define ioErr -36
|
#define ioErr -36
|
||||||
#define paramErr -50
|
#define paramErr -50
|
||||||
@@ -838,6 +847,8 @@ static OSStatus bio_cf_in_read(SSLConnectionRef connection,
|
|||||||
|
|
||||||
DEBUGASSERT(data);
|
DEBUGASSERT(data);
|
||||||
nread = Curl_conn_cf_recv(cf->next, data, buf, *dataLength, &result);
|
nread = Curl_conn_cf_recv(cf->next, data, buf, *dataLength, &result);
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "bio_read(len=%zu) -> %zd, result=%d"),
|
||||||
|
*dataLength, nread, result));
|
||||||
if(nread < 0) {
|
if(nread < 0) {
|
||||||
switch(result) {
|
switch(result) {
|
||||||
case CURLE_OK:
|
case CURLE_OK:
|
||||||
@@ -851,6 +862,9 @@ static OSStatus bio_cf_in_read(SSLConnectionRef connection,
|
|||||||
}
|
}
|
||||||
nread = 0;
|
nread = 0;
|
||||||
}
|
}
|
||||||
|
else if((size_t)nread < *dataLength) {
|
||||||
|
rtn = errSSLWouldBlock;
|
||||||
|
}
|
||||||
*dataLength = nread;
|
*dataLength = nread;
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
@@ -865,22 +879,27 @@ static OSStatus bio_cf_out_write(SSLConnectionRef connection,
|
|||||||
struct Curl_easy *data = connssl->call_data;
|
struct Curl_easy *data = connssl->call_data;
|
||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
OSStatus ortn = noErr;
|
OSStatus rtn = noErr;
|
||||||
|
|
||||||
DEBUGASSERT(data);
|
DEBUGASSERT(data);
|
||||||
nwritten = Curl_conn_cf_send(cf->next, data, buf, *dataLength, &result);
|
nwritten = Curl_conn_cf_send(cf->next, data, buf, *dataLength, &result);
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "bio_send(len=%zu) -> %zd, result=%d"),
|
||||||
|
*dataLength, nwritten, result));
|
||||||
if(nwritten <= 0) {
|
if(nwritten <= 0) {
|
||||||
if(result == CURLE_AGAIN) {
|
if(result == CURLE_AGAIN) {
|
||||||
ortn = errSSLWouldBlock;
|
rtn = errSSLWouldBlock;
|
||||||
backend->ssl_direction = true;
|
backend->ssl_direction = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ortn = ioErr;
|
rtn = ioErr;
|
||||||
}
|
}
|
||||||
nwritten = 0;
|
nwritten = 0;
|
||||||
}
|
}
|
||||||
|
else if((size_t)nwritten < *dataLength) {
|
||||||
|
rtn = errSSLWouldBlock;
|
||||||
|
}
|
||||||
*dataLength = nwritten;
|
*dataLength = nwritten;
|
||||||
return ortn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||||
@@ -1638,6 +1657,7 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
|
|||||||
|
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "connect_step1")));
|
||||||
GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
|
GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
|
||||||
#endif /* CURL_BUILD_MAC */
|
#endif /* CURL_BUILD_MAC */
|
||||||
|
|
||||||
@@ -2231,7 +2251,8 @@ static int append_cert_to_array(struct Curl_easy *data,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode verify_cert_buf(struct Curl_easy *data,
|
static CURLcode verify_cert_buf(struct Curl_cfilter *cf,
|
||||||
|
struct Curl_easy *data,
|
||||||
const unsigned char *certbuf, size_t buflen,
|
const unsigned char *certbuf, size_t buflen,
|
||||||
SSLContextRef ctx)
|
SSLContextRef ctx)
|
||||||
{
|
{
|
||||||
@@ -2239,7 +2260,12 @@ static CURLcode verify_cert_buf(struct Curl_easy *data,
|
|||||||
long res;
|
long res;
|
||||||
unsigned char *der;
|
unsigned char *der;
|
||||||
size_t derlen, offset = 0;
|
size_t derlen, offset = 0;
|
||||||
|
OSStatus ret;
|
||||||
|
SecTrustResultType trust_eval;
|
||||||
|
CFMutableArrayRef array = NULL;
|
||||||
|
SecTrustRef trust = NULL;
|
||||||
|
CURLcode result = CURLE_PEER_FAILED_VERIFICATION;
|
||||||
|
(void)cf;
|
||||||
/*
|
/*
|
||||||
* Certbuf now contains the contents of the certificate file, which can be
|
* Certbuf now contains the contents of the certificate file, which can be
|
||||||
* - a single DER certificate,
|
* - a single DER certificate,
|
||||||
@@ -2249,11 +2275,11 @@ static CURLcode verify_cert_buf(struct Curl_easy *data,
|
|||||||
* Go through certbuf, and convert any PEM certificate in it into DER
|
* Go through certbuf, and convert any PEM certificate in it into DER
|
||||||
* format.
|
* format.
|
||||||
*/
|
*/
|
||||||
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
|
array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||||
&kCFTypeArrayCallBacks);
|
|
||||||
if(!array) {
|
if(!array) {
|
||||||
failf(data, "SSL: out of memory creating CA certificate array");
|
failf(data, "SSL: out of memory creating CA certificate array");
|
||||||
return CURLE_OUT_OF_MEMORY;
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(offset < buflen) {
|
while(offset < buflen) {
|
||||||
@@ -2265,10 +2291,10 @@ static CURLcode verify_cert_buf(struct Curl_easy *data,
|
|||||||
*/
|
*/
|
||||||
res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
|
res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
|
||||||
if(res < 0) {
|
if(res < 0) {
|
||||||
CFRelease(array);
|
|
||||||
failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle",
|
failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle",
|
||||||
n, offset);
|
n, offset);
|
||||||
return CURLE_SSL_CACERT_BADFILE;
|
result = CURLE_SSL_CACERT_BADFILE;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
offset += res;
|
offset += res;
|
||||||
|
|
||||||
@@ -2276,8 +2302,9 @@ static CURLcode verify_cert_buf(struct Curl_easy *data,
|
|||||||
/* This is not a PEM file, probably a certificate in DER format. */
|
/* This is not a PEM file, probably a certificate in DER format. */
|
||||||
rc = append_cert_to_array(data, certbuf, buflen, array);
|
rc = append_cert_to_array(data, certbuf, buflen, array);
|
||||||
if(rc != CURLE_OK) {
|
if(rc != CURLE_OK) {
|
||||||
CFRelease(array);
|
CF_DEBUGF(infof(data, CFMSG(cf, "append_cert for CA failed")));
|
||||||
return rc;
|
result = rc;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2289,63 +2316,73 @@ static CURLcode verify_cert_buf(struct Curl_easy *data,
|
|||||||
rc = append_cert_to_array(data, der, derlen, array);
|
rc = append_cert_to_array(data, der, derlen, array);
|
||||||
free(der);
|
free(der);
|
||||||
if(rc != CURLE_OK) {
|
if(rc != CURLE_OK) {
|
||||||
CFRelease(array);
|
CF_DEBUGF(infof(data, CFMSG(cf, "append_cert for CA failed")));
|
||||||
return rc;
|
result = rc;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SecTrustRef trust;
|
ret = SSLCopyPeerTrust(ctx, &trust);
|
||||||
OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
|
|
||||||
if(!trust) {
|
if(!trust) {
|
||||||
failf(data, "SSL: error getting certificate chain");
|
failf(data, "SSL: error getting certificate chain");
|
||||||
CFRelease(array);
|
goto out;
|
||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
|
||||||
}
|
}
|
||||||
else if(ret != noErr) {
|
else if(ret != noErr) {
|
||||||
CFRelease(array);
|
|
||||||
failf(data, "SSLCopyPeerTrust() returned error %d", ret);
|
failf(data, "SSLCopyPeerTrust() returned error %d", ret);
|
||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "setting %d trust anchors"), n));
|
||||||
ret = SecTrustSetAnchorCertificates(trust, array);
|
ret = SecTrustSetAnchorCertificates(trust, array);
|
||||||
if(ret != noErr) {
|
if(ret != noErr) {
|
||||||
CFRelease(array);
|
|
||||||
CFRelease(trust);
|
|
||||||
failf(data, "SecTrustSetAnchorCertificates() returned error %d", ret);
|
failf(data, "SecTrustSetAnchorCertificates() returned error %d", ret);
|
||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
goto out;
|
||||||
}
|
}
|
||||||
ret = SecTrustSetAnchorCertificatesOnly(trust, true);
|
ret = SecTrustSetAnchorCertificatesOnly(trust, true);
|
||||||
if(ret != noErr) {
|
if(ret != noErr) {
|
||||||
CFRelease(array);
|
|
||||||
CFRelease(trust);
|
|
||||||
failf(data, "SecTrustSetAnchorCertificatesOnly() returned error %d", ret);
|
failf(data, "SecTrustSetAnchorCertificatesOnly() returned error %d", ret);
|
||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
SecTrustResultType trust_eval = 0;
|
trust_eval = 0;
|
||||||
ret = SecTrustEvaluate(trust, &trust_eval);
|
ret = SecTrustEvaluate(trust, &trust_eval);
|
||||||
CFRelease(array);
|
|
||||||
CFRelease(trust);
|
|
||||||
if(ret != noErr) {
|
if(ret != noErr) {
|
||||||
failf(data, "SecTrustEvaluate() returned error %d", ret);
|
failf(data, "SecTrustEvaluate() returned error %d", ret);
|
||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(trust_eval) {
|
switch(trust_eval) {
|
||||||
case kSecTrustResultUnspecified:
|
case kSecTrustResultUnspecified:
|
||||||
|
/* what does this really mean? */
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "trust result: Unspecified")));
|
||||||
|
result = CURLE_OK;
|
||||||
|
goto out;
|
||||||
case kSecTrustResultProceed:
|
case kSecTrustResultProceed:
|
||||||
return CURLE_OK;
|
CF_DEBUGF(infof(data, CFMSG(cf, "trust result: Proceed")));
|
||||||
|
result = CURLE_OK;
|
||||||
|
goto out;
|
||||||
|
|
||||||
case kSecTrustResultRecoverableTrustFailure:
|
case kSecTrustResultRecoverableTrustFailure:
|
||||||
|
failf(data, "SSL: peer not verified: RecoverableTrustFailure");
|
||||||
|
goto out;
|
||||||
case kSecTrustResultDeny:
|
case kSecTrustResultDeny:
|
||||||
|
failf(data, "SSL: peer not verified: Deny");
|
||||||
|
goto out;
|
||||||
default:
|
default:
|
||||||
failf(data, "SSL: certificate verification failed (result: %d)",
|
failf(data, "SSL: perr not verified: result=%d", trust_eval);
|
||||||
trust_eval);
|
goto out;
|
||||||
return CURLE_PEER_FAILED_VERIFICATION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if(trust)
|
||||||
|
CFRelease(trust);
|
||||||
|
if(array)
|
||||||
|
CFRelease(array);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode verify_cert(struct Curl_easy *data, const char *cafile,
|
static CURLcode verify_cert(struct Curl_cfilter *cf,
|
||||||
|
struct Curl_easy *data, const char *cafile,
|
||||||
const struct curl_blob *ca_info_blob,
|
const struct curl_blob *ca_info_blob,
|
||||||
SSLContextRef ctx)
|
SSLContextRef ctx)
|
||||||
{
|
{
|
||||||
@@ -2354,6 +2391,7 @@ static CURLcode verify_cert(struct Curl_easy *data, const char *cafile,
|
|||||||
size_t buflen;
|
size_t buflen;
|
||||||
|
|
||||||
if(ca_info_blob) {
|
if(ca_info_blob) {
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "verify_peer, CA from config blob")));
|
||||||
certbuf = (unsigned char *)malloc(ca_info_blob->len + 1);
|
certbuf = (unsigned char *)malloc(ca_info_blob->len + 1);
|
||||||
if(!certbuf) {
|
if(!certbuf) {
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
@@ -2363,6 +2401,8 @@ static CURLcode verify_cert(struct Curl_easy *data, const char *cafile,
|
|||||||
certbuf[ca_info_blob->len]='\0';
|
certbuf[ca_info_blob->len]='\0';
|
||||||
}
|
}
|
||||||
else if(cafile) {
|
else if(cafile) {
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "verify_peer, CA from file '%s'"),
|
||||||
|
cafile));
|
||||||
if(read_cert(cafile, &certbuf, &buflen) < 0) {
|
if(read_cert(cafile, &certbuf, &buflen) < 0) {
|
||||||
failf(data, "SSL: failed to read or invalid CA certificate");
|
failf(data, "SSL: failed to read or invalid CA certificate");
|
||||||
return CURLE_SSL_CACERT_BADFILE;
|
return CURLE_SSL_CACERT_BADFILE;
|
||||||
@@ -2371,7 +2411,7 @@ static CURLcode verify_cert(struct Curl_easy *data, const char *cafile,
|
|||||||
else
|
else
|
||||||
return CURLE_SSL_CACERT_BADFILE;
|
return CURLE_SSL_CACERT_BADFILE;
|
||||||
|
|
||||||
result = verify_cert_buf(data, certbuf, buflen, ctx);
|
result = verify_cert_buf(cf, data, certbuf, buflen, ctx);
|
||||||
free(certbuf);
|
free(certbuf);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -2498,8 +2538,10 @@ static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf,
|
|||||||
|| ssl_connect_2_reading == connssl->connecting_state
|
|| ssl_connect_2_reading == connssl->connecting_state
|
||||||
|| ssl_connect_2_writing == connssl->connecting_state);
|
|| ssl_connect_2_writing == connssl->connecting_state);
|
||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "connect_step2")));
|
||||||
|
|
||||||
/* Here goes nothing: */
|
/* Here goes nothing: */
|
||||||
|
check_handshake:
|
||||||
err = SSLHandshake(backend->ssl_ctx);
|
err = SSLHandshake(backend->ssl_ctx);
|
||||||
|
|
||||||
if(err != noErr) {
|
if(err != noErr) {
|
||||||
@@ -2514,14 +2556,14 @@ static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf,
|
|||||||
case -9841:
|
case -9841:
|
||||||
if((conn_config->CAfile || conn_config->ca_info_blob) &&
|
if((conn_config->CAfile || conn_config->ca_info_blob) &&
|
||||||
conn_config->verifypeer) {
|
conn_config->verifypeer) {
|
||||||
CURLcode result = verify_cert(data, conn_config->CAfile,
|
CURLcode result = verify_cert(cf, data, conn_config->CAfile,
|
||||||
conn_config->ca_info_blob,
|
conn_config->ca_info_blob,
|
||||||
backend->ssl_ctx);
|
backend->ssl_ctx);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/* the documentation says we need to call SSLHandshake() again */
|
/* the documentation says we need to call SSLHandshake() again */
|
||||||
return sectransp_connect_step2(cf, data);
|
goto check_handshake;
|
||||||
|
|
||||||
/* Problem with encrypt / decrypt */
|
/* Problem with encrypt / decrypt */
|
||||||
case errSSLPeerDecodeError:
|
case errSSLPeerDecodeError:
|
||||||
@@ -2961,6 +3003,7 @@ static CURLcode sectransp_connect_step3(struct Curl_cfilter *cf,
|
|||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = cf->ctx;
|
struct ssl_connect_data *connssl = cf->ctx;
|
||||||
|
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "connect_step3")));
|
||||||
/* There is no step 3!
|
/* There is no step 3!
|
||||||
* Well, okay, let's collect server certificates, and if verbose mode is on,
|
* Well, okay, let's collect server certificates, and if verbose mode is on,
|
||||||
* let's print the details of the server certificates. */
|
* let's print the details of the server certificates. */
|
||||||
@@ -3069,6 +3112,7 @@ sectransp_connect_common(struct Curl_cfilter *cf, struct Curl_easy *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ssl_connect_done == connssl->connecting_state) {
|
if(ssl_connect_done == connssl->connecting_state) {
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "connected")));
|
||||||
connssl->state = ssl_connection_complete;
|
connssl->state = ssl_connection_complete;
|
||||||
*done = TRUE;
|
*done = TRUE;
|
||||||
}
|
}
|
||||||
@@ -3114,6 +3158,7 @@ static void sectransp_close(struct Curl_cfilter *cf, struct Curl_easy *data)
|
|||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
if(backend->ssl_ctx) {
|
if(backend->ssl_ctx) {
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "close")));
|
||||||
(void)SSLClose(backend->ssl_ctx);
|
(void)SSLClose(backend->ssl_ctx);
|
||||||
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
|
||||||
if(SSLCreateContext)
|
if(SSLCreateContext)
|
||||||
@@ -3157,6 +3202,7 @@ static int sectransp_shutdown(struct Curl_cfilter *cf,
|
|||||||
|
|
||||||
what = SOCKET_READABLE(cf->conn->sock[cf->sockindex], SSL_SHUTDOWN_TIMEOUT);
|
what = SOCKET_READABLE(cf->conn->sock[cf->sockindex], SSL_SHUTDOWN_TIMEOUT);
|
||||||
|
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "shutdown")));
|
||||||
while(loop--) {
|
while(loop--) {
|
||||||
if(what < 0) {
|
if(what < 0) {
|
||||||
/* anything that gets here is fatally bad */
|
/* anything that gets here is fatally bad */
|
||||||
@@ -3225,6 +3271,7 @@ static int sectransp_check_cxn(struct Curl_cfilter *cf,
|
|||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
if(backend->ssl_ctx) {
|
if(backend->ssl_ctx) {
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "check connection")));
|
||||||
err = SSLGetSessionState(backend->ssl_ctx, &state);
|
err = SSLGetSessionState(backend->ssl_ctx, &state);
|
||||||
if(err == noErr)
|
if(err == noErr)
|
||||||
return state == kSSLConnected || state == kSSLHandshake;
|
return state == kSSLConnected || state == kSSLHandshake;
|
||||||
@@ -3245,6 +3292,7 @@ static bool sectransp_data_pending(struct Curl_cfilter *cf,
|
|||||||
DEBUGASSERT(backend);
|
DEBUGASSERT(backend);
|
||||||
|
|
||||||
if(backend->ssl_ctx) { /* SSL is in use */
|
if(backend->ssl_ctx) { /* SSL is in use */
|
||||||
|
CF_DEBUGF(infof(data, CFMSG(cf, "data_pending")));
|
||||||
err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer);
|
err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer);
|
||||||
if(err == noErr)
|
if(err == noErr)
|
||||||
return buffer > 0UL;
|
return buffer > 0UL;
|
||||||
@@ -3402,7 +3450,7 @@ static ssize_t sectransp_recv(struct Curl_cfilter *cf,
|
|||||||
case -9841:
|
case -9841:
|
||||||
if((conn_config->CAfile || conn_config->ca_info_blob) &&
|
if((conn_config->CAfile || conn_config->ca_info_blob) &&
|
||||||
conn_config->verifypeer) {
|
conn_config->verifypeer) {
|
||||||
CURLcode result = verify_cert(data, conn_config->CAfile,
|
CURLcode result = verify_cert(cf, data, conn_config->CAfile,
|
||||||
conn_config->ca_info_blob,
|
conn_config->ca_info_blob,
|
||||||
backend->ssl_ctx);
|
backend->ssl_ctx);
|
||||||
if(result)
|
if(result)
|
||||||
|
|||||||
Reference in New Issue
Block a user