vtls.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 
23 /* This file is for implementing all "generic" SSL functions that all libcurl
24  internals should use. It is then responsible for calling the proper
25  "backend" function.
26 
27  SSL-functions in libcurl should call functions in this source file, and not
28  to any specific SSL-layer.
29 
30  Curl_ssl_ - prefix for generic ones
31 
32  Note that this source code uses the functions of the configured SSL
33  backend via the global Curl_ssl instance.
34 
35  "SSL/TLS Strong Encryption: An Introduction"
36  https://httpd.apache.org/docs/2.0/ssl/ssl_intro.html
37 */
38 
39 #include "curl_setup.h"
40 
41 #ifdef HAVE_SYS_TYPES_H
42 #include <sys/types.h>
43 #endif
44 #ifdef HAVE_SYS_STAT_H
45 #include <sys/stat.h>
46 #endif
47 #ifdef HAVE_FCNTL_H
48 #include <fcntl.h>
49 #endif
50 
51 #include "urldata.h"
52 
53 #include "vtls.h" /* generic SSL protos etc */
54 #include "slist.h"
55 #include "sendf.h"
56 #include "strcase.h"
57 #include "url.h"
58 #include "progress.h"
59 #include "share.h"
60 #include "multiif.h"
61 #include "timeval.h"
62 #include "curl_md5.h"
63 #include "warnless.h"
64 #include "curl_base64.h"
65 #include "curl_printf.h"
66 
67 /* The last #include files should be: */
68 #include "curl_memory.h"
69 #include "memdebug.h"
70 
71 /* convenience macro to check if this handle is using a shared SSL session */
72 #define SSLSESSION_SHARED(data) (data->share && \
73  (data->share->specifier & \
74  (1<<CURL_LOCK_DATA_SSL_SESSION)))
75 
76 #define CLONE_STRING(var) \
77  if(source->var) { \
78  dest->var = strdup(source->var); \
79  if(!dest->var) \
80  return FALSE; \
81  } \
82  else \
83  dest->var = NULL;
84 
85 bool
87  struct ssl_primary_config* needle)
88 {
89  if((data->version == needle->version) &&
90  (data->version_max == needle->version_max) &&
91  (data->verifypeer == needle->verifypeer) &&
92  (data->verifyhost == needle->verifyhost) &&
93  (data->verifystatus == needle->verifystatus) &&
94  Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
95  Curl_safe_strcasecompare(data->CAfile, needle->CAfile) &&
100  return TRUE;
101 
102  return FALSE;
103 }
104 
105 bool
107  struct ssl_primary_config *dest)
108 {
109  dest->version = source->version;
110  dest->version_max = source->version_max;
111  dest->verifypeer = source->verifypeer;
112  dest->verifyhost = source->verifyhost;
113  dest->verifystatus = source->verifystatus;
114  dest->sessionid = source->sessionid;
115 
116  CLONE_STRING(CApath);
117  CLONE_STRING(CAfile);
118  CLONE_STRING(clientcert);
119  CLONE_STRING(random_file);
120  CLONE_STRING(egdsocket);
121  CLONE_STRING(cipher_list);
122 
123  return TRUE;
124 }
125 
127 {
128  Curl_safefree(sslc->CApath);
129  Curl_safefree(sslc->CAfile);
130  Curl_safefree(sslc->clientcert);
131  Curl_safefree(sslc->random_file);
132  Curl_safefree(sslc->egdsocket);
133  Curl_safefree(sslc->cipher_list);
134 }
135 
136 #ifdef USE_SSL
137 static int multissl_init(const struct Curl_ssl *backend);
138 #endif
139 
141 {
142 #ifdef USE_SSL
143  multissl_init(NULL);
144  return Curl_ssl->info.id;
145 #else
146  return (int)CURLSSLBACKEND_NONE;
147 #endif
148 }
149 
150 #ifdef USE_SSL
151 
152 /* "global" init done? */
153 static bool init_ssl = FALSE;
154 
161 int Curl_ssl_init(void)
162 {
163  /* make sure this is only done once */
164  if(init_ssl)
165  return 1;
166  init_ssl = TRUE; /* never again */
167 
168  return Curl_ssl->init();
169 }
170 
171 
172 /* Global cleanup */
173 void Curl_ssl_cleanup(void)
174 {
175  if(init_ssl) {
176  /* only cleanup if we did a previous init */
177  Curl_ssl->cleanup();
178  init_ssl = FALSE;
179  }
180 }
181 
182 static bool ssl_prefs_check(struct Curl_easy *data)
183 {
184  /* check for CURLOPT_SSLVERSION invalid parameter value */
185  const long sslver = data->set.ssl.primary.version;
186  if((sslver < 0) || (sslver >= CURL_SSLVERSION_LAST)) {
187  failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION");
188  return FALSE;
189  }
190 
191  switch(data->set.ssl.primary.version_max) {
194  break;
195 
196  default:
197  if((data->set.ssl.primary.version_max >> 16) < sslver) {
198  failf(data, "CURL_SSLVERSION_MAX incompatible with CURL_SSLVERSION");
199  return FALSE;
200  }
201  }
202 
203  return TRUE;
204 }
205 
206 static CURLcode
207 ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
208 {
209  DEBUGASSERT(conn->bits.proxy_ssl_connected[sockindex]);
210  if(ssl_connection_complete == conn->ssl[sockindex].state &&
211  !conn->proxy_ssl[sockindex].use) {
212  struct ssl_backend_data *pbdata;
213 
215  return CURLE_NOT_BUILT_IN;
216 
217  /* The pointers to the ssl backend data, which is opaque here, are swapped
218  rather than move the contents. */
219  pbdata = conn->proxy_ssl[sockindex].backend;
220  conn->proxy_ssl[sockindex] = conn->ssl[sockindex];
221 
222  memset(&conn->ssl[sockindex], 0, sizeof(conn->ssl[sockindex]));
223  memset(pbdata, 0, Curl_ssl->sizeof_ssl_backend_data);
224 
225  conn->ssl[sockindex].backend = pbdata;
226  }
227  return CURLE_OK;
228 }
229 
230 CURLcode
231 Curl_ssl_connect(struct connectdata *conn, int sockindex)
232 {
234 
235  if(conn->bits.proxy_ssl_connected[sockindex]) {
236  result = ssl_connect_init_proxy(conn, sockindex);
237  if(result)
238  return result;
239  }
240 
241  if(!ssl_prefs_check(conn->data))
243 
244  /* mark this is being ssl-enabled from here on. */
245  conn->ssl[sockindex].use = TRUE;
246  conn->ssl[sockindex].state = ssl_connection_negotiating;
247 
248  result = Curl_ssl->connect(conn, sockindex);
249 
250  if(!result)
251  Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
252 
253  return result;
254 }
255 
256 CURLcode
257 Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
258  bool *done)
259 {
261  if(conn->bits.proxy_ssl_connected[sockindex]) {
262  result = ssl_connect_init_proxy(conn, sockindex);
263  if(result)
264  return result;
265  }
266 
267  if(!ssl_prefs_check(conn->data))
269 
270  /* mark this is being ssl requested from here on. */
271  conn->ssl[sockindex].use = TRUE;
272  result = Curl_ssl->connect_nonblocking(conn, sockindex, done);
273  if(!result && *done)
274  Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
275  return result;
276 }
277 
278 /*
279  * Lock shared SSL session data
280  */
281 void Curl_ssl_sessionid_lock(struct connectdata *conn)
282 {
283  if(SSLSESSION_SHARED(conn->data))
284  Curl_share_lock(conn->data,
286 }
287 
288 /*
289  * Unlock shared SSL session data
290  */
291 void Curl_ssl_sessionid_unlock(struct connectdata *conn)
292 {
293  if(SSLSESSION_SHARED(conn->data))
295 }
296 
297 /*
298  * Check if there's a session ID for the given connection in the cache, and if
299  * there's one suitable, it is provided. Returns TRUE when no entry matched.
300  */
301 bool Curl_ssl_getsessionid(struct connectdata *conn,
302  void **ssl_sessionid,
303  size_t *idsize, /* set 0 if unknown */
304  int sockindex)
305 {
306  struct curl_ssl_session *check;
307  struct Curl_easy *data = conn->data;
308  size_t i;
309  long *general_age;
310  bool no_match = TRUE;
311 
312  const bool isProxy = CONNECT_PROXY_SSL();
313  struct ssl_primary_config * const ssl_config = isProxy ?
314  &conn->proxy_ssl_config :
315  &conn->ssl_config;
316  const char * const name = isProxy ? conn->http_proxy.host.name :
317  conn->host.name;
318  int port = isProxy ? (int)conn->port : conn->remote_port;
319  *ssl_sessionid = NULL;
320 
321  DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
322 
323  if(!SSL_SET_OPTION(primary.sessionid))
324  /* session ID re-use is disabled */
325  return TRUE;
326 
327  /* Lock if shared */
328  if(SSLSESSION_SHARED(data))
329  general_age = &data->share->sessionage;
330  else
331  general_age = &data->state.sessionage;
332 
333  for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) {
334  check = &data->state.session[i];
335  if(!check->sessionid)
336  /* not session ID means blank entry */
337  continue;
338  if(strcasecompare(name, check->name) &&
339  ((!conn->bits.conn_to_host && !check->conn_to_host) ||
340  (conn->bits.conn_to_host && check->conn_to_host &&
341  strcasecompare(conn->conn_to_host.name, check->conn_to_host))) &&
342  ((!conn->bits.conn_to_port && check->conn_to_port == -1) ||
343  (conn->bits.conn_to_port && check->conn_to_port != -1 &&
344  conn->conn_to_port == check->conn_to_port)) &&
345  (port == check->remote_port) &&
346  strcasecompare(conn->handler->scheme, check->scheme) &&
347  Curl_ssl_config_matches(ssl_config, &check->ssl_config)) {
348  /* yes, we have a session ID! */
349  (*general_age)++; /* increase general age */
350  check->age = *general_age; /* set this as used in this age */
351  *ssl_sessionid = check->sessionid;
352  if(idsize)
353  *idsize = check->idsize;
354  no_match = FALSE;
355  break;
356  }
357  }
358 
359  return no_match;
360 }
361 
362 /*
363  * Kill a single session ID entry in the cache.
364  */
365 void Curl_ssl_kill_session(struct curl_ssl_session *session)
366 {
367  if(session->sessionid) {
368  /* defensive check */
369 
370  /* free the ID the SSL-layer specific way */
371  Curl_ssl->session_free(session->sessionid);
372 
373  session->sessionid = NULL;
374  session->age = 0; /* fresh */
375 
377 
378  Curl_safefree(session->name);
379  Curl_safefree(session->conn_to_host);
380  }
381 }
382 
383 /*
384  * Delete the given session ID from the cache.
385  */
386 void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid)
387 {
388  size_t i;
389  struct Curl_easy *data = conn->data;
390 
391  for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) {
392  struct curl_ssl_session *check = &data->state.session[i];
393 
394  if(check->sessionid == ssl_sessionid) {
395  Curl_ssl_kill_session(check);
396  break;
397  }
398  }
399 }
400 
401 /*
402  * Store session id in the session cache. The ID passed on to this function
403  * must already have been extracted and allocated the proper way for the SSL
404  * layer. Curl_XXXX_session_free() will be called to free/kill the session ID
405  * later on.
406  */
407 CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
408  void *ssl_sessionid,
409  size_t idsize,
410  int sockindex)
411 {
412  size_t i;
413  struct Curl_easy *data = conn->data; /* the mother of all structs */
414  struct curl_ssl_session *store = &data->state.session[0];
415  long oldest_age = data->state.session[0].age; /* zero if unused */
416  char *clone_host;
417  char *clone_conn_to_host;
418  int conn_to_port;
419  long *general_age;
420  const bool isProxy = CONNECT_PROXY_SSL();
421  struct ssl_primary_config * const ssl_config = isProxy ?
422  &conn->proxy_ssl_config :
423  &conn->ssl_config;
424 
425  DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
426 
427  clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);
428  if(!clone_host)
429  return CURLE_OUT_OF_MEMORY; /* bail out */
430 
431  if(conn->bits.conn_to_host) {
432  clone_conn_to_host = strdup(conn->conn_to_host.name);
433  if(!clone_conn_to_host) {
434  free(clone_host);
435  return CURLE_OUT_OF_MEMORY; /* bail out */
436  }
437  }
438  else
439  clone_conn_to_host = NULL;
440 
441  if(conn->bits.conn_to_port)
442  conn_to_port = conn->conn_to_port;
443  else
444  conn_to_port = -1;
445 
446  /* Now we should add the session ID and the host name to the cache, (remove
447  the oldest if necessary) */
448 
449  /* If using shared SSL session, lock! */
450  if(SSLSESSION_SHARED(data)) {
451  general_age = &data->share->sessionage;
452  }
453  else {
454  general_age = &data->state.sessionage;
455  }
456 
457  /* find an empty slot for us, or find the oldest */
458  for(i = 1; (i < data->set.general_ssl.max_ssl_sessions) &&
459  data->state.session[i].sessionid; i++) {
460  if(data->state.session[i].age < oldest_age) {
461  oldest_age = data->state.session[i].age;
462  store = &data->state.session[i];
463  }
464  }
465  if(i == data->set.general_ssl.max_ssl_sessions)
466  /* cache is full, we must "kill" the oldest entry! */
467  Curl_ssl_kill_session(store);
468  else
469  store = &data->state.session[i]; /* use this slot */
470 
471  /* now init the session struct wisely */
472  store->sessionid = ssl_sessionid;
473  store->idsize = idsize;
474  store->age = *general_age; /* set current age */
475  /* free it if there's one already present */
476  free(store->name);
477  free(store->conn_to_host);
478  store->name = clone_host; /* clone host name */
479  store->conn_to_host = clone_conn_to_host; /* clone connect to host name */
480  store->conn_to_port = conn_to_port; /* connect to port number */
481  /* port number */
482  store->remote_port = isProxy ? (int)conn->port : conn->remote_port;
483  store->scheme = conn->handler->scheme;
484 
485  if(!Curl_clone_primary_ssl_config(ssl_config, &store->ssl_config)) {
486  store->sessionid = NULL; /* let caller free sessionid */
487  free(clone_host);
488  free(clone_conn_to_host);
489  return CURLE_OUT_OF_MEMORY;
490  }
491 
492  return CURLE_OK;
493 }
494 
495 
496 void Curl_ssl_close_all(struct Curl_easy *data)
497 {
498  size_t i;
499  /* kill the session ID cache if not shared */
500  if(data->state.session && !SSLSESSION_SHARED(data)) {
501  for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++)
502  /* the single-killer function handles empty table slots */
504 
505  /* free the cache data */
506  Curl_safefree(data->state.session);
507  }
508 
509  Curl_ssl->close_all(data);
510 }
511 
512 #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
513  defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
514  defined(USE_MBEDTLS)
515 int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
516  int numsocks)
517 {
518  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
519 
520  if(!numsocks)
521  return GETSOCK_BLANK;
522 
523  if(connssl->connecting_state == ssl_connect_2_writing) {
524  /* write mode */
525  socks[0] = conn->sock[FIRSTSOCKET];
526  return GETSOCK_WRITESOCK(0);
527  }
528  if(connssl->connecting_state == ssl_connect_2_reading) {
529  /* read mode */
530  socks[0] = conn->sock[FIRSTSOCKET];
531  return GETSOCK_READSOCK(0);
532  }
533 
534  return GETSOCK_BLANK;
535 }
536 #else
537 int Curl_ssl_getsock(struct connectdata *conn,
538  curl_socket_t *socks,
539  int numsocks)
540 {
541  (void)conn;
542  (void)socks;
543  (void)numsocks;
544  return GETSOCK_BLANK;
545 }
546 /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_DARWINSSL || USE_NSS */
547 #endif
548 
549 void Curl_ssl_close(struct connectdata *conn, int sockindex)
550 {
551  DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
552  Curl_ssl->close(conn, sockindex);
553 }
554 
555 CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
556 {
557  if(Curl_ssl->shutdown(conn, sockindex))
559 
560  conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */
561  conn->ssl[sockindex].state = ssl_connection_none;
562 
563  conn->recv[sockindex] = Curl_recv_plain;
564  conn->send[sockindex] = Curl_send_plain;
565 
566  return CURLE_OK;
567 }
568 
569 /* Selects an SSL crypto engine
570  */
571 CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine)
572 {
573  return Curl_ssl->set_engine(data, engine);
574 }
575 
576 /* Selects the default SSL crypto engine
577  */
579 {
580  return Curl_ssl->set_engine_default(data);
581 }
582 
583 /* Return list of OpenSSL crypto engine names. */
584 struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data)
585 {
586  return Curl_ssl->engines_list(data);
587 }
588 
589 /*
590  * This sets up a session ID cache to the specified size. Make sure this code
591  * is agnostic to what underlying SSL technology we use.
592  */
593 CURLcode Curl_ssl_initsessions(struct Curl_easy *data, size_t amount)
594 {
595  struct curl_ssl_session *session;
596 
597  if(data->state.session)
598  /* this is just a precaution to prevent multiple inits */
599  return CURLE_OK;
600 
601  session = calloc(amount, sizeof(struct curl_ssl_session));
602  if(!session)
603  return CURLE_OUT_OF_MEMORY;
604 
605  /* store the info in the SSL section */
606  data->set.general_ssl.max_ssl_sessions = amount;
607  data->state.session = session;
608  data->state.sessionage = 1; /* this is brand new */
609  return CURLE_OK;
610 }
611 
612 static size_t Curl_multissl_version(char *buffer, size_t size);
613 
614 size_t Curl_ssl_version(char *buffer, size_t size)
615 {
616 #ifdef CURL_WITH_MULTI_SSL
617  return Curl_multissl_version(buffer, size);
618 #else
619  return Curl_ssl->version(buffer, size);
620 #endif
621 }
622 
623 /*
624  * This function tries to determine connection status.
625  *
626  * Return codes:
627  * 1 means the connection is still in place
628  * 0 means the connection has been closed
629  * -1 means the connection status is unknown
630  */
631 int Curl_ssl_check_cxn(struct connectdata *conn)
632 {
633  return Curl_ssl->check_cxn(conn);
634 }
635 
636 bool Curl_ssl_data_pending(const struct connectdata *conn,
637  int connindex)
638 {
639  return Curl_ssl->data_pending(conn, connindex);
640 }
641 
642 void Curl_ssl_free_certinfo(struct Curl_easy *data)
643 {
644  int i;
645  struct curl_certinfo *ci = &data->info.certs;
646 
647  if(ci->num_of_certs) {
648  /* free all individual lists used */
649  for(i = 0; i<ci->num_of_certs; i++) {
651  ci->certinfo[i] = NULL;
652  }
653 
654  free(ci->certinfo); /* free the actual array too */
655  ci->certinfo = NULL;
656  ci->num_of_certs = 0;
657  }
658 }
659 
660 CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num)
661 {
662  struct curl_certinfo *ci = &data->info.certs;
663  struct curl_slist **table;
664 
665  /* Free any previous certificate information structures */
667 
668  /* Allocate the required certificate information structures */
669  table = calloc((size_t) num, sizeof(struct curl_slist *));
670  if(!table)
671  return CURLE_OUT_OF_MEMORY;
672 
673  ci->num_of_certs = num;
674  ci->certinfo = table;
675 
676  return CURLE_OK;
677 }
678 
679 /*
680  * 'value' is NOT a zero terminated string
681  */
682 CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data,
683  int certnum,
684  const char *label,
685  const char *value,
686  size_t valuelen)
687 {
688  struct curl_certinfo *ci = &data->info.certs;
689  char *output;
690  struct curl_slist *nl;
692  size_t labellen = strlen(label);
693  size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
694 
695  output = malloc(outlen);
696  if(!output)
697  return CURLE_OUT_OF_MEMORY;
698 
699  /* sprintf the label and colon */
700  snprintf(output, outlen, "%s:", label);
701 
702  /* memcpy the value (it might not be zero terminated) */
703  memcpy(&output[labellen + 1], value, valuelen);
704 
705  /* zero terminate the output */
706  output[labellen + 1 + valuelen] = 0;
707 
708  nl = Curl_slist_append_nodup(ci->certinfo[certnum], output);
709  if(!nl) {
710  free(output);
711  curl_slist_free_all(ci->certinfo[certnum]);
712  result = CURLE_OUT_OF_MEMORY;
713  }
714 
715  ci->certinfo[certnum] = nl;
716  return result;
717 }
718 
719 /*
720  * This is a convenience function for push_certinfo_len that takes a zero
721  * terminated value.
722  */
723 CURLcode Curl_ssl_push_certinfo(struct Curl_easy *data,
724  int certnum,
725  const char *label,
726  const char *value)
727 {
728  size_t valuelen = strlen(value);
729 
730  return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen);
731 }
732 
733 CURLcode Curl_ssl_random(struct Curl_easy *data,
734  unsigned char *entropy,
735  size_t length)
736 {
737  return Curl_ssl->random(data, entropy, length);
738 }
739 
740 /*
741  * Public key pem to der conversion
742  */
743 
744 static CURLcode pubkey_pem_to_der(const char *pem,
745  unsigned char **der, size_t *der_len)
746 {
747  char *stripped_pem, *begin_pos, *end_pos;
748  size_t pem_count, stripped_pem_count = 0, pem_len;
750 
751  /* if no pem, exit. */
752  if(!pem)
754 
755  begin_pos = strstr(pem, "-----BEGIN PUBLIC KEY-----");
756  if(!begin_pos)
758 
759  pem_count = begin_pos - pem;
760  /* Invalid if not at beginning AND not directly following \n */
761  if(0 != pem_count && '\n' != pem[pem_count - 1])
763 
764  /* 26 is length of "-----BEGIN PUBLIC KEY-----" */
765  pem_count += 26;
766 
767  /* Invalid if not directly following \n */
768  end_pos = strstr(pem + pem_count, "\n-----END PUBLIC KEY-----");
769  if(!end_pos)
771 
772  pem_len = end_pos - pem;
773 
774  stripped_pem = malloc(pem_len - pem_count + 1);
775  if(!stripped_pem)
776  return CURLE_OUT_OF_MEMORY;
777 
778  /*
779  * Here we loop through the pem array one character at a time between the
780  * correct indices, and place each character that is not '\n' or '\r'
781  * into the stripped_pem array, which should represent the raw base64 string
782  */
783  while(pem_count < pem_len) {
784  if('\n' != pem[pem_count] && '\r' != pem[pem_count])
785  stripped_pem[stripped_pem_count++] = pem[pem_count];
786  ++pem_count;
787  }
788  /* Place the null terminator in the correct place */
789  stripped_pem[stripped_pem_count] = '\0';
790 
791  result = Curl_base64_decode(stripped_pem, der, der_len);
792 
793  Curl_safefree(stripped_pem);
794 
795  return result;
796 }
797 
798 /*
799  * Generic pinned public key check.
800  */
801 
802 CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
803  const char *pinnedpubkey,
804  const unsigned char *pubkey, size_t pubkeylen)
805 {
806  FILE *fp;
807  unsigned char *buf = NULL, *pem_ptr = NULL;
808  long filesize;
809  size_t size, pem_len;
810  CURLcode pem_read;
812  CURLcode encode;
813  size_t encodedlen, pinkeylen;
814  char *encoded, *pinkeycopy, *begin_pos, *end_pos;
815  unsigned char *sha256sumdigest = NULL;
816 
817  /* if a path wasn't specified, don't pin */
818  if(!pinnedpubkey)
819  return CURLE_OK;
820  if(!pubkey || !pubkeylen)
821  return result;
822 
823  /* only do this if pinnedpubkey starts with "sha256//", length 8 */
824  if(strncmp(pinnedpubkey, "sha256//", 8) == 0) {
825  if(!Curl_ssl->sha256sum) {
826  /* without sha256 support, this cannot match */
827  return result;
828  }
829 
830  /* compute sha256sum of public key */
831  sha256sumdigest = malloc(CURL_SHA256_DIGEST_LENGTH);
832  if(!sha256sumdigest)
833  return CURLE_OUT_OF_MEMORY;
834  Curl_ssl->sha256sum(pubkey, pubkeylen,
835  sha256sumdigest, CURL_SHA256_DIGEST_LENGTH);
836  encode = Curl_base64_encode(data, (char *)sha256sumdigest,
837  CURL_SHA256_DIGEST_LENGTH, &encoded,
838  &encodedlen);
839  Curl_safefree(sha256sumdigest);
840 
841  if(encode)
842  return encode;
843 
844  infof(data, "\t public key hash: sha256//%s\n", encoded);
845 
846  /* it starts with sha256//, copy so we can modify it */
847  pinkeylen = strlen(pinnedpubkey) + 1;
848  pinkeycopy = malloc(pinkeylen);
849  if(!pinkeycopy) {
850  Curl_safefree(encoded);
851  return CURLE_OUT_OF_MEMORY;
852  }
853  memcpy(pinkeycopy, pinnedpubkey, pinkeylen);
854  /* point begin_pos to the copy, and start extracting keys */
855  begin_pos = pinkeycopy;
856  do {
857  end_pos = strstr(begin_pos, ";sha256//");
858  /*
859  * if there is an end_pos, null terminate,
860  * otherwise it'll go to the end of the original string
861  */
862  if(end_pos)
863  end_pos[0] = '\0';
864 
865  /* compare base64 sha256 digests, 8 is the length of "sha256//" */
866  if(encodedlen == strlen(begin_pos + 8) &&
867  !memcmp(encoded, begin_pos + 8, encodedlen)) {
868  result = CURLE_OK;
869  break;
870  }
871 
872  /*
873  * change back the null-terminator we changed earlier,
874  * and look for next begin
875  */
876  if(end_pos) {
877  end_pos[0] = ';';
878  begin_pos = strstr(end_pos, "sha256//");
879  }
880  } while(end_pos && begin_pos);
881  Curl_safefree(encoded);
882  Curl_safefree(pinkeycopy);
883  return result;
884  }
885 
886  fp = fopen(pinnedpubkey, "rb");
887  if(!fp)
888  return result;
889 
890  do {
891  /* Determine the file's size */
892  if(fseek(fp, 0, SEEK_END))
893  break;
894  filesize = ftell(fp);
895  if(fseek(fp, 0, SEEK_SET))
896  break;
897  if(filesize < 0 || filesize > MAX_PINNED_PUBKEY_SIZE)
898  break;
899 
900  /*
901  * if the size of our certificate is bigger than the file
902  * size then it can't match
903  */
904  size = curlx_sotouz((curl_off_t) filesize);
905  if(pubkeylen > size)
906  break;
907 
908  /*
909  * Allocate buffer for the pinned key
910  * With 1 additional byte for null terminator in case of PEM key
911  */
912  buf = malloc(size + 1);
913  if(!buf)
914  break;
915 
916  /* Returns number of elements read, which should be 1 */
917  if((int) fread(buf, size, 1, fp) != 1)
918  break;
919 
920  /* If the sizes are the same, it can't be base64 encoded, must be der */
921  if(pubkeylen == size) {
922  if(!memcmp(pubkey, buf, pubkeylen))
923  result = CURLE_OK;
924  break;
925  }
926 
927  /*
928  * Otherwise we will assume it's PEM and try to decode it
929  * after placing null terminator
930  */
931  buf[size] = '\0';
932  pem_read = pubkey_pem_to_der((const char *)buf, &pem_ptr, &pem_len);
933  /* if it wasn't read successfully, exit */
934  if(pem_read)
935  break;
936 
937  /*
938  * if the size of our certificate doesn't match the size of
939  * the decoded file, they can't be the same, otherwise compare
940  */
941  if(pubkeylen == pem_len && !memcmp(pubkey, pem_ptr, pubkeylen))
942  result = CURLE_OK;
943  } while(0);
944 
945  Curl_safefree(buf);
946  Curl_safefree(pem_ptr);
947  fclose(fp);
948 
949  return result;
950 }
951 
952 #ifndef CURL_DISABLE_CRYPTO_AUTH
953 CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
954  size_t tmplen,
955  unsigned char *md5sum, /* output */
956  size_t md5len)
957 {
958  return Curl_ssl->md5sum(tmp, tmplen, md5sum, md5len);
959 }
960 #endif
961 
962 /*
963  * Check whether the SSL backend supports the status_request extension.
964  */
966 {
967  return Curl_ssl->cert_status_request();
968 }
969 
970 /*
971  * Check whether the SSL backend supports false start.
972  */
973 bool Curl_ssl_false_start(void)
974 {
975  return Curl_ssl->false_start();
976 }
977 
978 /*
979  * Default implementations for unsupported functions.
980  */
981 
982 int Curl_none_init(void)
983 {
984  return 1;
985 }
986 
987 void Curl_none_cleanup(void)
988 { }
989 
991  int sockindex UNUSED_PARAM)
992 {
993  (void)conn;
994  (void)sockindex;
995  return 0;
996 }
997 
999 {
1000  (void)conn;
1001  return -1;
1002 }
1003 
1005  unsigned char *entropy UNUSED_PARAM,
1006  size_t length UNUSED_PARAM)
1007 {
1008  (void)data;
1009  (void)entropy;
1010  (void)length;
1011  return CURLE_NOT_BUILT_IN;
1012 }
1013 
1014 void Curl_none_close_all(struct Curl_easy *data UNUSED_PARAM)
1015 {
1016  (void)data;
1017 }
1018 
1020 {
1021  (void)ptr;
1022 }
1023 
1024 bool Curl_none_data_pending(const struct connectdata *conn UNUSED_PARAM,
1025  int connindex UNUSED_PARAM)
1026 {
1027  (void)conn;
1028  (void)connindex;
1029  return 0;
1030 }
1031 
1033 {
1034  return FALSE;
1035 }
1036 
1038  const char *engine UNUSED_PARAM)
1039 {
1040  (void)data;
1041  (void)engine;
1042  return CURLE_NOT_BUILT_IN;
1043 }
1044 
1046 {
1047  (void)data;
1048  return CURLE_NOT_BUILT_IN;
1049 }
1050 
1052 {
1053  (void)data;
1054  return (struct curl_slist *)NULL;
1055 }
1056 
1057 bool Curl_none_false_start(void)
1058 {
1059  return FALSE;
1060 }
1061 
1062 CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
1063  unsigned char *md5sum, size_t md5len UNUSED_PARAM)
1064 {
1065  MD5_context *MD5pw;
1066 
1067  (void)md5len;
1068 
1069  MD5pw = Curl_MD5_init(Curl_DIGEST_MD5);
1070  if(!MD5pw)
1071  return CURLE_OUT_OF_MEMORY;
1072  Curl_MD5_update(MD5pw, input, curlx_uztoui(inputlen));
1073  Curl_MD5_final(MD5pw, md5sum);
1074  return CURLE_OK;
1075 }
1076 
1077 static int Curl_multissl_init(void)
1078 {
1079  if(multissl_init(NULL))
1080  return 1;
1081  return Curl_ssl->init();
1082 }
1083 
1084 static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex)
1085 {
1086  if(multissl_init(NULL))
1087  return CURLE_FAILED_INIT;
1088  return Curl_ssl->connect(conn, sockindex);
1089 }
1090 
1091 static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn,
1092  int sockindex, bool *done)
1093 {
1094  if(multissl_init(NULL))
1095  return CURLE_FAILED_INIT;
1096  return Curl_ssl->connect_nonblocking(conn, sockindex, done);
1097 }
1098 
1099 static void *Curl_multissl_get_internals(struct ssl_connect_data *connssl,
1100  CURLINFO info)
1101 {
1102  if(multissl_init(NULL))
1103  return NULL;
1104  return Curl_ssl->get_internals(connssl, info);
1105 }
1106 
1107 static void Curl_multissl_close(struct connectdata *conn, int sockindex)
1108 {
1109  if(multissl_init(NULL))
1110  return;
1111  Curl_ssl->close(conn, sockindex);
1112 }
1113 
1114 static const struct Curl_ssl Curl_ssl_multi = {
1115  { CURLSSLBACKEND_NONE, "multi" }, /* info */
1116 
1117  0, /* have_ca_path */
1118  0, /* have_certinfo */
1119  0, /* have_pinnedpubkey */
1120  0, /* have_ssl_ctx */
1121  0, /* support_https_proxy */
1122 
1123  (size_t)-1, /* something insanely large to be on the safe side */
1124 
1125  Curl_multissl_init, /* init */
1126  Curl_none_cleanup, /* cleanup */
1127  Curl_multissl_version, /* version */
1128  Curl_none_check_cxn, /* check_cxn */
1129  Curl_none_shutdown, /* shutdown */
1130  Curl_none_data_pending, /* data_pending */
1131  Curl_none_random, /* random */
1132  Curl_none_cert_status_request, /* cert_status_request */
1133  Curl_multissl_connect, /* connect */
1134  Curl_multissl_connect_nonblocking, /* connect_nonblocking */
1135  Curl_multissl_get_internals, /* get_internals */
1136  Curl_multissl_close, /* close */
1137  Curl_none_close_all, /* close_all */
1138  Curl_none_session_free, /* session_free */
1139  Curl_none_set_engine, /* set_engine */
1140  Curl_none_set_engine_default, /* set_engine_default */
1141  Curl_none_engines_list, /* engines_list */
1142  Curl_none_false_start, /* false_start */
1143  Curl_none_md5sum, /* md5sum */
1144  NULL /* sha256sum */
1145 };
1146 
1147 const struct Curl_ssl *Curl_ssl =
1148 #if defined(CURL_WITH_MULTI_SSL)
1149  &Curl_ssl_multi;
1150 #elif defined(USE_AXTLS)
1151  &Curl_ssl_axtls;
1152 #elif defined(USE_CYASSL)
1153  &Curl_ssl_cyassl;
1154 #elif defined(USE_DARWINSSL)
1155  &Curl_ssl_darwinssl;
1156 #elif defined(USE_GNUTLS)
1157  &Curl_ssl_gnutls;
1158 #elif defined(USE_GSKIT)
1159  &Curl_ssl_gskit;
1160 #elif defined(USE_MBEDTLS)
1161  &Curl_ssl_mbedtls;
1162 #elif defined(USE_NSS)
1163  &Curl_ssl_nss;
1164 #elif defined(USE_OPENSSL)
1165  &Curl_ssl_openssl;
1166 #elif defined(USE_POLARSSL)
1167  &Curl_ssl_polarssl;
1168 #elif defined(USE_SCHANNEL)
1169  &Curl_ssl_schannel;
1170 #else
1171 #error "Missing struct Curl_ssl for selected SSL backend"
1172 #endif
1173 
1174 static const struct Curl_ssl *available_backends[] = {
1175 #if defined(USE_AXTLS)
1176  &Curl_ssl_axtls,
1177 #endif
1178 #if defined(USE_CYASSL)
1179  &Curl_ssl_cyassl,
1180 #endif
1181 #if defined(USE_DARWINSSL)
1182  &Curl_ssl_darwinssl,
1183 #endif
1184 #if defined(USE_GNUTLS)
1185  &Curl_ssl_gnutls,
1186 #endif
1187 #if defined(USE_GSKIT)
1188  &Curl_ssl_gskit,
1189 #endif
1190 #if defined(USE_MBEDTLS)
1191  &Curl_ssl_mbedtls,
1192 #endif
1193 #if defined(USE_NSS)
1194  &Curl_ssl_nss,
1195 #endif
1196 #if defined(USE_OPENSSL)
1197  &Curl_ssl_openssl,
1198 #endif
1199 #if defined(USE_POLARSSL)
1200  &Curl_ssl_polarssl,
1201 #endif
1202 #if defined(USE_SCHANNEL)
1203  &Curl_ssl_schannel,
1204 #endif
1205  NULL
1206 };
1207 
1208 static size_t Curl_multissl_version(char *buffer, size_t size)
1209 {
1210  static const struct Curl_ssl *selected;
1211  static char backends[200];
1212  static size_t total;
1213  const struct Curl_ssl *current;
1214 
1215  current = Curl_ssl == &Curl_ssl_multi ? available_backends[0] : Curl_ssl;
1216 
1217  if(current != selected) {
1218  char *p = backends;
1219  int i;
1220 
1221  selected = current;
1222 
1223  for(i = 0; available_backends[i]; i++) {
1224  if(i)
1225  *(p++) = ' ';
1226  if(selected != available_backends[i])
1227  *(p++) = '(';
1228  p += available_backends[i]->version(p, backends + sizeof(backends) - p);
1229  if(selected != available_backends[i])
1230  *(p++) = ')';
1231  }
1232  *p = '\0';
1233  total = p - backends;
1234  }
1235 
1236  if(size < total)
1237  memcpy(buffer, backends, total + 1);
1238  else {
1239  memcpy(buffer, backends, size - 1);
1240  buffer[size - 1] = '\0';
1241  }
1242 
1243  return total;
1244 }
1245 
1246 static int multissl_init(const struct Curl_ssl *backend)
1247 {
1248  const char *env;
1249  int i;
1250 
1251  if(Curl_ssl != &Curl_ssl_multi)
1252  return 1;
1253 
1254  if(backend) {
1255  Curl_ssl = backend;
1256  return 0;
1257  }
1258 
1259  if(!available_backends[0])
1260  return 1;
1261 
1262  env = getenv("CURL_SSL_BACKEND");
1263 #ifdef CURL_DEFAULT_SSL_BACKEND
1264  if(!env)
1265  env = CURL_DEFAULT_SSL_BACKEND;
1266 #endif
1267  if(env) {
1268  for(i = 0; available_backends[i]; i++) {
1269  if(strcasecompare(env, available_backends[i]->info.name)) {
1270  Curl_ssl = available_backends[i];
1271  return 0;
1272  }
1273  }
1274  }
1275 
1276  /* Fall back to first available backend */
1277  Curl_ssl = available_backends[0];
1278  return 0;
1279 }
1280 
1282  const curl_ssl_backend ***avail)
1283 {
1284  int i;
1285 
1286  if(Curl_ssl != &Curl_ssl_multi)
1287  return id == Curl_ssl->info.id ? CURLSSLSET_OK : CURLSSLSET_TOO_LATE;
1288 
1289  for(i = 0; available_backends[i]; i++) {
1290  if(available_backends[i]->info.id == id ||
1291  (name && strcasecompare(available_backends[i]->info.name, name))) {
1292  multissl_init(available_backends[i]);
1293  return CURLSSLSET_OK;
1294  }
1295  }
1296 
1297  if(avail)
1298  *avail = (const curl_ssl_backend **)&available_backends;
1300 }
1301 
1302 #else /* USE_SSL */
1304  const curl_ssl_backend ***avail)
1305 {
1306  (void)id;
1307  (void)name;
1308  (void)avail;
1309  return CURLSSLSET_NO_BACKENDS;
1310 }
1311 
1312 #endif /* !USE_SSL */
#define free(ptr)
Definition: curl_memory.h:130
struct ssl_connect_data ssl[2]
Definition: urldata.h:887
#define UNUSED_PARAM
Definition: curl_setup.h:660
bool Curl_ssl_config_matches(struct ssl_primary_config *data, struct ssl_primary_config *needle)
Definition: vtls.c:86
const char * scheme
Definition: urldata.h:256
struct ConnectBits bits
Definition: urldata.h:893
#define getenv
Definition: setup-vms.h:52
ROSCPP_DECL bool check()
#define Curl_ssl_random(x, y, z)
Definition: vtls.h:269
struct UserDefined set
Definition: urldata.h:1762
#define filesize(name, stat_data)
Definition: mime.c:127
Curl_recv * recv[2]
Definition: urldata.h:881
const MD5_params Curl_DIGEST_MD5[1]
Definition: md5.c:498
char * egdsocket
Definition: urldata.h:218
CURLcode Curl_base64_decode(const char *src, unsigned char **outptr, size_t *outlen)
Definition: base64.c:100
size_t idsize
Definition: urldata.h:258
CURLsslset
Definition: curl.h:2371
struct hostname host
Definition: urldata.h:758
void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
Definition: progress.c:162
#define FIRSTSOCKET
Definition: urldata.h:487
struct curl_slist * Curl_slist_append_nodup(struct curl_slist *list, char *data)
Definition: slist.c:59
int Curl_MD5_update(MD5_context *context, const unsigned char *data, unsigned int len)
Definition: md5.c:544
Definition: vtls.h:29
MD5_context * Curl_MD5_init(const MD5_params *md5params)
Definition: md5.c:520
int Curl_none_init(void)
const char * name
Definition: curl.h:2368
CURLcode(* set_engine)(struct Curl_easy *data, const char *engine)
Definition: vtls.h:67
void Curl_none_session_free(void *ptr)
#define failf
Definition: sendf.h:48
#define SSL_SET_OPTION(var)
Definition: vtls.h:133
ssl_connect_state connecting_state
Definition: urldata.h:201
CURLcode(* connect)(struct connectdata *conn, int sockindex)
Definition: vtls.h:59
#define strdup(ptr)
Definition: curl_memory.h:122
CURLcode Curl_base64_encode(struct Curl_easy *data, const char *inputbuff, size_t insize, char **outptr, size_t *outlen)
Definition: base64.c:291
const struct Curl_handler * handler
Definition: urldata.h:904
int conn_to_port
Definition: urldata.h:843
#define DEBUGASSERT(x)
#define SSLSESSION_SHARED(data)
Definition: vtls.c:72
UNITTEST_START char * ptr
Definition: unit1330.c:38
CURLcode
Definition: curl.h:454
#define GETSOCK_READSOCK(x)
Definition: multiif.h:48
#define Curl_ssl_close(x, y)
Definition: vtls.h:255
#define Curl_ssl_set_engine_default(x)
Definition: vtls.h:258
CURLINFO
Definition: curl.h:2439
int Curl_none_shutdown(struct connectdata *conn, int sockindex)
bool Curl_none_data_pending(const struct connectdata *conn, int connindex)
struct hostname host
Definition: urldata.h:833
#define Curl_ssl_connect(x, y)
Definition: vtls.h:253
#define Curl_ssl_connect_nonblocking(x, y, z)
Definition: vtls.h:267
CURLcode(* random)(struct Curl_easy *data, unsigned char *entropy, size_t length)
Definition: vtls.h:55
size_t max_ssl_sessions
Definition: urldata.h:249
bool conn_to_port
Definition: urldata.h:380
#define strcasecompare(a, b)
Definition: strcase.h:35
#define malloc(size)
Definition: curl_memory.h:124
char * name
Definition: urldata.h:444
UNITTEST_START int result
Definition: unit1304.c:49
const char ** p
Definition: unit1394.c:76
char buffer[]
Definition: unit1308.c:48
struct Curl_share * share
Definition: urldata.h:1760
struct ssl_config_data ssl
Definition: urldata.h:1586
unsigned int i
Definition: unit1303.c:79
bool(* false_start)(void)
Definition: vtls.h:71
char * clientcert
Definition: urldata.h:216
void *(* get_internals)(struct ssl_connect_data *connssl, CURLINFO info)
Definition: vtls.h:62
struct proxy_info http_proxy
Definition: urldata.h:839
#define MAX_PINNED_PUBKEY_SIZE
Definition: vtls.h:112
struct ssl_primary_config primary
Definition: urldata.h:223
void * sessionid
Definition: urldata.h:257
const char * scheme
Definition: urldata.h:623
curl_sslbackend
Definition: curl.h:137
ssl_connection_state state
Definition: urldata.h:200
memcpy(filename, filename1, strlen(filename1))
#define Curl_ssl_data_pending(x, y)
Definition: vtls.h:264
#define Curl_ssl_shutdown(x, y)
Definition: vtls.h:256
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
Definition: unit1302.c:50
CURLSHcode Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
Definition: share.c:231
#define Curl_ssl_engines_list(x)
Definition: vtls.h:259
#define FALSE
CURLcode(* set_engine_default)(struct Curl_easy *data)
Definition: vtls.h:68
char * conn_to_host
Definition: urldata.h:255
void(* session_free)(void *ptr)
Definition: vtls.h:65
bool(* data_pending)(const struct connectdata *conn, int connindex)
Definition: vtls.h:51
curl_easy_setopt expects a curl_off_t argument for this option curl_easy_setopt expects a curl_write_callback argument for this option curl_easy_setopt expects a curl_ioctl_callback argument for this option curl_easy_setopt expects a curl_opensocket_callback argument for this option curl_easy_setopt expects a curl_debug_callback argument for this option curl_easy_setopt expects a curl_conv_callback argument for this option curl_easy_setopt expects a private data pointer as argument for this option curl_easy_setopt expects a FILE *argument for this option curl_easy_setopt expects a struct curl_httppost *argument for this option curl_easy_setopt expects a struct curl_slist *argument for this option curl_easy_getinfo expects a pointer to char *for this info curl_easy_getinfo expects a pointer to double for this info curl_easy_getinfo expects a pointer to struct curl_tlssessioninfo *for this info curl_easy_getinfo expects a pointer to curl_socket_t for this info size_t
CURLcode(* connect_nonblocking)(struct connectdata *conn, int sockindex, bool *done)
Definition: vtls.h:60
bool Curl_none_false_start(void)
#define Curl_ssl_version(x, y)
Definition: vtls.h:263
bool Curl_none_cert_status_request(void)
#define Curl_ssl_check_cxn(x)
Definition: vtls.h:265
struct curl_certinfo certs
Definition: urldata.h:1086
char * cipher_list
Definition: urldata.h:219
int Curl_safe_strcasecompare(const char *first, const char *second)
Definition: strcase.c:124
#define Curl_ssl_initsessions(x, y)
Definition: vtls.h:262
bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source, struct ssl_primary_config *dest)
Definition: vtls.c:106
int Curl_MD5_final(MD5_context *context, unsigned char *result)
Definition: md5.c:553
void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
Definition: vtls.c:126
#define CURL_SHA256_DIGEST_LENGTH
Definition: vtls.h:120
void Curl_none_cleanup(void)
#define GETSOCK_BLANK
Definition: multiif.h:42
CURL_TYPEOF_CURL_OFF_T curl_off_t
Definition: system.h:420
long sessionage
Definition: share.h:54
int num_of_certs
Definition: curl.h:2415
CURLcode(* md5sum)(unsigned char *input, size_t inputlen, unsigned char *md5sum, size_t md5sumlen)
Definition: vtls.h:73
void(* close_all)(struct Curl_easy *data)
Definition: vtls.h:64
Curl_send * send[2]
Definition: urldata.h:882
int(* check_cxn)(struct connectdata *cxn)
Definition: vtls.h:49
#define GETSOCK_WRITESOCK(x)
Definition: multiif.h:45
unsigned int curlx_uztoui(size_t uznum)
Definition: warnless.c:243
Definition: curl.h:455
bool conn_to_host
Definition: urldata.h:378
char * random_file
Definition: urldata.h:217
static unsigned short port
Definition: sockfilt.c:137
CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, unsigned char *md5sum, size_t md5len)
#define Curl_safefree(ptr)
Definition: memdebug.h:170
#define Curl_ssl_cleanup()
Definition: vtls.h:252
unsigned support_https_proxy
Definition: vtls.h:41
struct UrlState state
Definition: urldata.h:1769
#define CLONE_STRING(var)
Definition: vtls.c:76
CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine)
int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks, int numsocks)
struct curl_slist ** certinfo
Definition: curl.h:2416
ssize_t Curl_send_plain(struct connectdata *conn, int num, const void *mem, size_t len, CURLcode *code)
Definition: sendf.c:351
struct PureInfo info
Definition: urldata.h:1772
size_t fread(void *, size_t, size_t, FILE *)
int Curl_ssl_backend(void)
Definition: vtls.c:140
#define Curl_ssl_init()
Definition: vtls.h:251
struct curl_ssl_session * session
Definition: urldata.h:1266
curl_socket_t sock[2]
Definition: urldata.h:876
#define Curl_ssl_set_engine(x, y)
Definition: vtls.h:257
struct curl_slist *(* engines_list)(struct Curl_easy *data)
Definition: vtls.h:69
struct hostname conn_to_host
Definition: urldata.h:835
struct ssl_primary_config ssl_config
Definition: urldata.h:889
struct curl_slist * Curl_none_engines_list(struct Curl_easy *data)
char buf[3]
Definition: unit1398.c:32
#define Curl_ssl_kill_session(x)
Definition: vtls.h:268
#define infof
Definition: sendf.h:44
struct ssl_primary_config proxy_ssl_config
Definition: urldata.h:890
UNITTEST_START int * value
Definition: unit1602.c:51
CURLSHcode Curl_share_lock(struct Curl_easy *data, curl_lock_data type, curl_lock_access accesstype)
Definition: share.c:213
ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, size_t len, CURLcode *code)
Definition: sendf.c:425
#define Curl_ssl_cert_status_request()
Definition: vtls.h:270
int(* shutdown)(struct connectdata *conn, int sockindex)
Definition: vtls.h:50
struct ssl_connect_data proxy_ssl[2]
Definition: urldata.h:888
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
void(* close)(struct connectdata *conn, int sockindex)
Definition: vtls.h:63
long port
Definition: urldata.h:841
int(* init)(void)
Definition: vtls.h:45
size_t size
Definition: unit1302.c:52
CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, const curl_ssl_backend ***avail)
Definition: vtls.c:1303
#define snprintf
Definition: curl_printf.h:42
#define TRUE
void(* cleanup)(void)
Definition: vtls.h:46
size_t sizeof_ssl_backend_data
Definition: vtls.h:43
static int current
Definition: tftpd.c:188
curl_ssl_backend info
Definition: vtls.h:34
#define Curl_ssl_free_certinfo(x)
Definition: vtls.h:266
#define Curl_ssl_false_start()
Definition: vtls.h:271
size_t curlx_sotouz(curl_off_t sonum)
Definition: warnless.c:347
int curl_socket_t
Definition: curl.h:130
const char * name
Definition: curl_sasl.c:54
struct ssl_general_config general_ssl
Definition: urldata.h:1588
#define CONNECT_PROXY_SSL()
Definition: url.h:81
curl_sslbackend id
Definition: curl.h:2367
CURL_EXTERN void curl_slist_free_all(struct curl_slist *)
Definition: slist.c:129
struct ssl_primary_config ssl_config
Definition: urldata.h:262
long sessionage
Definition: urldata.h:1267
bool(* cert_status_request)(void)
Definition: vtls.h:57
bool proxy_ssl_connected[2]
Definition: urldata.h:436
CURLcode Curl_none_set_engine_default(struct Curl_easy *data)
Definition: debug.c:29
int remote_port
Definition: urldata.h:842
void Curl_none_close_all(struct Curl_easy *data)
size_t(* version)(char *buffer, size_t size)
Definition: vtls.h:48
#define calloc(nbelem, size)
Definition: curl_memory.h:126
#define Curl_ssl_close_all(x)
Definition: vtls.h:254
void(* sha256sum)(const unsigned char *input, size_t inputlen, unsigned char *sha256sum, size_t sha256sumlen)
Definition: vtls.h:75
struct Curl_easy * data
Definition: urldata.h:791


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:17