1296
1340
return CURLE_SSL_CONNECT_ERROR;
1305
/* Find out if any timeout is set. If not, use 300 seconds.
1306
Otherwise, figure out the most strict timeout of the two possible one
1307
and then how much time that has elapsed to know how much time we
1308
allow for the connect call */
1309
if(data->set.timeout || data->set.connecttimeout) {
1311
/* get the most strict timeout of the ones converted to milliseconds */
1312
if(data->set.timeout &&
1313
(data->set.timeout>data->set.connecttimeout))
1314
timeout_ms = data->set.timeout*1000;
1316
timeout_ms = data->set.connecttimeout*1000;
1343
connssl->connecting_state = ssl_connect_2;
1348
Curl_ossl_connect_step2(struct connectdata *conn,
1349
int sockindex, long *timeout_ms)
1351
struct SessionHandle *data = conn->data;
1354
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1356
curlassert(ssl_connect_2 == connssl->connecting_state
1357
|| ssl_connect_2_reading == connssl->connecting_state
1358
|| ssl_connect_2_writing == connssl->connecting_state);
1360
/* Find out if any timeout is set. If not, use 300 seconds.
1361
Otherwise, figure out the most strict timeout of the two possible one
1362
and then how much time that has elapsed to know how much time we
1363
allow for the connect call */
1364
if(data->set.timeout && data->set.connecttimeout) {
1365
/* get the most strict timeout of the ones converted to milliseconds */
1366
if(data->set.timeout<data->set.connecttimeout)
1367
*timeout_ms = data->set.timeout*1000;
1319
/* no particular time-out has been set */
1320
timeout_ms= DEFAULT_CONNECT_TIMEOUT;
1322
/* Evaluate in milliseconds how much time that has passed */
1323
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
1325
/* subtract the passed time */
1326
timeout_ms -= has_passed;
1328
if(timeout_ms < 0) {
1329
/* a precaution, no need to continue if time already is up */
1330
failf(data, "SSL connection timeout");
1331
return CURLE_OPERATION_TIMEOUTED;
1334
readfd = CURL_SOCKET_BAD;
1335
writefd = CURL_SOCKET_BAD;
1337
err = SSL_connect(connssl->handle);
1340
0 is "not successful but was shut down controlled"
1341
<0 is "handshake was not successful, because a fatal error occurred" */
1343
int detail = SSL_get_error(connssl->handle, err);
1345
if(SSL_ERROR_WANT_READ == detail)
1347
else if(SSL_ERROR_WANT_WRITE == detail)
1350
/* untreated error */
1351
unsigned long errdetail;
1352
char error_buffer[120]; /* OpenSSL documents that this must be at least
1355
const char *cert_problem = NULL;
1357
errdetail = ERR_get_error(); /* Gets the earliest error code from the
1358
thread's error queue and removes the
1365
SSL2_SET_CERTIFICATE:
1366
certificate verify failed */
1371
SSL3_GET_SERVER_CERTIFICATE:
1372
certificate verify failed */
1373
cert_problem = "SSL certificate problem, verify that the CA cert is"
1375
rc = CURLE_SSL_CACERT;
1378
rc = CURLE_SSL_CONNECT_ERROR;
1382
/* detail is already set to the SSL error above */
1384
/* If we e.g. use SSLv2 request-method and the server doesn't like us
1385
* (RST connection etc.), OpenSSL gives no explanation whatsoever and
1386
* the SO_ERROR is also lost.
1388
if (CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
1389
failf(data, "Unknown SSL protocol error in connection to %s:%d ",
1390
conn->host.name, conn->port);
1393
/* Could be a CERT problem */
1395
SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
1396
failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
1369
*timeout_ms = data->set.connecttimeout*1000;
1371
else if(data->set.timeout)
1372
*timeout_ms = data->set.timeout*1000;
1373
else if(data->set.connecttimeout)
1374
*timeout_ms = data->set.connecttimeout*1000;
1376
/* no particular time-out has been set */
1377
*timeout_ms= DEFAULT_CONNECT_TIMEOUT;
1379
/* Evaluate in milliseconds how much time that has passed */
1380
has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle);
1382
/* subtract the passed time */
1383
*timeout_ms -= has_passed;
1385
if(*timeout_ms < 0) {
1386
/* a precaution, no need to continue if time already is up */
1387
failf(data, "SSL connection timeout");
1388
return CURLE_OPERATION_TIMEOUTED;
1391
err = SSL_connect(connssl->handle);
1394
0 is "not successful but was shut down controlled"
1395
<0 is "handshake was not successful, because a fatal error occurred" */
1397
int detail = SSL_get_error(connssl->handle, err);
1399
if(SSL_ERROR_WANT_READ == detail) {
1400
connssl->connecting_state = ssl_connect_2_reading;
1403
else if(SSL_ERROR_WANT_WRITE == detail) {
1404
connssl->connecting_state = ssl_connect_2_writing;
1408
/* untreated error */
1409
unsigned long errdetail;
1410
char error_buffer[120]; /* OpenSSL documents that this must be at least
1413
const char *cert_problem = NULL;
1415
connssl->connecting_state = ssl_connect_2; /* the connection failed,
1416
we're not waiting for
1419
errdetail = ERR_get_error(); /* Gets the earliest error code from the
1420
thread's error queue and removes the
1427
SSL2_SET_CERTIFICATE:
1428
certificate verify failed */
1433
SSL3_GET_SERVER_CERTIFICATE:
1434
certificate verify failed */
1435
cert_problem = "SSL certificate problem, verify that the CA cert is"
1437
rc = CURLE_SSL_CACERT;
1440
rc = CURLE_SSL_CONNECT_ERROR;
1444
/* detail is already set to the SSL error above */
1446
/* If we e.g. use SSLv2 request-method and the server doesn't like us
1447
* (RST connection etc.), OpenSSL gives no explanation whatsoever and
1448
* the SO_ERROR is also lost.
1450
if (CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
1451
failf(data, "Unknown SSL protocol error in connection to %s:%d ",
1452
conn->host.name, conn->port);
1455
/* Could be a CERT problem */
1457
SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
1458
failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
1401
/* we have been connected fine, get out of the connect loop */
1405
what = Curl_select(readfd, writefd, (int)timeout_ms);
1407
/* reabable or writable, go loop in the outer loop */
1409
else if(0 == what) {
1411
failf(data, "SSL connection timeout");
1412
return CURLE_OPERATION_TIMEDOUT;
1415
/* anything that gets here is fatally bad */
1416
failf(data, "select on SSL socket, errno: %d", Curl_ourerrno());
1417
return CURLE_SSL_CONNECT_ERROR;
1419
} /* while()-loop for the select() */
1420
} /* while()-loop for the SSL_connect() */
1422
/* Informational message */
1423
infof (data, "SSL connection using %s\n",
1424
SSL_get_cipher(connssl->handle));
1426
if(!ssl_sessionid) {
1463
/* we have been connected fine, we're not waiting for anything else. */
1464
connssl->connecting_state = ssl_connect_3;
1466
/* Informational message */
1467
infof (data, "SSL connection using %s\n",
1468
SSL_get_cipher(connssl->handle));
1475
Curl_ossl_connect_step3(struct connectdata *conn,
1478
CURLcode retcode = CURLE_OK;
1481
ASN1_TIME *certdate;
1482
void *ssl_sessionid=NULL;
1483
struct SessionHandle *data = conn->data;
1484
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1486
curlassert(ssl_connect_3 == connssl->connecting_state);
1488
if(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
1427
1489
/* Since this is not a cached session ID, then we want to stach this one
1428
1490
in the cache! */
1429
1491
SSL_SESSION *ssl_sessionid;
1529
1591
X509_free(connssl->server_cert);
1530
1592
connssl->server_cert = NULL;
1593
connssl->connecting_state = ssl_connect_done;
1531
1594
return retcode;
1598
Curl_ossl_connect_common(struct connectdata *conn,
1604
struct SessionHandle *data = conn->data;
1605
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1606
curl_socket_t sockfd = conn->sock[sockindex];
1609
if (ssl_connect_1==connssl->connecting_state) {
1610
retcode = Curl_ossl_connect_step1(conn, sockindex);
1616
while (ssl_connect_2 == connssl->connecting_state ||
1617
ssl_connect_2_reading == connssl->connecting_state ||
1618
ssl_connect_2_writing == connssl->connecting_state) {
1620
/* if ssl is expecting something, check if it's available. */
1621
if (connssl->connecting_state == ssl_connect_2_reading
1622
|| connssl->connecting_state == ssl_connect_2_writing) {
1624
int writefd = ssl_connect_2_writing==
1625
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1626
int readfd = ssl_connect_2_reading==
1627
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
1630
int what = Curl_select(readfd, writefd, nonblocking?0:(int)timeout_ms);
1632
/* reabable or writable, go loop in the outer loop */
1634
else if(0 == what) {
1641
failf(data, "SSL connection timeout");
1642
return CURLE_OPERATION_TIMEDOUT;
1646
/* anything that gets here is fatally bad */
1647
failf(data, "select on SSL socket, errno: %d", Curl_sockerrno());
1648
return CURLE_SSL_CONNECT_ERROR;
1650
} /* while()-loop for the select() */
1653
/* get the timeout from step2 to avoid computing it twice. */
1654
retcode = Curl_ossl_connect_step2(conn, sockindex, &timeout_ms);
1658
} /* repeat step2 until all transactions are done. */
1661
if (ssl_connect_3==connssl->connecting_state) {
1662
retcode = Curl_ossl_connect_step3(conn, sockindex);
1667
if (ssl_connect_done==connssl->connecting_state) {
1674
/* Reset our connect state machine */
1675
connssl->connecting_state = ssl_connect_1;
1681
Curl_ossl_connect_nonblocking(struct connectdata *conn,
1685
return Curl_ossl_connect_common(conn, sockindex, TRUE, done);
1689
Curl_ossl_connect(struct connectdata *conn,
1695
retcode = Curl_ossl_connect_common(conn, sockindex, FALSE, &done);
1534
1704
/* return number of sent (non-SSL) bytes */
1535
1705
int Curl_ossl_send(struct connectdata *conn,