/* Provenance: curl/curl nss_do_connect (fixed). * repo: curl/curl * commit: 5ea3145850ebff1dc2b13d17440300a01ca38161 * parent: fd9b40bf8dfd43edcbc0d254d613d95a11061c05 * commit_url: https://github.com/curl/curl/commit/5ea3145850ebff1dc2b13d17440300a01ca38161 * cve: CVE-2021-22924 * license: curl * function: nss_do_connect * relpath: lib/vtls/nss.c * provenance: human * mechanism: other */ static CURLcode nss_do_connect(struct Curl_easy *data, struct connectdata *conn, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; CURLcode result = CURLE_SSL_CONNECT_ERROR; PRUint32 timeout; /* check timeout situation */ const timediff_t time_left = Curl_timeleft(data, NULL, TRUE); if(time_left < 0) { failf(data, "timed out before SSL handshake"); result = CURLE_OPERATION_TIMEDOUT; goto error; } /* Force the handshake now */ timeout = PR_MillisecondsToInterval((PRUint32) time_left); if(SSL_ForceHandshakeWithTimeout(backend->handle, timeout) != SECSuccess) { if(PR_GetError() == PR_WOULD_BLOCK_ERROR) /* blocking direction is updated by nss_update_connecting_state() */ return CURLE_AGAIN; else if(SSL_SET_OPTION(certverifyresult) == SSL_ERROR_BAD_CERT_DOMAIN) result = CURLE_PEER_FAILED_VERIFICATION; else if(SSL_SET_OPTION(certverifyresult) != 0) result = CURLE_PEER_FAILED_VERIFICATION; goto error; } result = display_conn_info(data, backend->handle); if(result) goto error; if(SSL_CONN_CONFIG(issuercert)) { SECStatus ret = SECFailure; char *nickname = dup_nickname(data, SSL_CONN_CONFIG(issuercert)); if(nickname) { /* we support only nicknames in case of issuercert for now */ ret = check_issuer_cert(backend->handle, nickname); free(nickname); } if(SECFailure == ret) { infof(data, "SSL certificate issuer check failed"); result = CURLE_SSL_ISSUER_ERROR; goto error; } else { infof(data, "SSL certificate issuer check ok"); } } result = cmp_peer_pubkey(connssl, SSL_PINNED_PUB_KEY()); if(result) /* status already printed */ goto error; return CURLE_OK; error: return nss_fail_connect(connssl, data, result); }