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