Revert "Update to 7.40.1"
[platform/upstream/curl.git] / lib / vtls / polarssl.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 - 2014, 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 http://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 PolarSSL-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_POLARSSL
33
34 #include <polarssl/net.h>
35 #include <polarssl/ssl.h>
36 #include <polarssl/certs.h>
37 #include <polarssl/x509.h>
38 #include <polarssl/version.h>
39
40 #if POLARSSL_VERSION_NUMBER < 0x01030000
41 #error too old PolarSSL
42 #endif
43
44 #include <polarssl/error.h>
45 #include <polarssl/entropy.h>
46 #include <polarssl/ctr_drbg.h>
47
48 #include "urldata.h"
49 #include "sendf.h"
50 #include "inet_pton.h"
51 #include "polarssl.h"
52 #include "vtls.h"
53 #include "parsedate.h"
54 #include "connect.h" /* for the connect timeout */
55 #include "select.h"
56 #include "rawstr.h"
57 #include "polarssl_threadlock.h"
58
59 #define _MPRINTF_REPLACE /* use our functions only */
60 #include <curl/mprintf.h>
61 #include "curl_memory.h"
62 /* The last #include file should be: */
63 #include "memdebug.h"
64
65 /* apply threading? */
66 #if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
67 #define THREADING_SUPPORT
68 #endif
69
70 #if defined(THREADING_SUPPORT)
71 static entropy_context entropy;
72
73 static int  entropy_init_initialized  = 0;
74
75 /* start of entropy_init_mutex() */
76 static void entropy_init_mutex(entropy_context *ctx)
77 {
78   /* lock 0 = entropy_init_mutex() */
79   polarsslthreadlock_lock_function(0);
80   if(entropy_init_initialized == 0) {
81     entropy_init(ctx);
82     entropy_init_initialized = 1;
83   }
84   polarsslthreadlock_unlock_function(0);
85 }
86 /* end of entropy_init_mutex() */
87
88 /* start of entropy_func_mutex() */
89 static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
90 {
91     int ret;
92     /* lock 1 = entropy_func_mutex() */
93     polarsslthreadlock_lock_function(1);
94     ret = entropy_func(data, output, len);
95     polarsslthreadlock_unlock_function(1);
96
97     return ret;
98 }
99 /* end of entropy_func_mutex() */
100
101 #endif /* THREADING_SUPPORT */
102
103 /* Define this to enable lots of debugging for PolarSSL */
104 #undef POLARSSL_DEBUG
105
106 #ifdef POLARSSL_DEBUG
107 static void polarssl_debug(void *context, int level, const char *line)
108 {
109   struct SessionHandle *data = NULL;
110
111   if(!context)
112     return;
113
114   data = (struct SessionHandle *)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 POLARSSL_SSL_ALPN
126 #    define HAS_ALPN
127 #  endif
128 #endif
129
130 static Curl_recv polarssl_recv;
131 static Curl_send polarssl_send;
132
133
134 static CURLcode
135 polarssl_connect_step1(struct connectdata *conn,
136                      int sockindex)
137 {
138   struct SessionHandle *data = conn->data;
139   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
140
141   bool sni = TRUE; /* default is SNI enabled */
142   int ret = -1;
143 #ifdef ENABLE_IPV6
144   struct in6_addr addr;
145 #else
146   struct in_addr addr;
147 #endif
148   void *old_session = NULL;
149   size_t old_session_size = 0;
150   char errorbuf[128];
151   memset(errorbuf, 0, sizeof(errorbuf));
152
153   /* PolarSSL only supports SSLv3 and TLSv1 */
154   if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
155     failf(data, "PolarSSL does not support SSLv2");
156     return CURLE_SSL_CONNECT_ERROR;
157   }
158   else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
159     sni = FALSE; /* SSLv3 has no SNI */
160
161 #ifdef THREADING_SUPPORT
162   entropy_init_mutex(&entropy);
163
164   if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy,
165                                connssl->ssn.id, connssl->ssn.length)) != 0) {
166 #ifdef POLARSSL_ERROR_C
167      error_strerror(ret, errorbuf, sizeof(errorbuf));
168 #endif /* POLARSSL_ERROR_C */
169      failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
170                                                             -ret, errorbuf);
171   }
172 #else
173   entropy_init(&connssl->entropy);
174
175   if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy,
176                                 connssl->ssn.id, connssl->ssn.length)) != 0) {
177 #ifdef POLARSSL_ERROR_C
178      error_strerror(ret, errorbuf, sizeof(errorbuf));
179 #endif /* POLARSSL_ERROR_C */
180      failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
181                                                             -ret, errorbuf);
182   }
183 #endif /* THREADING_SUPPORT */
184
185   /* Load the trusted CA */
186   memset(&connssl->cacert, 0, sizeof(x509_crt));
187
188   if(data->set.str[STRING_SSL_CAFILE]) {
189     ret = x509_crt_parse_file(&connssl->cacert,
190                               data->set.str[STRING_SSL_CAFILE]);
191
192     if(ret<0) {
193 #ifdef POLARSSL_ERROR_C
194       error_strerror(ret, errorbuf, sizeof(errorbuf));
195 #endif /* POLARSSL_ERROR_C */
196       failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
197             data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
198
199       if(data->set.ssl.verifypeer)
200         return CURLE_SSL_CACERT_BADFILE;
201     }
202   }
203
204   /* Load the client certificate */
205   memset(&connssl->clicert, 0, sizeof(x509_crt));
206
207   if(data->set.str[STRING_CERT]) {
208     ret = x509_crt_parse_file(&connssl->clicert,
209                               data->set.str[STRING_CERT]);
210
211     if(ret) {
212 #ifdef POLARSSL_ERROR_C
213       error_strerror(ret, errorbuf, sizeof(errorbuf));
214 #endif /* POLARSSL_ERROR_C */
215       failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
216             data->set.str[STRING_CERT], -ret, errorbuf);
217
218       return CURLE_SSL_CERTPROBLEM;
219     }
220   }
221
222   /* Load the client private key */
223   if(data->set.str[STRING_KEY]) {
224     pk_context pk;
225     pk_init(&pk);
226     ret = pk_parse_keyfile(&pk, data->set.str[STRING_KEY],
227                            data->set.str[STRING_KEY_PASSWD]);
228     if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
229       ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
230     if(ret == 0)
231       rsa_copy(&connssl->rsa, pk_rsa(pk));
232     else
233       rsa_free(&connssl->rsa);
234     pk_free(&pk);
235
236     if(ret) {
237 #ifdef POLARSSL_ERROR_C
238       error_strerror(ret, errorbuf, sizeof(errorbuf));
239 #endif /* POLARSSL_ERROR_C */
240       failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
241             data->set.str[STRING_KEY], -ret, errorbuf);
242
243       return CURLE_SSL_CERTPROBLEM;
244     }
245   }
246
247   /* Load the CRL */
248   memset(&connssl->crl, 0, sizeof(x509_crl));
249
250   if(data->set.str[STRING_SSL_CRLFILE]) {
251     ret = x509_crl_parse_file(&connssl->crl,
252                               data->set.str[STRING_SSL_CRLFILE]);
253
254     if(ret) {
255 #ifdef POLARSSL_ERROR_C
256       error_strerror(ret, errorbuf, sizeof(errorbuf));
257 #endif /* POLARSSL_ERROR_C */
258       failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
259             data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
260
261       return CURLE_SSL_CRL_BADFILE;
262     }
263   }
264
265   infof(data, "PolarSSL: Connecting to %s:%d\n",
266         conn->host.name, conn->remote_port);
267
268   if(ssl_init(&connssl->ssl)) {
269     failf(data, "PolarSSL: ssl_init failed");
270     return CURLE_SSL_CONNECT_ERROR;
271   }
272
273   ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT);
274   ssl_set_authmode(&connssl->ssl, SSL_VERIFY_OPTIONAL);
275
276   ssl_set_rng(&connssl->ssl, ctr_drbg_random,
277               &connssl->ctr_drbg);
278   ssl_set_bio(&connssl->ssl,
279               net_recv, &conn->sock[sockindex],
280               net_send, &conn->sock[sockindex]);
281
282   ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
283   if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) {
284     memcpy(&connssl->ssn, old_session, old_session_size);
285     infof(data, "PolarSSL re-using session\n");
286   }
287
288   ssl_set_session(&connssl->ssl,
289                   &connssl->ssn);
290
291   ssl_set_ca_chain(&connssl->ssl,
292                    &connssl->cacert,
293                    &connssl->crl,
294                    conn->host.name);
295
296   ssl_set_own_cert_rsa(&connssl->ssl,
297                        &connssl->clicert, &connssl->rsa);
298
299   if(!Curl_inet_pton(AF_INET, conn->host.name, &addr) &&
300 #ifdef ENABLE_IPV6
301      !Curl_inet_pton(AF_INET6, conn->host.name, &addr) &&
302 #endif
303      sni && ssl_set_hostname(&connssl->ssl, conn->host.name)) {
304      infof(data, "WARNING: failed to configure "
305                  "server name indication (SNI) TLS extension\n");
306   }
307
308 #ifdef HAS_ALPN
309   if(data->set.httpversion == CURL_HTTP_VERSION_2_0) {
310     if(data->set.ssl_enable_alpn) {
311       static const char* protocols[] = {
312         NGHTTP2_PROTO_VERSION_ID, ALPN_HTTP_1_1, NULL
313       };
314       ssl_set_alpn_protocols(&connssl->ssl, protocols);
315       infof(data, "ALPN, offering %s, %s\n", protocols[0],
316             protocols[1]);
317     }
318   }
319 #endif
320
321 #ifdef POLARSSL_DEBUG
322   ssl_set_dbg(&connssl->ssl, polarssl_debug, data);
323 #endif
324
325   connssl->connecting_state = ssl_connect_2;
326
327   return CURLE_OK;
328 }
329
330 static CURLcode
331 polarssl_connect_step2(struct connectdata *conn,
332                      int sockindex)
333 {
334   int ret;
335   struct SessionHandle *data = conn->data;
336   struct ssl_connect_data* connssl = &conn->ssl[sockindex];
337   char buffer[1024];
338
339 #ifdef HAS_ALPN
340   const char* next_protocol;
341 #endif
342
343   char errorbuf[128];
344   memset(errorbuf, 0, sizeof(errorbuf));
345
346   conn->recv[sockindex] = polarssl_recv;
347   conn->send[sockindex] = polarssl_send;
348
349   for(;;) {
350     if(!(ret = ssl_handshake(&connssl->ssl)))
351       break;
352     else if(ret != POLARSSL_ERR_NET_WANT_READ &&
353             ret != POLARSSL_ERR_NET_WANT_WRITE) {
354 #ifdef POLARSSL_ERROR_C
355      error_strerror(ret, errorbuf, sizeof(errorbuf));
356 #endif /* POLARSSL_ERROR_C */
357      failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
358                                                     -ret, errorbuf);
359
360      return CURLE_SSL_CONNECT_ERROR;
361     }
362     else {
363       if(ret == POLARSSL_ERR_NET_WANT_READ) {
364         connssl->connecting_state = ssl_connect_2_reading;
365         return CURLE_OK;
366       }
367       if(ret == POLARSSL_ERR_NET_WANT_WRITE) {
368         connssl->connecting_state = ssl_connect_2_writing;
369         return CURLE_OK;
370       }
371       failf(data, "SSL_connect failed with error %d.", ret);
372       return CURLE_SSL_CONNECT_ERROR;
373
374     }
375   }
376
377   infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
378         ssl_get_ciphersuite(&conn->ssl[sockindex].ssl)
379     );
380
381   ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl);
382
383   if(ret && data->set.ssl.verifypeer) {
384     if(ret & BADCERT_EXPIRED)
385       failf(data, "Cert verify failed: BADCERT_EXPIRED");
386
387     if(ret & BADCERT_REVOKED) {
388       failf(data, "Cert verify failed: BADCERT_REVOKED");
389       return CURLE_SSL_CACERT;
390     }
391
392     if(ret & BADCERT_CN_MISMATCH)
393       failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
394
395     if(ret & BADCERT_NOT_TRUSTED)
396       failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
397
398     return CURLE_PEER_FAILED_VERIFICATION;
399   }
400
401   if(ssl_get_peer_cert(&(connssl->ssl))) {
402     /* If the session was resumed, there will be no peer certs */
403     memset(buffer, 0, sizeof(buffer));
404
405     if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
406                      ssl_get_peer_cert(&(connssl->ssl))) != -1)
407       infof(data, "Dumping cert info:\n%s\n", buffer);
408   }
409
410 #ifdef HAS_ALPN
411   if(data->set.ssl_enable_alpn) {
412     next_protocol = ssl_get_alpn_protocol(&connssl->ssl);
413
414     if(next_protocol != NULL) {
415       infof(data, "ALPN, server accepted to use %s\n", next_protocol);
416
417       if(strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
418                   NGHTTP2_PROTO_VERSION_ID_LEN)) {
419         conn->negnpn = NPN_HTTP2;
420       }
421       else if(strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
422         conn->negnpn = NPN_HTTP1_1;
423       }
424     }
425     else {
426       infof(data, "ALPN, server did not agree to a protocol\n");
427     }
428   }
429 #endif
430
431   connssl->connecting_state = ssl_connect_3;
432   infof(data, "SSL connected\n");
433
434   return CURLE_OK;
435 }
436
437 static CURLcode
438 polarssl_connect_step3(struct connectdata *conn,
439                      int sockindex)
440 {
441   CURLcode retcode = CURLE_OK;
442   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
443   struct SessionHandle *data = conn->data;
444   void *old_ssl_sessionid = NULL;
445   ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn ;
446   int incache;
447
448   DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
449
450   /* Save the current session data for possible re-use */
451   incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
452   if(incache) {
453     if(old_ssl_sessionid != our_ssl_sessionid) {
454       infof(data, "old SSL session ID is stale, removing\n");
455       Curl_ssl_delsessionid(conn, old_ssl_sessionid);
456       incache = FALSE;
457     }
458   }
459   if(!incache) {
460     void *new_session = malloc(sizeof(ssl_session));
461
462     if(new_session) {
463       memcpy(new_session, our_ssl_sessionid,
464              sizeof(ssl_session));
465
466       retcode = Curl_ssl_addsessionid(conn, new_session,
467                                    sizeof(ssl_session));
468     }
469     else {
470       retcode = CURLE_OUT_OF_MEMORY;
471     }
472
473     if(retcode) {
474       failf(data, "failed to store ssl session");
475       return retcode;
476     }
477   }
478
479   connssl->connecting_state = ssl_connect_done;
480
481   return CURLE_OK;
482 }
483
484 static ssize_t polarssl_send(struct connectdata *conn,
485                              int sockindex,
486                              const void *mem,
487                              size_t len,
488                              CURLcode *curlcode)
489 {
490   int ret = -1;
491
492   ret = ssl_write(&conn->ssl[sockindex].ssl,
493                   (unsigned char *)mem, len);
494
495   if(ret < 0) {
496     *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ?
497       CURLE_AGAIN : CURLE_SEND_ERROR;
498     ret = -1;
499   }
500
501   return ret;
502 }
503
504 void Curl_polarssl_close_all(struct SessionHandle *data)
505 {
506   (void)data;
507 }
508
509 void Curl_polarssl_close(struct connectdata *conn, int sockindex)
510 {
511   rsa_free(&conn->ssl[sockindex].rsa);
512   x509_crt_free(&conn->ssl[sockindex].clicert);
513   x509_crt_free(&conn->ssl[sockindex].cacert);
514   x509_crl_free(&conn->ssl[sockindex].crl);
515   ssl_free(&conn->ssl[sockindex].ssl);
516 }
517
518 static ssize_t polarssl_recv(struct connectdata *conn,
519                              int num,
520                              char *buf,
521                              size_t buffersize,
522                              CURLcode *curlcode)
523 {
524   int ret = -1;
525   ssize_t len = -1;
526
527   memset(buf, 0, buffersize);
528   ret = ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf, buffersize);
529
530   if(ret <= 0) {
531     if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
532       return 0;
533
534     *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ?
535       CURLE_AGAIN : CURLE_RECV_ERROR;
536     return -1;
537   }
538
539   len = ret;
540
541   return len;
542 }
543
544 void Curl_polarssl_session_free(void *ptr)
545 {
546   free(ptr);
547 }
548
549 size_t Curl_polarssl_version(char *buffer, size_t size)
550 {
551   unsigned int version = version_get_number();
552   return snprintf(buffer, size, "PolarSSL/%d.%d.%d", version>>24,
553                   (version>>16)&0xff, (version>>8)&0xff);
554 }
555
556 static CURLcode
557 polarssl_connect_common(struct connectdata *conn,
558                         int sockindex,
559                         bool nonblocking,
560                         bool *done)
561 {
562   CURLcode retcode;
563   struct SessionHandle *data = conn->data;
564   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
565   curl_socket_t sockfd = conn->sock[sockindex];
566   long timeout_ms;
567   int what;
568
569   /* check if the connection has already been established */
570   if(ssl_connection_complete == connssl->state) {
571     *done = TRUE;
572     return CURLE_OK;
573   }
574
575   if(ssl_connect_1==connssl->connecting_state) {
576     /* Find out how much more time we're allowed */
577     timeout_ms = Curl_timeleft(data, NULL, TRUE);
578
579     if(timeout_ms < 0) {
580       /* no need to continue if time already is up */
581       failf(data, "SSL connection timeout");
582       return CURLE_OPERATION_TIMEDOUT;
583     }
584     retcode = polarssl_connect_step1(conn, sockindex);
585     if(retcode)
586       return retcode;
587   }
588
589   while(ssl_connect_2 == connssl->connecting_state ||
590         ssl_connect_2_reading == connssl->connecting_state ||
591         ssl_connect_2_writing == connssl->connecting_state) {
592
593     /* check allowed time left */
594     timeout_ms = Curl_timeleft(data, NULL, TRUE);
595
596     if(timeout_ms < 0) {
597       /* no need to continue if time already is up */
598       failf(data, "SSL connection timeout");
599       return CURLE_OPERATION_TIMEDOUT;
600     }
601
602     /* if ssl is expecting something, check if it's available. */
603     if(connssl->connecting_state == ssl_connect_2_reading
604        || connssl->connecting_state == ssl_connect_2_writing) {
605
606       curl_socket_t writefd = ssl_connect_2_writing==
607         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
608       curl_socket_t readfd = ssl_connect_2_reading==
609         connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
610
611       what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
612       if(what < 0) {
613         /* fatal error */
614         failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
615         return CURLE_SSL_CONNECT_ERROR;
616       }
617       else if(0 == what) {
618         if(nonblocking) {
619           *done = FALSE;
620           return CURLE_OK;
621         }
622         else {
623           /* timeout */
624           failf(data, "SSL connection timeout");
625           return CURLE_OPERATION_TIMEDOUT;
626         }
627       }
628       /* socket is readable or writable */
629     }
630
631     /* Run transaction, and return to the caller if it failed or if
632      * this connection is part of a multi handle and this loop would
633      * execute again. This permits the owner of a multi handle to
634      * abort a connection attempt before step2 has completed while
635      * ensuring that a client using select() or epoll() will always
636      * have a valid fdset to wait on.
637      */
638     retcode = polarssl_connect_step2(conn, sockindex);
639     if(retcode || (nonblocking &&
640                    (ssl_connect_2 == connssl->connecting_state ||
641                     ssl_connect_2_reading == connssl->connecting_state ||
642                     ssl_connect_2_writing == connssl->connecting_state)))
643       return retcode;
644
645   } /* repeat step2 until all transactions are done. */
646
647   if(ssl_connect_3==connssl->connecting_state) {
648     retcode = polarssl_connect_step3(conn, sockindex);
649     if(retcode)
650       return retcode;
651   }
652
653   if(ssl_connect_done==connssl->connecting_state) {
654     connssl->state = ssl_connection_complete;
655     conn->recv[sockindex] = polarssl_recv;
656     conn->send[sockindex] = polarssl_send;
657     *done = TRUE;
658   }
659   else
660     *done = FALSE;
661
662   /* Reset our connect state machine */
663   connssl->connecting_state = ssl_connect_1;
664
665   return CURLE_OK;
666 }
667
668 CURLcode
669 Curl_polarssl_connect_nonblocking(struct connectdata *conn,
670                                 int sockindex,
671                                 bool *done)
672 {
673   return polarssl_connect_common(conn, sockindex, TRUE, done);
674 }
675
676
677 CURLcode
678 Curl_polarssl_connect(struct connectdata *conn,
679                     int sockindex)
680 {
681   CURLcode retcode;
682   bool done = FALSE;
683
684   retcode = polarssl_connect_common(conn, sockindex, FALSE, &done);
685   if(retcode)
686     return retcode;
687
688   DEBUGASSERT(done);
689
690   return CURLE_OK;
691 }
692
693 /*
694  * return 0 error initializing SSL
695  * return 1 SSL initialized successfully
696  */
697 int polarssl_init(void)
698 {
699   return polarsslthreadlock_thread_setup();
700 }
701
702 void polarssl_cleanup(void)
703 {
704   (void)polarsslthreadlock_thread_cleanup();
705 }
706
707 #endif /* USE_POLARSSL */