Imported Upstream version 7.53.1
[platform/upstream/curl.git] / lib / vtls / mbedtls.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
9  * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
10  *
11  * This software is licensed as described in the file COPYING, which
12  * you should have received as part of this distribution. The terms
13  * are also available at https://curl.haxx.se/docs/copyright.html.
14  *
15  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16  * copies of the Software, and permit persons to whom the Software is
17  * furnished to do so, under the terms of the COPYING file.
18  *
19  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20  * KIND, either express or implied.
21  *
22  ***************************************************************************/
23
24 /*
25  * Source file for all mbedTLS-specific code for the TLS/SSL layer. No code
26  * but vtls.c should ever call or use these functions.
27  *
28  */
29
30 #include "curl_setup.h"
31
32 #ifdef USE_MBEDTLS
33
34 #include <mbedtls/version.h>
35 #if MBEDTLS_VERSION_NUMBER >= 0x02040000
36 #include <mbedtls/net_sockets.h>
37 #else
38 #include <mbedtls/net.h>
39 #endif
40 #include <mbedtls/ssl.h>
41 #include <mbedtls/certs.h>
42 #include <mbedtls/x509.h>
43
44 #include <mbedtls/error.h>
45 #include <mbedtls/entropy.h>
46 #include <mbedtls/ctr_drbg.h>
47 #include <mbedtls/sha256.h>
48
49 #include "urldata.h"
50 #include "sendf.h"
51 #include "inet_pton.h"
52 #include "mbedtls.h"
53 #include "vtls.h"
54 #include "parsedate.h"
55 #include "connect.h" /* for the connect timeout */
56 #include "select.h"
57 #include "polarssl_threadlock.h"
58
59 /* The last 3 #include files should be in this order */
60 #include "curl_printf.h"
61 #include "curl_memory.h"
62 #include "memdebug.h"
63
64 /* apply threading? */
65 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
66 #define THREADING_SUPPORT
67 #endif
68
69 #if defined(THREADING_SUPPORT)
70 static mbedtls_entropy_context entropy;
71
72 static int entropy_init_initialized = 0;
73
74 /* start of entropy_init_mutex() */
75 static void entropy_init_mutex(mbedtls_entropy_context *ctx)
76 {
77   /* lock 0 = entropy_init_mutex() */
78   Curl_polarsslthreadlock_lock_function(0);
79   if(entropy_init_initialized == 0) {
80     mbedtls_entropy_init(ctx);
81     entropy_init_initialized = 1;
82   }
83   Curl_polarsslthreadlock_unlock_function(0);
84 }
85 /* end of entropy_init_mutex() */
86
87 /* start of entropy_func_mutex() */
88 static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
89 {
90   int ret;
91   /* lock 1 = entropy_func_mutex() */
92   Curl_polarsslthreadlock_lock_function(1);
93   ret = mbedtls_entropy_func(data, output, len);
94   Curl_polarsslthreadlock_unlock_function(1);
95
96   return ret;
97 }
98 /* end of entropy_func_mutex() */
99
100 #endif /* THREADING_SUPPORT */
101
102 /* Define this to enable lots of debugging for mbedTLS */
103 #undef MBEDTLS_DEBUG
104
105 #ifdef MBEDTLS_DEBUG
106 static void mbed_debug(void *context, int level, const char *f_name,
107                        int line_nb, const char *line)
108 {
109   struct Curl_easy *data = NULL;
110
111   if(!context)
112     return;
113
114   data = (struct Curl_easy *)context;
115
116   infof(data, "%s", line);
117   (void) level;
118 }
119 #else
120 #endif
121
122 /* ALPN for http2? */
123 #ifdef USE_NGHTTP2
124 #  undef HAS_ALPN
125 #  ifdef MBEDTLS_SSL_ALPN
126 #    define HAS_ALPN
127 #  endif
128 #endif
129
130
131 /*
132  *  profile
133  */
134 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
135 {
136   /* Hashes from SHA-1 and above */
137   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) |
138   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_RIPEMD160) |
139   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) |
140   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
141   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) |
142   MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
143   0xFFFFFFF, /* Any PK alg    */
144   0xFFFFFFF, /* Any curve     */
145   1024,      /* RSA min key len */
146 };
147
148 /* See https://tls.mbed.org/discussions/generic/
149    howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
150 */
151 #define RSA_PUB_DER_MAX_BYTES   (38 + 2 * MBEDTLS_MPI_MAX_SIZE)
152 #define ECP_PUB_DER_MAX_BYTES   (30 + 2 * MBEDTLS_ECP_MAX_BYTES)
153
154 #define PUB_DER_MAX_BYTES   (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
155                              RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
156
157 static Curl_recv mbed_recv;
158 static Curl_send mbed_send;
159
160 static CURLcode
161 mbed_connect_step1(struct connectdata *conn,
162                    int sockindex)
163 {
164   struct Curl_easy *data = conn->data;
165   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
166   const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
167   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
168   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
169   char * const ssl_cert = SSL_SET_OPTION(cert);
170   const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
171   const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
172     conn->host.name;
173   const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
174   int ret = -1;
175   char errorbuf[128];
176   errorbuf[0]=0;
177
178   /* mbedTLS only supports SSLv3 and TLSv1 */
179   if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
180     failf(data, "mbedTLS does not support SSLv2");
181     return CURLE_SSL_CONNECT_ERROR;
182   }
183
184 #ifdef THREADING_SUPPORT
185   entropy_init_mutex(&entropy);
186   mbedtls_ctr_drbg_init(&connssl->ctr_drbg);
187
188   ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, entropy_func_mutex,
189                               &entropy, NULL, 0);
190   if(ret) {
191 #ifdef MBEDTLS_ERROR_C
192     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
193 #endif /* MBEDTLS_ERROR_C */
194     failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
195           -ret, errorbuf);
196   }
197 #else
198   mbedtls_entropy_init(&connssl->entropy);
199   mbedtls_ctr_drbg_init(&connssl->ctr_drbg);
200
201   ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func,
202                               &connssl->entropy, NULL, 0);
203   if(ret) {
204 #ifdef MBEDTLS_ERROR_C
205     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
206 #endif /* MBEDTLS_ERROR_C */
207     failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
208           -ret, errorbuf);
209   }
210 #endif /* THREADING_SUPPORT */
211
212   /* Load the trusted CA */
213   mbedtls_x509_crt_init(&connssl->cacert);
214
215   if(ssl_cafile) {
216     ret = mbedtls_x509_crt_parse_file(&connssl->cacert, ssl_cafile);
217
218     if(ret<0) {
219 #ifdef MBEDTLS_ERROR_C
220       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
221 #endif /* MBEDTLS_ERROR_C */
222       failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
223             ssl_cafile, -ret, errorbuf);
224
225       if(verifypeer)
226         return CURLE_SSL_CACERT_BADFILE;
227     }
228   }
229
230   if(ssl_capath) {
231     ret = mbedtls_x509_crt_parse_path(&connssl->cacert, ssl_capath);
232
233     if(ret<0) {
234 #ifdef MBEDTLS_ERROR_C
235       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
236 #endif /* MBEDTLS_ERROR_C */
237       failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
238             ssl_capath, -ret, errorbuf);
239
240       if(verifypeer)
241         return CURLE_SSL_CACERT_BADFILE;
242     }
243   }
244
245   /* Load the client certificate */
246   mbedtls_x509_crt_init(&connssl->clicert);
247
248   if(ssl_cert) {
249     ret = mbedtls_x509_crt_parse_file(&connssl->clicert, ssl_cert);
250
251     if(ret) {
252 #ifdef MBEDTLS_ERROR_C
253       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
254 #endif /* MBEDTLS_ERROR_C */
255       failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
256             ssl_cert, -ret, errorbuf);
257
258       return CURLE_SSL_CERTPROBLEM;
259     }
260   }
261
262   /* Load the client private key */
263   mbedtls_pk_init(&connssl->pk);
264
265   if(SSL_SET_OPTION(key)) {
266     ret = mbedtls_pk_parse_keyfile(&connssl->pk, SSL_SET_OPTION(key),
267                                    SSL_SET_OPTION(key_passwd));
268     if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA))
269       ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
270
271     if(ret) {
272 #ifdef MBEDTLS_ERROR_C
273       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
274 #endif /* MBEDTLS_ERROR_C */
275       failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
276             SSL_SET_OPTION(key), -ret, errorbuf);
277
278       return CURLE_SSL_CERTPROBLEM;
279     }
280   }
281
282   /* Load the CRL */
283   mbedtls_x509_crl_init(&connssl->crl);
284
285   if(ssl_crlfile) {
286     ret = mbedtls_x509_crl_parse_file(&connssl->crl, ssl_crlfile);
287
288     if(ret) {
289 #ifdef MBEDTLS_ERROR_C
290       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
291 #endif /* MBEDTLS_ERROR_C */
292       failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s",
293             ssl_crlfile, -ret, errorbuf);
294
295       return CURLE_SSL_CRL_BADFILE;
296     }
297   }
298
299   infof(data, "mbedTLS: Connecting to %s:%d\n", hostname, port);
300
301   mbedtls_ssl_config_init(&connssl->config);
302
303   mbedtls_ssl_init(&connssl->ssl);
304   if(mbedtls_ssl_setup(&connssl->ssl, &connssl->config)) {
305     failf(data, "mbedTLS: ssl_init failed");
306     return CURLE_SSL_CONNECT_ERROR;
307   }
308   ret = mbedtls_ssl_config_defaults(&connssl->config,
309                                     MBEDTLS_SSL_IS_CLIENT,
310                                     MBEDTLS_SSL_TRANSPORT_STREAM,
311                                     MBEDTLS_SSL_PRESET_DEFAULT);
312   if(ret) {
313     failf(data, "mbedTLS: ssl_config failed");
314     return CURLE_SSL_CONNECT_ERROR;
315   }
316
317   /* new profile with RSA min key len = 1024 ... */
318   mbedtls_ssl_conf_cert_profile(&connssl->config,
319                                 &mbedtls_x509_crt_profile_fr);
320
321   switch(SSL_CONN_CONFIG(version)) {
322   case CURL_SSLVERSION_DEFAULT:
323   case CURL_SSLVERSION_TLSv1:
324     mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
325                                  MBEDTLS_SSL_MINOR_VERSION_1);
326     infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n");
327     break;
328   case CURL_SSLVERSION_SSLv3:
329     mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
330                                  MBEDTLS_SSL_MINOR_VERSION_0);
331     mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
332                                  MBEDTLS_SSL_MINOR_VERSION_0);
333     infof(data, "mbedTLS: Set SSL version to SSLv3\n");
334     break;
335   case CURL_SSLVERSION_TLSv1_0:
336     mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
337                                  MBEDTLS_SSL_MINOR_VERSION_1);
338     mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
339                                  MBEDTLS_SSL_MINOR_VERSION_1);
340     infof(data, "mbedTLS: Set SSL version to TLS 1.0\n");
341     break;
342   case CURL_SSLVERSION_TLSv1_1:
343     mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
344                                  MBEDTLS_SSL_MINOR_VERSION_2);
345     mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
346                                  MBEDTLS_SSL_MINOR_VERSION_2);
347     infof(data, "mbedTLS: Set SSL version to TLS 1.1\n");
348     break;
349   case CURL_SSLVERSION_TLSv1_2:
350     mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
351                                  MBEDTLS_SSL_MINOR_VERSION_3);
352     mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
353                                  MBEDTLS_SSL_MINOR_VERSION_3);
354     infof(data, "mbedTLS: Set SSL version to TLS 1.2\n");
355     break;
356   case CURL_SSLVERSION_TLSv1_3:
357     failf(data, "mbedTLS: TLS 1.3 is not yet supported");
358     return CURLE_SSL_CONNECT_ERROR;
359   default:
360     failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
361     return CURLE_SSL_CONNECT_ERROR;
362   }
363
364   mbedtls_ssl_conf_authmode(&connssl->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
365
366   mbedtls_ssl_conf_rng(&connssl->config, mbedtls_ctr_drbg_random,
367                        &connssl->ctr_drbg);
368   mbedtls_ssl_set_bio(&connssl->ssl, &conn->sock[sockindex],
369                       mbedtls_net_send,
370                       mbedtls_net_recv,
371                       NULL /*  rev_timeout() */);
372
373   mbedtls_ssl_conf_ciphersuites(&connssl->config,
374                                 mbedtls_ssl_list_ciphersuites());
375
376 #if defined(MBEDTLS_SSL_SESSION_TICKETS)
377   mbedtls_ssl_conf_session_tickets(&connssl->config,
378                                    MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
379 #endif
380
381   /* Check if there's a cached ID we can/should use here! */
382   if(data->set.general_ssl.sessionid) {
383     void *old_session = NULL;
384
385     Curl_ssl_sessionid_lock(conn);
386     if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
387       ret = mbedtls_ssl_set_session(&connssl->ssl, old_session);
388       if(ret) {
389         Curl_ssl_sessionid_unlock(conn);
390         failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret);
391         return CURLE_SSL_CONNECT_ERROR;
392       }
393       infof(data, "mbedTLS re-using session\n");
394     }
395     Curl_ssl_sessionid_unlock(conn);
396   }
397
398   mbedtls_ssl_conf_ca_chain(&connssl->config,
399                             &connssl->cacert,
400                             &connssl->crl);
401
402   if(SSL_SET_OPTION(key)) {
403     mbedtls_ssl_conf_own_cert(&connssl->config,
404                               &connssl->clicert, &connssl->pk);
405   }
406   if(mbedtls_ssl_set_hostname(&connssl->ssl, hostname)) {
407     /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and*
408        the name to set in the SNI extension. So even if curl connects to a
409        host specified as an IP address, this function must be used. */
410     failf(data, "couldn't set hostname in mbedTLS");
411     return CURLE_SSL_CONNECT_ERROR;
412   }
413
414 #ifdef HAS_ALPN
415   if(conn->bits.tls_enable_alpn) {
416     const char **p = &connssl->protocols[0];
417 #ifdef USE_NGHTTP2
418     if(data->set.httpversion >= CURL_HTTP_VERSION_2)
419       *p++ = NGHTTP2_PROTO_VERSION_ID;
420 #endif
421     *p++ = ALPN_HTTP_1_1;
422     *p = NULL;
423     /* this function doesn't clone the protocols array, which is why we need
424        to keep it around */
425     if(mbedtls_ssl_conf_alpn_protocols(&connssl->config,
426                                        &connssl->protocols[0])) {
427       failf(data, "Failed setting ALPN protocols");
428       return CURLE_SSL_CONNECT_ERROR;
429     }
430     for(p = &connssl->protocols[0]; *p; ++p)
431       infof(data, "ALPN, offering %s\n", *p);
432   }
433 #endif
434
435 #ifdef MBEDTLS_DEBUG
436   /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
437   mbedtls_ssl_conf_dbg(&connssl->config, mbed_debug, data);
438   /* - 0 No debug
439    * - 1 Error
440    * - 2 State change
441    * - 3 Informational
442    * - 4 Verbose
443    */
444   mbedtls_debug_set_threshold(4);
445 #endif
446
447   connssl->connecting_state = ssl_connect_2;
448
449   return CURLE_OK;
450 }
451
452 static CURLcode
453 mbed_connect_step2(struct connectdata *conn,
454                    int sockindex)
455 {
456   int ret;
457   struct Curl_easy *data = conn->data;
458   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
459   const mbedtls_x509_crt *peercert;
460   const char * const pinnedpubkey = SSL_IS_PROXY() ?
461         data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
462         data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
463
464 #ifdef HAS_ALPN
465   const char *next_protocol;
466 #endif
467
468   char errorbuf[128];
469   errorbuf[0] = 0;
470
471   conn->recv[sockindex] = mbed_recv;
472   conn->send[sockindex] = mbed_send;
473
474   ret = mbedtls_ssl_handshake(&connssl->ssl);
475
476   if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
477     connssl->connecting_state = ssl_connect_2_reading;
478     return CURLE_OK;
479   }
480   else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
481     connssl->connecting_state = ssl_connect_2_writing;
482     return CURLE_OK;
483   }
484   else if(ret) {
485 #ifdef MBEDTLS_ERROR_C
486     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
487 #endif /* MBEDTLS_ERROR_C */
488     failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s",
489           -ret, errorbuf);
490     return CURLE_SSL_CONNECT_ERROR;
491   }
492
493   infof(data, "mbedTLS: Handshake complete, cipher is %s\n",
494         mbedtls_ssl_get_ciphersuite(&conn->ssl[sockindex].ssl)
495     );
496
497   ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl);
498
499   if(ret && SSL_CONN_CONFIG(verifypeer)) {
500     if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
501       failf(data, "Cert verify failed: BADCERT_EXPIRED");
502
503     if(ret & MBEDTLS_X509_BADCERT_REVOKED) {
504       failf(data, "Cert verify failed: BADCERT_REVOKED");
505       return CURLE_SSL_CACERT;
506     }
507
508     if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH)
509       failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
510
511     if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
512       failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
513
514     return CURLE_PEER_FAILED_VERIFICATION;
515   }
516
517   peercert = mbedtls_ssl_get_peer_cert(&connssl->ssl);
518
519   if(peercert && data->set.verbose) {
520     const size_t bufsize = 16384;
521     char *buffer = malloc(bufsize);
522
523     if(!buffer)
524       return CURLE_OUT_OF_MEMORY;
525
526     if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0)
527       infof(data, "Dumping cert info:\n%s\n", buffer);
528     else
529       infof(data, "Unable to dump certificate information.\n");
530
531     free(buffer);
532   }
533
534   if(pinnedpubkey) {
535     int size;
536     CURLcode result;
537     mbedtls_x509_crt *p;
538     unsigned char pubkey[PUB_DER_MAX_BYTES];
539
540     if(!peercert || !peercert->raw.p || !peercert->raw.len) {
541       failf(data, "Failed due to missing peer certificate");
542       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
543     }
544
545     p = calloc(1, sizeof(*p));
546
547     if(!p)
548       return CURLE_OUT_OF_MEMORY;
549
550     mbedtls_x509_crt_init(p);
551
552     /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
553        needs a non-const key, for now.
554        https://github.com/ARMmbed/mbedtls/issues/396 */
555     if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
556       failf(data, "Failed copying peer certificate");
557       mbedtls_x509_crt_free(p);
558       free(p);
559       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
560     }
561
562     size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
563
564     if(size <= 0) {
565       failf(data, "Failed copying public key from peer certificate");
566       mbedtls_x509_crt_free(p);
567       free(p);
568       return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
569     }
570
571     /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */
572     result = Curl_pin_peer_pubkey(data,
573                                   pinnedpubkey,
574                                   &pubkey[PUB_DER_MAX_BYTES - size], size);
575     if(result) {
576       mbedtls_x509_crt_free(p);
577       free(p);
578       return result;
579     }
580
581     mbedtls_x509_crt_free(p);
582     free(p);
583   }
584
585 #ifdef HAS_ALPN
586   if(conn->bits.tls_enable_alpn) {
587     next_protocol = mbedtls_ssl_get_alpn_protocol(&connssl->ssl);
588
589     if(next_protocol) {
590       infof(data, "ALPN, server accepted to use %s\n", next_protocol);
591 #ifdef USE_NGHTTP2
592       if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
593                   NGHTTP2_PROTO_VERSION_ID_LEN) &&
594          !next_protocol[NGHTTP2_PROTO_VERSION_ID_LEN]) {
595         conn->negnpn = CURL_HTTP_VERSION_2;
596       }
597       else
598 #endif
599         if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) &&
600            !next_protocol[ALPN_HTTP_1_1_LENGTH]) {
601           conn->negnpn = CURL_HTTP_VERSION_1_1;
602         }
603     }
604     else {
605       infof(data, "ALPN, server did not agree to a protocol\n");
606     }
607   }
608 #endif
609
610   connssl->connecting_state = ssl_connect_3;
611   infof(data, "SSL connected\n");
612
613   return CURLE_OK;
614 }
615
616 static CURLcode
617 mbed_connect_step3(struct connectdata *conn,
618                    int sockindex)
619 {
620   CURLcode retcode = CURLE_OK;
621   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
622   struct Curl_easy *data = conn->data;
623
624   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
625
626   if(data->set.general_ssl.sessionid) {
627     int ret;
628     mbedtls_ssl_session *our_ssl_sessionid;
629     void *old_ssl_sessionid = NULL;
630
631     our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session));
632     if(!our_ssl_sessionid)
633       return CURLE_OUT_OF_MEMORY;
634
635     mbedtls_ssl_session_init(our_ssl_sessionid);
636
637     ret = mbedtls_ssl_get_session(&connssl->ssl, our_ssl_sessionid);
638     if(ret) {
639       failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
640       return CURLE_SSL_CONNECT_ERROR;
641     }
642
643     /* If there's already a matching session in the cache, delete it */
644     Curl_ssl_sessionid_lock(conn);
645     if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
646       Curl_ssl_delsessionid(conn, old_ssl_sessionid);
647
648     retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
649     Curl_ssl_sessionid_unlock(conn);
650     if(retcode) {
651       free(our_ssl_sessionid);
652       failf(data, "failed to store ssl session");
653       return retcode;
654     }
655   }
656
657   connssl->connecting_state = ssl_connect_done;
658
659   return CURLE_OK;
660 }
661
662 static ssize_t mbed_send(struct connectdata *conn, int sockindex,
663                          const void *mem, size_t len,
664                          CURLcode *curlcode)
665 {
666   int ret = -1;
667
668   ret = mbedtls_ssl_write(&conn->ssl[sockindex].ssl,
669                           (unsigned char *)mem, len);
670
671   if(ret < 0) {
672     *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ?
673       CURLE_AGAIN : CURLE_SEND_ERROR;
674     ret = -1;
675   }
676
677   return ret;
678 }
679
680 void Curl_mbedtls_close_all(struct Curl_easy *data)
681 {
682   (void)data;
683 }
684
685 void Curl_mbedtls_close(struct connectdata *conn, int sockindex)
686 {
687   mbedtls_pk_free(&conn->ssl[sockindex].pk);
688   mbedtls_x509_crt_free(&conn->ssl[sockindex].clicert);
689   mbedtls_x509_crt_free(&conn->ssl[sockindex].cacert);
690   mbedtls_x509_crl_free(&conn->ssl[sockindex].crl);
691   mbedtls_ssl_config_free(&conn->ssl[sockindex].config);
692   mbedtls_ssl_free(&conn->ssl[sockindex].ssl);
693   mbedtls_ctr_drbg_free(&conn->ssl[sockindex].ctr_drbg);
694 #ifndef THREADING_SUPPORT
695   mbedtls_entropy_free(&conn->ssl[sockindex].entropy);
696 #endif /* THREADING_SUPPORT */
697 }
698
699 static ssize_t mbed_recv(struct connectdata *conn, int num,
700                          char *buf, size_t buffersize,
701                          CURLcode *curlcode)
702 {
703   int ret = -1;
704   ssize_t len = -1;
705
706   memset(buf, 0, buffersize);
707   ret = mbedtls_ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf,
708                          buffersize);
709
710   if(ret <= 0) {
711     if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
712       return 0;
713
714     *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_READ) ?
715       CURLE_AGAIN : CURLE_RECV_ERROR;
716     return -1;
717   }
718
719   len = ret;
720
721   return len;
722 }
723
724 void Curl_mbedtls_session_free(void *ptr)
725 {
726   mbedtls_ssl_session_free(ptr);
727   free(ptr);
728 }
729
730 size_t Curl_mbedtls_version(char *buffer, size_t size)
731 {
732   unsigned int version = mbedtls_version_get_number();
733   return snprintf(buffer, size, "mbedTLS/%d.%d.%d", version>>24,
734                   (version>>16)&0xff, (version>>8)&0xff);
735 }
736
737 CURLcode Curl_mbedtls_random(struct Curl_easy *data, unsigned char *entropy,
738                              size_t length)
739 {
740 #if defined(MBEDTLS_CTR_DRBG_C)
741   int ret = -1;
742   char errorbuf[128];
743   mbedtls_entropy_context ctr_entropy;
744   mbedtls_ctr_drbg_context ctr_drbg;
745   mbedtls_entropy_init(&ctr_entropy);
746   mbedtls_ctr_drbg_init(&ctr_drbg);
747   errorbuf[0]=0;
748
749   ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
750                               &ctr_entropy, NULL, 0);
751
752   if(ret) {
753 #ifdef MBEDTLS_ERROR_C
754     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
755 #endif /* MBEDTLS_ERROR_C */
756     failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\n",
757           -ret, errorbuf);
758   }
759   else {
760     ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length);
761
762     if(ret) {
763 #ifdef MBEDTLS_ERROR_C
764       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
765 #endif /* MBEDTLS_ERROR_C */
766       failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
767             -ret, errorbuf);
768     }
769   }
770
771   mbedtls_ctr_drbg_free(&ctr_drbg);
772   mbedtls_entropy_free(&ctr_entropy);
773
774   return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT;
775 #elif defined(MBEDTLS_HAVEGE_C)
776   mbedtls_havege_state hs;
777   mbedtls_havege_init(&hs);
778   mbedtls_havege_random(&hs, entropy, length);
779   mbedtls_havege_free(&hs);
780   return CURLE_OK;
781 #else
782   return CURLE_NOT_BUILT_IN;
783 #endif
784 }
785
786 static CURLcode
787 mbed_connect_common(struct connectdata *conn,
788                     int sockindex,
789                     bool nonblocking,
790                     bool *done)
791 {
792   CURLcode retcode;
793   struct Curl_easy *data = conn->data;
794   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
795   curl_socket_t sockfd = conn->sock[sockindex];
796   long timeout_ms;
797   int what;
798
799   /* check if the connection has already been established */
800   if(ssl_connection_complete == connssl->state) {
801     *done = TRUE;
802     return CURLE_OK;
803   }
804
805   if(ssl_connect_1==connssl->connecting_state) {
806     /* Find out how much more time we're allowed */
807     timeout_ms = Curl_timeleft(data, NULL, TRUE);
808
809     if(timeout_ms < 0) {
810       /* no need to continue if time already is up */
811       failf(data, "SSL connection timeout");
812       return CURLE_OPERATION_TIMEDOUT;
813     }
814     retcode = mbed_connect_step1(conn, sockindex);
815     if(retcode)
816       return retcode;
817   }
818
819   while(ssl_connect_2 == connssl->connecting_state ||
820         ssl_connect_2_reading == connssl->connecting_state ||
821         ssl_connect_2_writing == connssl->connecting_state) {
822
823     /* check allowed time left */
824     timeout_ms = Curl_timeleft(data, NULL, TRUE);
825
826     if(timeout_ms < 0) {
827       /* no need to continue if time already is up */
828       failf(data, "SSL connection timeout");
829       return CURLE_OPERATION_TIMEDOUT;
830     }
831
832     /* if ssl is expecting something, check if it's available. */
833     if(connssl->connecting_state == ssl_connect_2_reading
834        || connssl->connecting_state == ssl_connect_2_writing) {
835
836       curl_socket_t writefd = ssl_connect_2_writing==
837         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
838       curl_socket_t readfd = ssl_connect_2_reading==
839         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
840
841       what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
842                                nonblocking ? 0 : timeout_ms);
843       if(what < 0) {
844         /* fatal error */
845         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
846         return CURLE_SSL_CONNECT_ERROR;
847       }
848       else if(0 == what) {
849         if(nonblocking) {
850           *done = FALSE;
851           return CURLE_OK;
852         }
853         else {
854           /* timeout */
855           failf(data, "SSL connection timeout");
856           return CURLE_OPERATION_TIMEDOUT;
857         }
858       }
859       /* socket is readable or writable */
860     }
861
862     /* Run transaction, and return to the caller if it failed or if
863      * this connection is part of a multi handle and this loop would
864      * execute again. This permits the owner of a multi handle to
865      * abort a connection attempt before step2 has completed while
866      * ensuring that a client using select() or epoll() will always
867      * have a valid fdset to wait on.
868      */
869     retcode = mbed_connect_step2(conn, sockindex);
870     if(retcode || (nonblocking &&
871                    (ssl_connect_2 == connssl->connecting_state ||
872                     ssl_connect_2_reading == connssl->connecting_state ||
873                     ssl_connect_2_writing == connssl->connecting_state)))
874       return retcode;
875
876   } /* repeat step2 until all transactions are done. */
877
878   if(ssl_connect_3==connssl->connecting_state) {
879     retcode = mbed_connect_step3(conn, sockindex);
880     if(retcode)
881       return retcode;
882   }
883
884   if(ssl_connect_done==connssl->connecting_state) {
885     connssl->state = ssl_connection_complete;
886     conn->recv[sockindex] = mbed_recv;
887     conn->send[sockindex] = mbed_send;
888     *done = TRUE;
889   }
890   else
891     *done = FALSE;
892
893   /* Reset our connect state machine */
894   connssl->connecting_state = ssl_connect_1;
895
896   return CURLE_OK;
897 }
898
899 CURLcode
900 Curl_mbedtls_connect_nonblocking(struct connectdata *conn,
901                                  int sockindex,
902                                  bool *done)
903 {
904   return mbed_connect_common(conn, sockindex, TRUE, done);
905 }
906
907
908 CURLcode
909 Curl_mbedtls_connect(struct connectdata *conn,
910                      int sockindex)
911 {
912   CURLcode retcode;
913   bool done = FALSE;
914
915   retcode = mbed_connect_common(conn, sockindex, FALSE, &done);
916   if(retcode)
917     return retcode;
918
919   DEBUGASSERT(done);
920
921   return CURLE_OK;
922 }
923
924 /*
925  * return 0 error initializing SSL
926  * return 1 SSL initialized successfully
927  */
928 int Curl_mbedtls_init(void)
929 {
930   return Curl_polarsslthreadlock_thread_setup();
931 }
932
933 void Curl_mbedtls_cleanup(void)
934 {
935   (void)Curl_polarsslthreadlock_thread_cleanup();
936 }
937
938 int Curl_mbedtls_data_pending(const struct connectdata *conn, int sockindex)
939 {
940   return mbedtls_ssl_get_bytes_avail(&conn->ssl[sockindex].ssl) != 0;
941 }
942
943 #endif /* USE_MBEDTLS */