mirror of
https://github.com/moparisthebest/curl
synced 2024-11-17 23:15:08 -05:00
nss: remove the BACKEND define kludge
This commit is contained in:
parent
89865c149d
commit
259d62c7c0
113
lib/vtls/nss.c
113
lib/vtls/nss.c
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -87,8 +87,6 @@ struct ssl_backend_data {
|
|||||||
PK11GenericObject *obj_clicert;
|
PK11GenericObject *obj_clicert;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BACKEND connssl->backend
|
|
||||||
|
|
||||||
static PRLock *nss_initlock = NULL;
|
static PRLock *nss_initlock = NULL;
|
||||||
static PRLock *nss_crllock = NULL;
|
static PRLock *nss_crllock = NULL;
|
||||||
static PRLock *nss_findslot_lock = NULL;
|
static PRLock *nss_findslot_lock = NULL;
|
||||||
@ -462,6 +460,7 @@ static CURLcode nss_create_object(struct ssl_connect_data *connssl,
|
|||||||
|
|
||||||
const int slot_id = (cacert) ? 0 : 1;
|
const int slot_id = (cacert) ? 0 : 1;
|
||||||
char *slot_name = aprintf("PEM Token #%d", slot_id);
|
char *slot_name = aprintf("PEM Token #%d", slot_id);
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
if(!slot_name)
|
if(!slot_name)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
@ -495,14 +494,14 @@ static CURLcode nss_create_object(struct ssl_connect_data *connssl,
|
|||||||
if(!obj)
|
if(!obj)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if(insert_wrapped_ptr(&BACKEND->obj_list, obj) != CURLE_OK) {
|
if(insert_wrapped_ptr(&backend->obj_list, obj) != CURLE_OK) {
|
||||||
PK11_DestroyGenericObject(obj);
|
PK11_DestroyGenericObject(obj);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!cacert && CKO_CERTIFICATE == obj_class)
|
if(!cacert && CKO_CERTIFICATE == obj_class)
|
||||||
/* store reference to a client certificate */
|
/* store reference to a client certificate */
|
||||||
BACKEND->obj_clicert = obj;
|
backend->obj_clicert = obj;
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
@ -1084,7 +1083,8 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
|
|||||||
const char *pinnedpubkey)
|
const char *pinnedpubkey)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||||
struct Curl_easy *data = BACKEND->data;
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
|
struct Curl_easy *data = backend->data;
|
||||||
CERTCertificate *cert;
|
CERTCertificate *cert;
|
||||||
|
|
||||||
if(!pinnedpubkey)
|
if(!pinnedpubkey)
|
||||||
@ -1092,7 +1092,7 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
/* get peer certificate */
|
/* get peer certificate */
|
||||||
cert = SSL_PeerCertificate(BACKEND->handle);
|
cert = SSL_PeerCertificate(backend->handle);
|
||||||
if(cert) {
|
if(cert) {
|
||||||
/* extract public key from peer certificate */
|
/* extract public key from peer certificate */
|
||||||
SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
|
SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
|
||||||
@ -1136,11 +1136,12 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
|||||||
struct SECKEYPrivateKeyStr **pRetKey)
|
struct SECKEYPrivateKeyStr **pRetKey)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
|
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
|
||||||
struct Curl_easy *data = BACKEND->data;
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
const char *nickname = BACKEND->client_nickname;
|
struct Curl_easy *data = backend->data;
|
||||||
|
const char *nickname = backend->client_nickname;
|
||||||
static const char pem_slotname[] = "PEM Token #1";
|
static const char pem_slotname[] = "PEM Token #1";
|
||||||
|
|
||||||
if(BACKEND->obj_clicert) {
|
if(backend->obj_clicert) {
|
||||||
/* use the cert/key provided by PEM reader */
|
/* use the cert/key provided by PEM reader */
|
||||||
SECItem cert_der = { 0, NULL, 0 };
|
SECItem cert_der = { 0, NULL, 0 };
|
||||||
void *proto_win = SSL_RevealPinArg(sock);
|
void *proto_win = SSL_RevealPinArg(sock);
|
||||||
@ -1153,7 +1154,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
|
|||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(PK11_ReadRawAttribute(PK11_TypeGeneric, BACKEND->obj_clicert, CKA_VALUE,
|
if(PK11_ReadRawAttribute(PK11_TypeGeneric, backend->obj_clicert, CKA_VALUE,
|
||||||
&cert_der) != SECSuccess) {
|
&cert_der) != SECSuccess) {
|
||||||
failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
|
failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
|
||||||
PK11_FreeSlot(slot);
|
PK11_FreeSlot(slot);
|
||||||
@ -1503,11 +1504,12 @@ static void Curl_nss_cleanup(void)
|
|||||||
static int Curl_nss_check_cxn(struct connectdata *conn)
|
static int Curl_nss_check_cxn(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
int rc;
|
int rc;
|
||||||
char buf;
|
char buf;
|
||||||
|
|
||||||
rc =
|
rc =
|
||||||
PR_Recv(BACKEND->handle, (void *)&buf, 1, PR_MSG_PEEK,
|
PR_Recv(backend->handle, (void *)&buf, 1, PR_MSG_PEEK,
|
||||||
PR_SecondsToInterval(1));
|
PR_SecondsToInterval(1));
|
||||||
if(rc > 0)
|
if(rc > 0)
|
||||||
return 1; /* connection still in place */
|
return 1; /* connection still in place */
|
||||||
@ -1521,26 +1523,27 @@ static int Curl_nss_check_cxn(struct connectdata *conn)
|
|||||||
static void nss_close(struct ssl_connect_data *connssl)
|
static void nss_close(struct ssl_connect_data *connssl)
|
||||||
{
|
{
|
||||||
/* before the cleanup, check whether we are using a client certificate */
|
/* before the cleanup, check whether we are using a client certificate */
|
||||||
const bool client_cert = (BACKEND->client_nickname != NULL)
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
|| (BACKEND->obj_clicert != NULL);
|
const bool client_cert = (backend->client_nickname != NULL)
|
||||||
|
|| (backend->obj_clicert != NULL);
|
||||||
|
|
||||||
free(BACKEND->client_nickname);
|
free(backend->client_nickname);
|
||||||
BACKEND->client_nickname = NULL;
|
backend->client_nickname = NULL;
|
||||||
|
|
||||||
/* destroy all NSS objects in order to avoid failure of NSS shutdown */
|
/* destroy all NSS objects in order to avoid failure of NSS shutdown */
|
||||||
Curl_llist_destroy(&BACKEND->obj_list, NULL);
|
Curl_llist_destroy(&backend->obj_list, NULL);
|
||||||
BACKEND->obj_clicert = NULL;
|
backend->obj_clicert = NULL;
|
||||||
|
|
||||||
if(BACKEND->handle) {
|
if(backend->handle) {
|
||||||
if(client_cert)
|
if(client_cert)
|
||||||
/* A server might require different authentication based on the
|
/* A server might require different authentication based on the
|
||||||
* particular path being requested by the client. To support this
|
* particular path being requested by the client. To support this
|
||||||
* scenario, we must ensure that a connection will never reuse the
|
* scenario, we must ensure that a connection will never reuse the
|
||||||
* authentication data from a previous connection. */
|
* authentication data from a previous connection. */
|
||||||
SSL_InvalidateSession(BACKEND->handle);
|
SSL_InvalidateSession(backend->handle);
|
||||||
|
|
||||||
PR_Close(BACKEND->handle);
|
PR_Close(backend->handle);
|
||||||
BACKEND->handle = NULL;
|
backend->handle = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1551,15 +1554,16 @@ static void Curl_nss_close(struct connectdata *conn, int sockindex)
|
|||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
|
struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
|
|
||||||
if(BACKEND->handle || connssl_proxy->backend->handle) {
|
if(backend->handle || connssl_proxy->backend->handle) {
|
||||||
/* NSS closes the socket we previously handed to it, so we must mark it
|
/* NSS closes the socket we previously handed to it, so we must mark it
|
||||||
as closed to avoid double close */
|
as closed to avoid double close */
|
||||||
fake_sclose(conn->sock[sockindex]);
|
fake_sclose(conn->sock[sockindex]);
|
||||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(BACKEND->handle)
|
if(backend->handle)
|
||||||
/* nss_close(connssl) will transitively close also
|
/* nss_close(connssl) will transitively close also
|
||||||
connssl_proxy->backend->handle if both are used. Clear it to avoid
|
connssl_proxy->backend->handle if both are used. Clear it to avoid
|
||||||
a double close leading to crash. */
|
a double close leading to crash. */
|
||||||
@ -1773,6 +1777,7 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
|
|||||||
CURLcode curlerr)
|
CURLcode curlerr)
|
||||||
{
|
{
|
||||||
PRErrorCode err = 0;
|
PRErrorCode err = 0;
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
|
|
||||||
if(is_nss_error(curlerr)) {
|
if(is_nss_error(curlerr)) {
|
||||||
/* read NSPR error code */
|
/* read NSPR error code */
|
||||||
@ -1788,7 +1793,7 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* cleanup on connection failure */
|
/* cleanup on connection failure */
|
||||||
Curl_llist_destroy(&BACKEND->obj_list, NULL);
|
Curl_llist_destroy(&backend->obj_list, NULL);
|
||||||
|
|
||||||
return curlerr;
|
return curlerr;
|
||||||
}
|
}
|
||||||
@ -1799,10 +1804,11 @@ static CURLcode nss_set_blocking(struct ssl_connect_data *connssl,
|
|||||||
bool blocking)
|
bool blocking)
|
||||||
{
|
{
|
||||||
static PRSocketOptionData sock_opt;
|
static PRSocketOptionData sock_opt;
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
sock_opt.option = PR_SockOpt_Nonblocking;
|
sock_opt.option = PR_SockOpt_Nonblocking;
|
||||||
sock_opt.value.non_blocking = !blocking;
|
sock_opt.value.non_blocking = !blocking;
|
||||||
|
|
||||||
if(PR_SetSocketOption(BACKEND->handle, &sock_opt) != PR_SUCCESS)
|
if(PR_SetSocketOption(backend->handle, &sock_opt) != PR_SUCCESS)
|
||||||
return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
|
return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@ -1818,6 +1824,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
|||||||
struct Curl_easy *data = conn->data;
|
struct Curl_easy *data = conn->data;
|
||||||
curl_socket_t sockfd = conn->sock[sockindex];
|
curl_socket_t sockfd = conn->sock[sockindex];
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
bool second_layer = FALSE;
|
bool second_layer = FALSE;
|
||||||
SSLVersionRange sslver_supported;
|
SSLVersionRange sslver_supported;
|
||||||
@ -1835,10 +1842,10 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
BACKEND->data = data;
|
backend->data = data;
|
||||||
|
|
||||||
/* list of all NSS objects we need to destroy in Curl_nss_close() */
|
/* list of all NSS objects we need to destroy in Curl_nss_close() */
|
||||||
Curl_llist_init(&BACKEND->obj_list, nss_destroy_object);
|
Curl_llist_init(&backend->obj_list, nss_destroy_object);
|
||||||
|
|
||||||
PR_Lock(nss_initlock);
|
PR_Lock(nss_initlock);
|
||||||
result = nss_init(conn->data);
|
result = nss_init(conn->data);
|
||||||
@ -1960,7 +1967,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
|||||||
char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
|
char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
|
||||||
if(nickname) {
|
if(nickname) {
|
||||||
/* we are not going to use libnsspem.so to read the client cert */
|
/* we are not going to use libnsspem.so to read the client cert */
|
||||||
BACKEND->obj_clicert = NULL;
|
backend->obj_clicert = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
|
CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
|
||||||
@ -1973,10 +1980,10 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* store the nickname for SelectClientCert() called during handshake */
|
/* store the nickname for SelectClientCert() called during handshake */
|
||||||
BACKEND->client_nickname = nickname;
|
backend->client_nickname = nickname;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
BACKEND->client_nickname = NULL;
|
backend->client_nickname = NULL;
|
||||||
|
|
||||||
if(SSL_GetClientAuthDataHook(model, SelectClientCert,
|
if(SSL_GetClientAuthDataHook(model, SelectClientCert,
|
||||||
(void *)connssl) != SECSuccess) {
|
(void *)connssl) != SECSuccess) {
|
||||||
@ -2017,8 +2024,8 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* import our model socket onto the current I/O stack */
|
/* import our model socket onto the current I/O stack */
|
||||||
BACKEND->handle = SSL_ImportFD(model, nspr_io);
|
backend->handle = SSL_ImportFD(model, nspr_io);
|
||||||
if(!BACKEND->handle) {
|
if(!backend->handle) {
|
||||||
if(!second_layer)
|
if(!second_layer)
|
||||||
PR_Close(nspr_io);
|
PR_Close(nspr_io);
|
||||||
goto error;
|
goto error;
|
||||||
@ -2029,36 +2036,36 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
|||||||
|
|
||||||
/* This is the password associated with the cert that we're using */
|
/* This is the password associated with the cert that we're using */
|
||||||
if(SSL_SET_OPTION(key_passwd)) {
|
if(SSL_SET_OPTION(key_passwd)) {
|
||||||
SSL_SetPKCS11PinArg(BACKEND->handle, SSL_SET_OPTION(key_passwd));
|
SSL_SetPKCS11PinArg(backend->handle, SSL_SET_OPTION(key_passwd));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SSL_ENABLE_OCSP_STAPLING
|
#ifdef SSL_ENABLE_OCSP_STAPLING
|
||||||
if(SSL_CONN_CONFIG(verifystatus)) {
|
if(SSL_CONN_CONFIG(verifystatus)) {
|
||||||
if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
|
if(SSL_OptionSet(backend->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
|
||||||
!= SECSuccess)
|
!= SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_ENABLE_NPN
|
#ifdef SSL_ENABLE_NPN
|
||||||
if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
|
if(SSL_OptionSet(backend->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
|
||||||
? PR_TRUE : PR_FALSE) != SECSuccess)
|
? PR_TRUE : PR_FALSE) != SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SSL_ENABLE_ALPN
|
#ifdef SSL_ENABLE_ALPN
|
||||||
if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
|
if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
|
||||||
? PR_TRUE : PR_FALSE) != SECSuccess)
|
? PR_TRUE : PR_FALSE) != SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
|
#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
|
||||||
if(data->set.ssl.falsestart) {
|
if(data->set.ssl.falsestart) {
|
||||||
if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
|
if(SSL_OptionSet(backend->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
|
||||||
!= SECSuccess)
|
!= SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if(SSL_SetCanFalseStartCallback(BACKEND->handle, CanFalseStartCallback,
|
if(SSL_SetCanFalseStartCallback(backend->handle, CanFalseStartCallback,
|
||||||
conn) != SECSuccess)
|
conn) != SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -2082,24 +2089,24 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
|||||||
memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
|
memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
|
||||||
cur += ALPN_HTTP_1_1_LENGTH;
|
cur += ALPN_HTTP_1_1_LENGTH;
|
||||||
|
|
||||||
if(SSL_SetNextProtoNego(BACKEND->handle, protocols, cur) != SECSuccess)
|
if(SSL_SetNextProtoNego(backend->handle, protocols, cur) != SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Force handshake on next I/O */
|
/* Force handshake on next I/O */
|
||||||
if(SSL_ResetHandshake(BACKEND->handle, /* asServer */ PR_FALSE)
|
if(SSL_ResetHandshake(backend->handle, /* asServer */ PR_FALSE)
|
||||||
!= SECSuccess)
|
!= SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* propagate hostname to the TLS layer */
|
/* propagate hostname to the TLS layer */
|
||||||
if(SSL_SetURL(BACKEND->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
if(SSL_SetURL(backend->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||||
conn->host.name) != SECSuccess)
|
conn->host.name) != SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* prevent NSS from re-using the session for a different hostname */
|
/* prevent NSS from re-using the session for a different hostname */
|
||||||
if(SSL_SetSockPeerID(BACKEND->handle, SSL_IS_PROXY() ?
|
if(SSL_SetSockPeerID(backend->handle, SSL_IS_PROXY() ?
|
||||||
conn->http_proxy.host.name : conn->host.name)
|
conn->http_proxy.host.name : conn->host.name)
|
||||||
!= SECSuccess)
|
!= SECSuccess)
|
||||||
goto error;
|
goto error;
|
||||||
@ -2116,6 +2123,7 @@ error:
|
|||||||
static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
struct Curl_easy *data = conn->data;
|
struct Curl_easy *data = conn->data;
|
||||||
CURLcode result = CURLE_SSL_CONNECT_ERROR;
|
CURLcode result = CURLE_SSL_CONNECT_ERROR;
|
||||||
PRUint32 timeout;
|
PRUint32 timeout;
|
||||||
@ -2136,7 +2144,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
|||||||
|
|
||||||
/* Force the handshake now */
|
/* Force the handshake now */
|
||||||
timeout = PR_MillisecondsToInterval((PRUint32) time_left);
|
timeout = PR_MillisecondsToInterval((PRUint32) time_left);
|
||||||
if(SSL_ForceHandshakeWithTimeout(BACKEND->handle, timeout) != SECSuccess) {
|
if(SSL_ForceHandshakeWithTimeout(backend->handle, timeout) != SECSuccess) {
|
||||||
if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
|
if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
|
||||||
/* blocking direction is updated by nss_update_connecting_state() */
|
/* blocking direction is updated by nss_update_connecting_state() */
|
||||||
return CURLE_AGAIN;
|
return CURLE_AGAIN;
|
||||||
@ -2147,7 +2155,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = display_conn_info(conn, BACKEND->handle);
|
result = display_conn_info(conn, backend->handle);
|
||||||
if(result)
|
if(result)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -2156,7 +2164,7 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
|
|||||||
char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert));
|
char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert));
|
||||||
if(nickname) {
|
if(nickname) {
|
||||||
/* we support only nicknames in case of issuercert for now */
|
/* we support only nicknames in case of issuercert for now */
|
||||||
ret = check_issuer_cert(BACKEND->handle, nickname);
|
ret = check_issuer_cert(backend->handle, nickname);
|
||||||
free(nickname);
|
free(nickname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2260,13 +2268,14 @@ static ssize_t nss_send(struct connectdata *conn, /* connection data */
|
|||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
|
|
||||||
/* The SelectClientCert() hook uses this for infof() and failf() but the
|
/* The SelectClientCert() hook uses this for infof() and failf() but the
|
||||||
handle stored in nss_setup_connect() could have already been freed. */
|
handle stored in nss_setup_connect() could have already been freed. */
|
||||||
BACKEND->data = conn->data;
|
backend->data = conn->data;
|
||||||
|
|
||||||
rc = PR_Send(BACKEND->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
|
rc = PR_Send(backend->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
PRInt32 err = PR_GetError();
|
PRInt32 err = PR_GetError();
|
||||||
if(err == PR_WOULD_BLOCK_ERROR)
|
if(err == PR_WOULD_BLOCK_ERROR)
|
||||||
@ -2297,13 +2306,14 @@ static ssize_t nss_recv(struct connectdata *conn, /* connection data */
|
|||||||
CURLcode *curlcode)
|
CURLcode *curlcode)
|
||||||
{
|
{
|
||||||
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
|
|
||||||
/* The SelectClientCert() hook uses this for infof() and failf() but the
|
/* The SelectClientCert() hook uses this for infof() and failf() but the
|
||||||
handle stored in nss_setup_connect() could have already been freed. */
|
handle stored in nss_setup_connect() could have already been freed. */
|
||||||
BACKEND->data = conn->data;
|
backend->data = conn->data;
|
||||||
|
|
||||||
nread = PR_Recv(BACKEND->handle, buf, (int)buffersize, 0,
|
nread = PR_Recv(backend->handle, buf, (int)buffersize, 0,
|
||||||
PR_INTERVAL_NO_WAIT);
|
PR_INTERVAL_NO_WAIT);
|
||||||
if(nread < 0) {
|
if(nread < 0) {
|
||||||
/* failed SSL read */
|
/* failed SSL read */
|
||||||
@ -2407,8 +2417,9 @@ static bool Curl_nss_false_start(void)
|
|||||||
static void *Curl_nss_get_internals(struct ssl_connect_data *connssl,
|
static void *Curl_nss_get_internals(struct ssl_connect_data *connssl,
|
||||||
CURLINFO info UNUSED_PARAM)
|
CURLINFO info UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
|
struct ssl_backend_data *backend = connssl->backend;
|
||||||
(void)info;
|
(void)info;
|
||||||
return BACKEND->handle;
|
return backend->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct Curl_ssl Curl_ssl_nss = {
|
const struct Curl_ssl Curl_ssl_nss = {
|
||||||
|
Loading…
Reference in New Issue
Block a user