33 #include <polarssl/net.h> 34 #include <polarssl/ssl.h> 35 #include <polarssl/certs.h> 36 #include <polarssl/x509.h> 37 #include <polarssl/version.h> 38 #include <polarssl/sha256.h> 40 #if POLARSSL_VERSION_NUMBER < 0x01030000 41 #error too old PolarSSL 44 #include <polarssl/error.h> 45 #include <polarssl/entropy.h> 46 #include <polarssl/ctr_drbg.h> 66 #define RSA_PUB_DER_MAX_BYTES (38 + 2 * POLARSSL_MPI_MAX_SIZE) 67 #define ECP_PUB_DER_MAX_BYTES (30 + 2 * POLARSSL_ECP_MAX_BYTES) 69 #define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ 70 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) 72 struct ssl_backend_data {
73 ctr_drbg_context ctr_drbg;
74 entropy_context entropy;
83 #define BACKEND connssl->backend 86 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) 87 #define THREADING_SUPPORT 90 #ifndef POLARSSL_ERROR_C 91 #define error_strerror(x,y,z) 95 #if defined(THREADING_SUPPORT) 96 static entropy_context entropy;
98 static int entropy_init_initialized = 0;
101 static void entropy_init_mutex(entropy_context *ctx)
104 Curl_polarsslthreadlock_lock_function(0);
105 if(entropy_init_initialized == 0) {
107 entropy_init_initialized = 1;
109 Curl_polarsslthreadlock_unlock_function(0);
114 static int entropy_func_mutex(
void *
data,
unsigned char *
output,
size_t len)
118 Curl_polarsslthreadlock_lock_function(1);
119 ret = entropy_func(data, output, len);
120 Curl_polarsslthreadlock_unlock_function(1);
129 #undef POLARSSL_DEBUG 131 #ifdef POLARSSL_DEBUG 132 static void polarssl_debug(
void *context,
int level,
const char *line)
141 infof(data,
"%s", line);
148 #ifdef POLARSSL_SSL_ALPN 155 static CURLcode polarssl_version_from_curl(
int *polarver,
long ssl_version)
157 switch(ssl_version) {
159 *polarver = SSL_MINOR_VERSION_1;
162 *polarver = SSL_MINOR_VERSION_2;
165 *polarver = SSL_MINOR_VERSION_3;
174 set_ssl_version_min_max(
struct connectdata *conn,
int sockindex)
180 int ssl_min_ver = SSL_MINOR_VERSION_1;
181 int ssl_max_ver = SSL_MINOR_VERSION_1;
184 switch(ssl_version) {
192 switch(ssl_version_max) {
194 ssl_version_max = ssl_version << 16;
201 result = polarssl_version_from_curl(&ssl_min_ver, ssl_version);
203 failf(data,
"unsupported min version passed via CURLOPT_SSLVERSION");
206 result = polarssl_version_from_curl(&ssl_max_ver, ssl_version_max >> 16);
208 failf(data,
"unsupported max version passed via CURLOPT_SSLVERSION");
212 ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver);
213 ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver);
234 failf(data,
"PolarSSL does not support SSLv2");
238 #ifdef THREADING_SUPPORT 239 entropy_init_mutex(&entropy);
241 if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy,
243 error_strerror(ret, errorbuf,
sizeof(errorbuf));
244 failf(data,
"Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
248 entropy_init(&BACKEND->entropy);
250 if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy,
252 error_strerror(ret, errorbuf,
sizeof(errorbuf));
253 failf(data,
"Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
259 memset(&BACKEND->cacert, 0,
sizeof(x509_crt));
262 ret = x509_crt_parse_file(&BACKEND->cacert,
266 error_strerror(ret, errorbuf,
sizeof(errorbuf));
267 failf(data,
"Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
276 ret = x509_crt_parse_path(&BACKEND->cacert, capath);
279 error_strerror(ret, errorbuf,
sizeof(errorbuf));
280 failf(data,
"Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
281 capath, -ret, errorbuf);
289 memset(&BACKEND->clicert, 0,
sizeof(x509_crt));
292 ret = x509_crt_parse_file(&BACKEND->clicert,
296 error_strerror(ret, errorbuf,
sizeof(errorbuf));
297 failf(data,
"Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
310 if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
311 ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
313 rsa_copy(&BACKEND->rsa, pk_rsa(pk));
315 rsa_free(&BACKEND->rsa);
319 error_strerror(ret, errorbuf,
sizeof(errorbuf));
320 failf(data,
"Error reading private key %s - PolarSSL: (-0x%04X) %s",
328 memset(&BACKEND->crl, 0,
sizeof(x509_crl));
331 ret = x509_crl_parse_file(&BACKEND->crl,
335 error_strerror(ret, errorbuf,
sizeof(errorbuf));
336 failf(data,
"Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
343 infof(data,
"PolarSSL: Connecting to %s:%d\n", hostname, port);
345 if(ssl_init(&BACKEND->ssl)) {
346 failf(data,
"PolarSSL: ssl_init failed");
353 ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
354 SSL_MINOR_VERSION_1);
357 ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
358 SSL_MINOR_VERSION_0);
359 ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
360 SSL_MINOR_VERSION_0);
361 infof(data,
"PolarSSL: Forced min. SSL Version to be SSLv3\n");
368 CURLcode result = set_ssl_version_min_max(conn, sockindex);
374 failf(data,
"Unrecognized parameter passed via CURLOPT_SSLVERSION");
378 ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT);
379 ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL);
381 ssl_set_rng(&BACKEND->ssl, ctr_drbg_random,
383 ssl_set_bio(&BACKEND->ssl,
384 net_recv, &conn->
sock[sockindex],
385 net_send, &conn->
sock[sockindex]);
387 ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites());
391 void *old_session = NULL;
393 Curl_ssl_sessionid_lock(conn);
394 if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
395 ret = ssl_set_session(&BACKEND->ssl, old_session);
397 Curl_ssl_sessionid_unlock(conn);
398 failf(data,
"ssl_set_session returned -0x%x", -ret);
401 infof(data,
"PolarSSL re-using session\n");
403 Curl_ssl_sessionid_unlock(conn);
406 ssl_set_ca_chain(&BACKEND->ssl,
411 ssl_set_own_cert_rsa(&BACKEND->ssl,
412 &BACKEND->clicert, &BACKEND->rsa);
414 if(ssl_set_hostname(&BACKEND->ssl, hostname)) {
418 failf(data,
"couldn't set hostname in PolarSSL");
429 protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
430 infof(data,
"ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
437 protocols[cur] = NULL;
439 ssl_set_alpn_protocols(&BACKEND->ssl, protocols);
443 #ifdef POLARSSL_DEBUG 444 ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data);
468 conn->
recv[sockindex] = polarssl_recv;
469 conn->
send[sockindex] = polarssl_send;
471 ret = ssl_handshake(&BACKEND->ssl);
477 case POLARSSL_ERR_NET_WANT_READ:
481 case POLARSSL_ERR_NET_WANT_WRITE:
486 error_strerror(ret, errorbuf,
sizeof(errorbuf));
487 failf(data,
"ssl_handshake returned - PolarSSL: (-0x%04X) %s",
492 infof(data,
"PolarSSL: Handshake complete, cipher is %s\n",
493 ssl_get_ciphersuite(&BACKEND->ssl) );
495 ret = ssl_get_verify_result(&BACKEND->ssl);
498 if(ret & BADCERT_EXPIRED)
499 failf(data,
"Cert verify failed: BADCERT_EXPIRED");
501 if(ret & BADCERT_REVOKED) {
502 failf(data,
"Cert verify failed: BADCERT_REVOKED");
506 if(ret & BADCERT_CN_MISMATCH)
507 failf(data,
"Cert verify failed: BADCERT_CN_MISMATCH");
509 if(ret & BADCERT_NOT_TRUSTED)
510 failf(data,
"Cert verify failed: BADCERT_NOT_TRUSTED");
515 if(ssl_get_peer_cert(&(BACKEND->ssl))) {
517 memset(buffer, 0,
sizeof(buffer));
519 if(x509_crt_info(buffer,
sizeof(buffer), (
char *)
"* ",
520 ssl_get_peer_cert(&(BACKEND->ssl))) != -1)
521 infof(data,
"Dumping cert info:\n%s\n", buffer);
529 unsigned char pubkey[PUB_DER_MAX_BYTES];
530 const x509_crt *peercert;
532 peercert = ssl_get_peer_cert(&BACKEND->ssl);
534 if(!peercert || !peercert->raw.p || !peercert->raw.len) {
535 failf(data,
"Failed due to missing peer certificate");
539 p =
calloc(1,
sizeof(*p));
549 if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
550 failf(data,
"Failed copying peer certificate");
556 size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
559 failf(data,
"Failed copying public key from peer certificate");
566 result = Curl_pin_peer_pubkey(data,
568 &pubkey[PUB_DER_MAX_BYTES - size], size);
581 const char *next_protocol = ssl_get_alpn_protocol(&BACKEND->ssl);
583 if(next_protocol != NULL) {
584 infof(data,
"ALPN, server accepted to use %s\n", next_protocol);
587 if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
588 NGHTTP2_PROTO_VERSION_ID_LEN)) {
598 infof(data,
"ALPN, server did not agree to a protocol\n");
603 infof(data,
"SSL connected\n");
620 ssl_session *our_ssl_sessionid;
621 void *old_ssl_sessionid = NULL;
623 our_ssl_sessionid =
malloc(
sizeof(ssl_session));
624 if(!our_ssl_sessionid)
627 memset(our_ssl_sessionid, 0,
sizeof(ssl_session));
629 ret = ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
631 failf(data,
"ssl_get_session returned -0x%x", -ret);
636 Curl_ssl_sessionid_lock(conn);
637 if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
638 Curl_ssl_delsessionid(conn, old_ssl_sessionid);
640 retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
641 Curl_ssl_sessionid_unlock(conn);
643 free(our_ssl_sessionid);
644 failf(data,
"failed to store ssl session");
663 ret = ssl_write(&BACKEND->ssl,
664 (
unsigned char *)mem, len);
667 *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ?
675 static void Curl_polarssl_close(
struct connectdata *conn,
int sockindex)
678 rsa_free(&BACKEND->rsa);
679 x509_crt_free(&BACKEND->clicert);
680 x509_crt_free(&BACKEND->cacert);
681 x509_crl_free(&BACKEND->crl);
682 ssl_free(&BACKEND->ssl);
695 memset(buf, 0, buffersize);
696 ret = ssl_read(&BACKEND->ssl, (
unsigned char *)buf, buffersize);
699 if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
702 *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ?
712 static void Curl_polarssl_session_free(
void *
ptr)
714 ssl_session_free(ptr);
721 static size_t Curl_polarssl_version(
char *buffer,
size_t size)
723 unsigned int version = version_get_number();
724 return snprintf(buffer, size,
"%s/%d.%d.%d",
725 version >= 0x01030A00?
"mbedTLS":
"PolarSSL",
726 version>>24, (version>>16)&0xff, (version>>8)&0xff);
754 failf(data,
"SSL connection timeout");
758 result = polarssl_connect_step1(conn, sockindex);
772 failf(data,
"SSL connection timeout");
786 nonblocking?0:timeout_ms);
799 failf(data,
"SSL connection timeout");
813 result = polarssl_connect_step2(conn, sockindex);
814 if(result || (nonblocking &&
823 result = polarssl_connect_step3(conn, sockindex);
830 conn->
recv[sockindex] = polarssl_recv;
831 conn->
send[sockindex] = polarssl_send;
844 int sockindex,
bool *done)
846 return polarssl_connect_common(conn, sockindex,
TRUE, done);
855 result = polarssl_connect_common(conn, sockindex,
FALSE, &done);
868 static int Curl_polarssl_init(
void)
870 return Curl_polarsslthreadlock_thread_setup();
873 static void Curl_polarssl_cleanup(
void)
875 (void)Curl_polarsslthreadlock_thread_cleanup();
878 static bool Curl_polarssl_data_pending(
const struct connectdata *conn,
882 return ssl_get_bytes_avail(&BACKEND->ssl) != 0;
885 static void Curl_polarssl_sha256sum(
const unsigned char *
input,
887 unsigned char *sha256sum,
891 sha256(input, inputlen, sha256sum, 0);
898 return &BACKEND->ssl;
901 const struct Curl_ssl Curl_ssl_polarssl = {
910 sizeof(
struct ssl_backend_data),
913 Curl_polarssl_cleanup,
914 Curl_polarssl_version,
917 Curl_polarssl_data_pending,
923 Curl_polarssl_connect,
924 Curl_polarssl_connect_nonblocking,
925 Curl_polarssl_get_internals,
928 Curl_polarssl_session_free,
934 Curl_polarssl_sha256sum
struct ssl_connect_data ssl[2]
ssize_t( Curl_recv)(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err)
#define SSL_CONN_CONFIG(var)
#define SSL_SET_OPTION(var)
ssl_connect_state connecting_state
UNITTEST_START char * ptr
static const struct Curl_handler *const protocols[]
int Curl_none_shutdown(struct connectdata *conn, int sockindex)
UNITTEST_START int result
struct proxy_info http_proxy
ssl_connection_state state
CURLcode Curl_none_random(struct Curl_easy *data, unsigned char *entropy, size_t length)
int Curl_none_check_cxn(struct connectdata *conn)
UNITTEST_START char * output
#define ALPN_HTTP_1_1_LENGTH
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
bool Curl_none_false_start(void)
bool Curl_none_cert_status_request(void)
ssize_t( Curl_send)(struct connectdata *conn, int sockindex, const void *buf, size_t len, CURLcode *err)
static unsigned short port
CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, unsigned char *md5sum, size_t md5len)
int Curl_socket_check(curl_socket_t readfd0, curl_socket_t readfd1, curl_socket_t writefd, time_t timeout_ms)
CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine)
struct curl_slist * Curl_none_engines_list(struct Curl_easy *data)
#define CURL_HTTP_VERSION_2
CURLcode Curl_none_set_engine_default(struct Curl_easy *data)
void Curl_none_close_all(struct Curl_easy *data)
#define calloc(nbelem, size)