Remove unnecessary projects and libs

This commit is contained in:
Miguel Horta
2022-06-17 12:02:21 +01:00
parent 8c03645bce
commit e4939e3f3f
8360 changed files with 0 additions and 3346261 deletions

View File

@@ -1,736 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>.
* Copyright (C) 2010 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
* Source file for all axTLS-specific code for the TLS/SSL layer. No code
* but vtls.c should ever call or use these functions.
*/
#include "curl_setup.h"
#ifdef USE_AXTLS
#include <axTLS/config.h>
#include <axTLS/ssl.h>
#include "axtls.h"
#include "sendf.h"
#include "inet_pton.h"
#include "vtls.h"
#include "parsedate.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "curl_printf.h"
#include "hostcheck.h"
#include <unistd.h>
/* The last #include files should be: */
#include "curl_memory.h"
#include "memdebug.h"
struct ssl_backend_data {
SSL_CTX* ssl_ctx;
SSL* ssl;
};
#define BACKEND connssl->backend
static CURLcode map_error_to_curl(int axtls_err)
{
switch(axtls_err) {
case SSL_ERROR_NOT_SUPPORTED:
case SSL_ERROR_INVALID_VERSION:
case -70: /* protocol version alert from server */
return CURLE_UNSUPPORTED_PROTOCOL;
break;
case SSL_ERROR_NO_CIPHER:
return CURLE_SSL_CIPHER;
break;
case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
case SSL_ERROR_NO_CERT_DEFINED:
case -42: /* bad certificate alert from server */
case -43: /* unsupported cert alert from server */
case -44: /* cert revoked alert from server */
case -45: /* cert expired alert from server */
case -46: /* cert unknown alert from server */
return CURLE_SSL_CERTPROBLEM;
break;
case SSL_X509_ERROR(X509_NOT_OK):
case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
return CURLE_PEER_FAILED_VERIFICATION;
break;
case -48: /* unknown ca alert from server */
return CURLE_SSL_CACERT;
break;
case -49: /* access denied alert from server */
return CURLE_REMOTE_ACCESS_DENIED;
break;
case SSL_ERROR_CONN_LOST:
case SSL_ERROR_SOCK_SETUP_FAILURE:
case SSL_ERROR_INVALID_HANDSHAKE:
case SSL_ERROR_INVALID_PROT_MSG:
case SSL_ERROR_INVALID_HMAC:
case SSL_ERROR_INVALID_SESSION:
case SSL_ERROR_INVALID_KEY: /* it's too bad this doesn't map better */
case SSL_ERROR_FINISHED_INVALID:
case SSL_ERROR_NO_CLIENT_RENOG:
default:
return CURLE_SSL_CONNECT_ERROR;
break;
}
}
static Curl_recv axtls_recv;
static Curl_send axtls_send;
static void free_ssl_structs(struct ssl_connect_data *connssl)
{
if(BACKEND->ssl) {
ssl_free(BACKEND->ssl);
BACKEND->ssl = NULL;
}
if(BACKEND->ssl_ctx) {
ssl_ctx_free(BACKEND->ssl_ctx);
BACKEND->ssl_ctx = NULL;
}
}
/*
* For both blocking and non-blocking connects, this function sets up the
* ssl context and state. This function is called after the TCP connect
* has completed.
*/
static CURLcode connect_prep(struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct Curl_easy *data = conn->data;
SSL_CTX *ssl_ctx;
SSL *ssl = NULL;
int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
int i, ssl_fcn_return;
/* Assuming users will not compile in custom key/cert to axTLS.
* Also, even for blocking connects, use axTLS non-blocking feature.
*/
uint32_t client_option = SSL_NO_DEFAULT_KEY |
SSL_SERVER_VERIFY_LATER |
SSL_CONNECT_IN_PARTS;
if(connssl->state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
same connection */
return CURLE_OK;
if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
failf(data, "axtls does not support CURL_SSLVERSION_MAX");
return CURLE_SSL_CONNECT_ERROR;
}
/* axTLS only supports TLSv1 */
/* check to see if we've been told to use an explicit SSL/TLS version */
switch(SSL_CONN_CONFIG(version)) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
break;
default:
failf(data, "axTLS only supports TLS 1.0 and 1.1, "
"and it cannot be specified which one to use");
return CURLE_SSL_CONNECT_ERROR;
}
#ifdef AXTLSDEBUG
client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
#endif /* AXTLSDEBUG */
/* Allocate an SSL_CTX struct */
ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
if(ssl_ctx == NULL) {
failf(data, "unable to create client SSL context");
return CURLE_SSL_CONNECT_ERROR;
}
BACKEND->ssl_ctx = ssl_ctx;
BACKEND->ssl = NULL;
/* Load the trusted CA cert bundle file */
if(SSL_CONN_CONFIG(CAfile)) {
if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT,
SSL_CONN_CONFIG(CAfile), NULL) != SSL_OK) {
infof(data, "error reading ca cert file %s \n",
SSL_CONN_CONFIG(CAfile));
if(SSL_CONN_CONFIG(verifypeer)) {
return CURLE_SSL_CACERT_BADFILE;
}
}
else
infof(data, "found certificates in %s\n", SSL_CONN_CONFIG(CAfile));
}
/* gtls.c tasks we're skipping for now:
* 1) certificate revocation list checking
* 2) dns name assignment to host
* 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore
* 4) set certificate priority. axTLS ignores type and sends certs in
* order added. can probably ignore this.
*/
/* Load client certificate */
if(SSL_SET_OPTION(cert)) {
i = 0;
/* Instead of trying to analyze cert type here, let axTLS try them all. */
while(cert_types[i] != 0) {
ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
SSL_SET_OPTION(cert), NULL);
if(ssl_fcn_return == SSL_OK) {
infof(data, "successfully read cert file %s \n",
SSL_SET_OPTION(cert));
break;
}
i++;
}
/* Tried all cert types, none worked. */
if(cert_types[i] == 0) {
failf(data, "%s is not x509 or pkcs12 format",
SSL_SET_OPTION(cert));
return CURLE_SSL_CERTPROBLEM;
}
}
/* Load client key.
If a pkcs12 file successfully loaded a cert, then there's nothing to do
because the key has already been loaded. */
if(SSL_SET_OPTION(key) && cert_types[i] != SSL_OBJ_PKCS12) {
i = 0;
/* Instead of trying to analyze key type here, let axTLS try them all. */
while(key_types[i] != 0) {
ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
SSL_SET_OPTION(key), NULL);
if(ssl_fcn_return == SSL_OK) {
infof(data, "successfully read key file %s \n",
SSL_SET_OPTION(key));
break;
}
i++;
}
/* Tried all key types, none worked. */
if(key_types[i] == 0) {
failf(data, "Failure: %s is not a supported key file",
SSL_SET_OPTION(key));
return CURLE_SSL_CONNECT_ERROR;
}
}
/* gtls.c does more here that is being left out for now
* 1) set session credentials. can probably ignore since axtls puts this
* info in the ssl_ctx struct
* 2) setting up callbacks. these seem gnutls specific
*/
if(SSL_SET_OPTION(primary.sessionid)) {
const uint8_t *ssl_sessionid;
size_t ssl_idsize;
/* In axTLS, handshaking happens inside ssl_client_new. */
Curl_ssl_sessionid_lock(conn);
if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize,
sockindex)) {
/* we got a session id, use it! */
infof(data, "SSL re-using session ID\n");
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
ssl_sessionid, (uint8_t)ssl_idsize, NULL);
}
Curl_ssl_sessionid_unlock(conn);
}
if(!ssl)
ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0, NULL);
BACKEND->ssl = ssl;
return CURLE_OK;
}
static void Curl_axtls_close(struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
infof(conn->data, " Curl_axtls_close\n");
/* line from openssl.c: (void)SSL_shutdown(BACKEND->ssl);
axTLS compat layer does nothing for SSL_shutdown */
/* The following line is from openssl.c. There seems to be no axTLS
equivalent. ssl_free and ssl_ctx_free close things.
SSL_set_connect_state(connssl->handle); */
free_ssl_structs(connssl);
}
/*
* For both blocking and non-blocking connects, this function finalizes the
* SSL connection.
*/
static CURLcode connect_finish(struct connectdata *conn, int sockindex)
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
SSL *ssl = BACKEND->ssl;
const char *peer_CN;
uint32_t dns_altname_index;
const char *dns_altname;
int8_t found_subject_alt_names = 0;
int8_t found_subject_alt_name_matching_conn = 0;
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const char * const dispname = SSL_IS_PROXY() ?
conn->http_proxy.host.dispname : conn->host.dispname;
/* Here, gtls.c gets the peer certificates and fails out depending on
* settings in "data." axTLS api doesn't have get cert chain fcn, so omit?
*/
/* Verify server's certificate */
if(SSL_CONN_CONFIG(verifypeer)) {
if(ssl_verify_cert(ssl) != SSL_OK) {
Curl_axtls_close(conn, sockindex);
failf(data, "server cert verify failed");
return CURLE_PEER_FAILED_VERIFICATION;
}
}
else
infof(data, "\t server certificate verification SKIPPED\n");
/* Here, gtls.c does issuer verification. axTLS has no straightforward
* equivalent, so omitting for now.*/
/* Here, gtls.c does the following
* 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but
* it seems useful. This is now implemented, by Oscar Koeroo
* 2) checks cert validity based on time. axTLS does this in ssl_verify_cert
* 3) displays a bunch of cert information. axTLS doesn't support most of
* this, but a couple fields are available.
*/
/* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
risk of an inifite loop */
for(dns_altname_index = 0; ; dns_altname_index++) {
dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
if(dns_altname == NULL) {
break;
}
found_subject_alt_names = 1;
infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
dns_altname, hostname);
if(Curl_cert_hostcheck(dns_altname, hostname)) {
found_subject_alt_name_matching_conn = 1;
break;
}
}
/* RFC2818 checks */
if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
if(SSL_CONN_CONFIG(verifyhost)) {
/* Break connection ! */
Curl_axtls_close(conn, sockindex);
failf(data, "\tsubjectAltName(s) do not match %s\n", dispname);
return CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "\tsubjectAltName(s) do not match %s\n", dispname);
}
else if(found_subject_alt_names == 0) {
/* Per RFC2818, when no Subject Alt Names were available, examine the peer
CN as a legacy fallback */
peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
if(peer_CN == NULL) {
if(SSL_CONN_CONFIG(verifyhost)) {
Curl_axtls_close(conn, sockindex);
failf(data, "unable to obtain common name from peer certificate");
return CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "unable to obtain common name from peer certificate");
}
else {
if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
if(SSL_CONN_CONFIG(verifyhost)) {
/* Break connection ! */
Curl_axtls_close(conn, sockindex);
failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
peer_CN, dispname);
return CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
peer_CN, dispname);
}
}
}
/* General housekeeping */
connssl->state = ssl_connection_complete;
conn->recv[sockindex] = axtls_recv;
conn->send[sockindex] = axtls_send;
/* Put our freshly minted SSL session in cache */
if(SSL_SET_OPTION(primary.sessionid)) {
const uint8_t *ssl_sessionid = ssl_get_session_id(ssl);
size_t ssl_idsize = ssl_get_session_id_size(ssl);
Curl_ssl_sessionid_lock(conn);
if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize,
sockindex) != CURLE_OK)
infof(data, "failed to add session to cache\n");
Curl_ssl_sessionid_unlock(conn);
}
return CURLE_OK;
}
/*
* Use axTLS's non-blocking connection feature to open an SSL connection.
* This is called after a TCP connection is already established.
*/
static CURLcode Curl_axtls_connect_nonblocking(struct connectdata *conn,
int sockindex, bool *done)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode conn_step;
int ssl_fcn_return;
int i;
*done = FALSE;
/* connectdata is calloc'd and connecting_state is only changed in this
function, so this is safe, as the state is effectively initialized. */
if(connssl->connecting_state == ssl_connect_1) {
conn_step = connect_prep(conn, sockindex);
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
connssl->connecting_state = ssl_connect_2;
}
if(connssl->connecting_state == ssl_connect_2) {
/* Check to make sure handshake was ok. */
if(ssl_handshake_status(BACKEND->ssl) != SSL_OK) {
/* Loop to perform more work in between sleeps. This is work around the
fact that axtls does not expose any knowledge about when work needs
to be performed. This can save ~25% of time on SSL handshakes. */
for(i = 0; i<5; i++) {
ssl_fcn_return = ssl_read(BACKEND->ssl, NULL);
if(ssl_fcn_return < 0) {
Curl_axtls_close(conn, sockindex);
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
return map_error_to_curl(ssl_fcn_return);
}
return CURLE_OK;
}
}
infof(conn->data, "handshake completed successfully\n");
connssl->connecting_state = ssl_connect_3;
}
if(connssl->connecting_state == ssl_connect_3) {
conn_step = connect_finish(conn, sockindex);
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
/* Reset connect state */
connssl->connecting_state = ssl_connect_1;
*done = TRUE;
return CURLE_OK;
}
/* Unrecognized state. Things are very bad. */
connssl->state = ssl_connection_none;
connssl->connecting_state = ssl_connect_1;
/* Return value perhaps not strictly correct, but distinguishes the issue.*/
return CURLE_BAD_FUNCTION_ARGUMENT;
}
/*
* This function is called after the TCP connect has completed. Setup the TLS
* layer and do all necessary magic for a blocking connect.
*/
static CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex)
{
struct Curl_easy *data = conn->data;
CURLcode conn_step = connect_prep(conn, sockindex);
int ssl_fcn_return;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
SSL *ssl = BACKEND->ssl;
long timeout_ms;
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
/* Check to make sure handshake was ok. */
while(ssl_handshake_status(ssl) != SSL_OK) {
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
ssl_fcn_return = ssl_read(ssl, NULL);
if(ssl_fcn_return < 0) {
Curl_axtls_close(conn, sockindex);
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
return map_error_to_curl(ssl_fcn_return);
}
/* TODO: avoid polling */
Curl_wait_ms(10);
}
infof(conn->data, "handshake completed successfully\n");
conn_step = connect_finish(conn, sockindex);
if(conn_step != CURLE_OK) {
Curl_axtls_close(conn, sockindex);
return conn_step;
}
return CURLE_OK;
}
/* return number of sent (non-SSL) bytes */
static ssize_t axtls_send(struct connectdata *conn,
int sockindex,
const void *mem,
size_t len,
CURLcode *err)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
/* ssl_write() returns 'int' while write() and send() returns 'size_t' */
int rc = ssl_write(BACKEND->ssl, mem, (int)len);
infof(conn->data, " axtls_send\n");
if(rc < 0) {
*err = map_error_to_curl(rc);
rc = -1; /* generic error code for send failure */
}
*err = CURLE_OK;
return rc;
}
/*
* This function is called to shut down the SSL layer but keep the
* socket open (CCC - Clear Command Channel)
*/
static int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
{
/* Outline taken from openssl.c since functions are in axTLS compat layer.
axTLS's error set is much smaller, so a lot of error-handling was removed.
*/
int retval = 0;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct Curl_easy *data = conn->data;
uint8_t *buf;
ssize_t nread;
infof(conn->data, " Curl_axtls_shutdown\n");
/* This has only been tested on the proftpd server, and the mod_tls code
sends a close notify alert without waiting for a close notify alert in
response. Thus we wait for a close notify alert from the server, but
we do not send one. Let's hope other servers do the same... */
/* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
(void)SSL_shutdown(BACKEND->ssl);
*/
if(BACKEND->ssl) {
int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
if(what > 0) {
/* Something to read, let's do it and hope that it is the close
notify alert from the server. buf is managed internally by
axTLS and will be released upon calling ssl_free via
free_ssl_structs. */
nread = (ssize_t)ssl_read(BACKEND->ssl, &buf);
if(nread < SSL_OK) {
failf(data, "close notify alert not received during shutdown");
retval = -1;
}
}
else if(0 == what) {
/* timeout */
failf(data, "SSL shutdown timeout");
}
else {
/* anything that gets here is fatally bad */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
retval = -1;
}
free_ssl_structs(connssl);
}
return retval;
}
static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
int num, /* socketindex */
char *buf, /* store read data here */
size_t buffersize, /* max amount to read */
CURLcode *err)
{
struct ssl_connect_data *connssl = &conn->ssl[num];
ssize_t ret = 0;
uint8_t *read_buf;
infof(conn->data, " axtls_recv\n");
*err = CURLE_OK;
if(connssl) {
ret = ssl_read(BACKEND->ssl, &read_buf);
if(ret > SSL_OK) {
/* ssl_read returns SSL_OK if there is more data to read, so if it is
larger, then all data has been read already. */
memcpy(buf, read_buf,
(size_t)ret > buffersize ? buffersize : (size_t)ret);
}
else if(ret == SSL_OK) {
/* more data to be read, signal caller to call again */
*err = CURLE_AGAIN;
ret = -1;
}
else if(ret == -3) {
/* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS
team approves proposed fix. */
Curl_axtls_close(conn, num);
}
else {
failf(conn->data, "axTLS recv error (%d)", ret);
*err = map_error_to_curl((int) ret);
ret = -1;
}
}
return ret;
}
/*
* Return codes:
* 1 means the connection is still in place
* 0 means the connection has been closed
* -1 means the connection status is unknown
*/
static int Curl_axtls_check_cxn(struct connectdata *conn)
{
/* openssl.c line:
rc = SSL_peek(conn->ssl[FIRSTSOCKET].backend->ssl, (void*)&buf, 1);
axTLS compat layer always returns the last argument, so connection is
always alive? */
infof(conn->data, " Curl_axtls_check_cxn\n");
return 1; /* connection still in place */
}
static void Curl_axtls_session_free(void *ptr)
{
(void)ptr;
/* free the ID */
/* both openssl.c and gtls.c do something here, but axTLS's OpenSSL
compatibility layer does nothing, so we do nothing too. */
}
static size_t Curl_axtls_version(char *buffer, size_t size)
{
return snprintf(buffer, size, "axTLS/%s", ssl_version());
}
static CURLcode Curl_axtls_random(struct Curl_easy *data,
unsigned char *entropy, size_t length)
{
static bool ssl_seeded = FALSE;
(void)data;
if(!ssl_seeded) {
ssl_seeded = TRUE;
/* Initialize the seed if not already done. This call is not exactly thread
* safe (and neither is the ssl_seeded check), but the worst effect of a
* race condition is that some global resources will leak. */
RNG_initialize();
}
get_random((int)length, entropy);
return CURLE_OK;
}
static void *Curl_axtls_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
(void)info;
return BACKEND->ssl;
}
const struct Curl_ssl Curl_ssl_axtls = {
{ CURLSSLBACKEND_AXTLS, "axtls" }, /* info */
0, /* no fancy stuff */
sizeof(struct ssl_backend_data),
/*
* axTLS has no global init. Everything is done through SSL and SSL_CTX
* structs stored in connectdata structure.
*/
Curl_none_init, /* init */
/* axTLS has no global cleanup. */
Curl_none_cleanup, /* cleanup */
Curl_axtls_version, /* version */
Curl_axtls_check_cxn, /* check_cxn */
Curl_axtls_shutdown, /* shutdown */
Curl_none_data_pending, /* data_pending */
Curl_axtls_random, /* random */
Curl_none_cert_status_request, /* cert_status_request */
Curl_axtls_connect, /* connect */
Curl_axtls_connect_nonblocking, /* connect_nonblocking */
Curl_axtls_get_internals, /* get_internals */
Curl_axtls_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_axtls_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
Curl_none_md5sum, /* md5sum */
NULL /* sha256sum */
};
#endif /* USE_AXTLS */

View File

@@ -1,34 +0,0 @@
#ifndef HEADER_CURL_AXTLS_H
#define HEADER_CURL_AXTLS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu@directv.com>
* Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#ifdef USE_AXTLS
#include "curl/curl.h"
#include "urldata.h"
extern const struct Curl_ssl Curl_ssl_axtls;
#endif /* USE_AXTLS */
#endif /* HEADER_CURL_AXTLS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +0,0 @@
#ifndef HEADER_CURL_CYASSL_H
#define HEADER_CURL_CYASSL_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_CYASSL
extern const struct Curl_ssl Curl_ssl_cyassl;
#endif /* USE_CYASSL */
#endif /* HEADER_CURL_CYASSL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +0,0 @@
#ifndef HEADER_CURL_DARWINSSL_H
#define HEADER_CURL_DARWINSSL_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
* Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_DARWINSSL
extern const struct Curl_ssl Curl_ssl_darwinssl;
#endif /* USE_DARWINSSL */
#endif /* HEADER_CURL_DARWINSSL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,38 +0,0 @@
#ifndef HEADER_CURL_GSKIT_H
#define HEADER_CURL_GSKIT_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
/*
* This header should only be needed to get included by vtls.c and gskit.c
*/
#include "urldata.h"
#ifdef USE_GSKIT
extern const struct Curl_ssl Curl_ssl_gskit;
#endif /* USE_GSKIT */
#endif /* HEADER_CURL_GSKIT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,34 +0,0 @@
#ifndef HEADER_CURL_GTLS_H
#define HEADER_CURL_GTLS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_GNUTLS
#include "urldata.h"
extern const struct Curl_ssl Curl_ssl_gnutls;
#endif /* USE_GNUTLS */
#endif /* HEADER_CURL_GTLS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +0,0 @@
#ifndef HEADER_CURL_MBEDTLS_H
#define HEADER_CURL_MBEDTLS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_MBEDTLS
extern const struct Curl_ssl Curl_ssl_mbedtls;
#endif /* USE_MBEDTLS */
#endif /* HEADER_CURL_MBEDTLS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,39 +0,0 @@
#ifndef HEADER_CURL_NSSG_H
#define HEADER_CURL_NSSG_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_NSS
/*
* This header should only be needed to get included by vtls.c and nss.c
*/
#include "urldata.h"
/* initialize NSS library if not already */
CURLcode Curl_nss_force_init(struct Curl_easy *data);
extern const struct Curl_ssl Curl_ssl_nss;
#endif /* USE_NSS */
#endif /* HEADER_CURL_NSSG_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +0,0 @@
#ifndef HEADER_CURL_SSLUSE_H
#define HEADER_CURL_SSLUSE_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_OPENSSL
/*
* This header should only be needed to get included by vtls.c and openssl.c
*/
#include "urldata.h"
extern const struct Curl_ssl Curl_ssl_openssl;
#endif /* USE_OPENSSL */
#endif /* HEADER_CURL_SSLUSE_H */

View File

@@ -1,933 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
* Source file for all PolarSSL-specific code for the TLS/SSL layer. No code
* but vtls.c should ever call or use these functions.
*
*/
#include "curl_setup.h"
#ifdef USE_POLARSSL
#include <polarssl/net.h>
#include <polarssl/ssl.h>
#include <polarssl/certs.h>
#include <polarssl/x509.h>
#include <polarssl/version.h>
#include <polarssl/sha256.h>
#if POLARSSL_VERSION_NUMBER < 0x01030000
#error too old PolarSSL
#endif
#include <polarssl/error.h>
#include <polarssl/entropy.h>
#include <polarssl/ctr_drbg.h>
#include "urldata.h"
#include "sendf.h"
#include "inet_pton.h"
#include "polarssl.h"
#include "vtls.h"
#include "parsedate.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
#include "strcase.h"
#include "polarssl_threadlock.h"
#include "curl_printf.h"
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* See https://tls.mbed.org/discussions/generic/
howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
*/
#define RSA_PUB_DER_MAX_BYTES (38 + 2 * POLARSSL_MPI_MAX_SIZE)
#define ECP_PUB_DER_MAX_BYTES (30 + 2 * POLARSSL_ECP_MAX_BYTES)
#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
struct ssl_backend_data {
ctr_drbg_context ctr_drbg;
entropy_context entropy;
ssl_context ssl;
int server_fd;
x509_crt cacert;
x509_crt clicert;
x509_crl crl;
rsa_context rsa;
};
#define BACKEND connssl->backend
/* apply threading? */
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
#define THREADING_SUPPORT
#endif
#ifndef POLARSSL_ERROR_C
#define error_strerror(x,y,z)
#endif /* POLARSSL_ERROR_C */
#if defined(THREADING_SUPPORT)
static entropy_context entropy;
static int entropy_init_initialized = 0;
/* start of entropy_init_mutex() */
static void entropy_init_mutex(entropy_context *ctx)
{
/* lock 0 = entropy_init_mutex() */
Curl_polarsslthreadlock_lock_function(0);
if(entropy_init_initialized == 0) {
entropy_init(ctx);
entropy_init_initialized = 1;
}
Curl_polarsslthreadlock_unlock_function(0);
}
/* end of entropy_init_mutex() */
/* start of entropy_func_mutex() */
static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
{
int ret;
/* lock 1 = entropy_func_mutex() */
Curl_polarsslthreadlock_lock_function(1);
ret = entropy_func(data, output, len);
Curl_polarsslthreadlock_unlock_function(1);
return ret;
}
/* end of entropy_func_mutex() */
#endif /* THREADING_SUPPORT */
/* Define this to enable lots of debugging for PolarSSL */
#undef POLARSSL_DEBUG
#ifdef POLARSSL_DEBUG
static void polarssl_debug(void *context, int level, const char *line)
{
struct Curl_easy *data = NULL;
if(!context)
return;
data = (struct Curl_easy *)context;
infof(data, "%s", line);
(void) level;
}
#else
#endif
/* ALPN for http2? */
#ifdef POLARSSL_SSL_ALPN
# define HAS_ALPN
#endif
static Curl_recv polarssl_recv;
static Curl_send polarssl_send;
static CURLcode polarssl_version_from_curl(int *polarver, long ssl_version)
{
switch(ssl_version) {
case CURL_SSLVERSION_TLSv1_0:
*polarver = SSL_MINOR_VERSION_1;
return CURLE_OK;
case CURL_SSLVERSION_TLSv1_1:
*polarver = SSL_MINOR_VERSION_2;
return CURLE_OK;
case CURL_SSLVERSION_TLSv1_2:
*polarver = SSL_MINOR_VERSION_3;
return CURLE_OK;
case CURL_SSLVERSION_TLSv1_3:
break;
}
return CURLE_SSL_CONNECT_ERROR;
}
static CURLcode
set_ssl_version_min_max(struct connectdata *conn, int sockindex)
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
long ssl_version = SSL_CONN_CONFIG(version);
long ssl_version_max = SSL_CONN_CONFIG(version_max);
int ssl_min_ver = SSL_MINOR_VERSION_1;
int ssl_max_ver = SSL_MINOR_VERSION_1;
CURLcode result = CURLE_OK;
switch(ssl_version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
ssl_version = CURL_SSLVERSION_TLSv1_0;
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
break;
}
switch(ssl_version_max) {
case CURL_SSLVERSION_MAX_NONE:
ssl_version_max = ssl_version << 16;
break;
case CURL_SSLVERSION_MAX_DEFAULT:
ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
break;
}
result = polarssl_version_from_curl(&ssl_min_ver, ssl_version);
if(result) {
failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
return result;
}
result = polarssl_version_from_curl(&ssl_max_ver, ssl_version_max >> 16);
if(result) {
failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
return result;
}
ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver);
ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver);
return result;
}
static CURLcode
polarssl_connect_step1(struct connectdata *conn,
int sockindex)
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
const char *capath = SSL_CONN_CONFIG(CApath);
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
int ret = -1;
char errorbuf[128];
errorbuf[0] = 0;
/* PolarSSL only supports SSLv3 and TLSv1 */
if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
failf(data, "PolarSSL does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
#ifdef THREADING_SUPPORT
entropy_init_mutex(&entropy);
if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy,
NULL, 0)) != 0) {
error_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
-ret, errorbuf);
}
#else
entropy_init(&BACKEND->entropy);
if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy,
NULL, 0)) != 0) {
error_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
-ret, errorbuf);
}
#endif /* THREADING_SUPPORT */
/* Load the trusted CA */
memset(&BACKEND->cacert, 0, sizeof(x509_crt));
if(SSL_CONN_CONFIG(CAfile)) {
ret = x509_crt_parse_file(&BACKEND->cacert,
SSL_CONN_CONFIG(CAfile));
if(ret<0) {
error_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
SSL_CONN_CONFIG(CAfile), -ret, errorbuf);
if(SSL_CONN_CONFIG(verifypeer))
return CURLE_SSL_CACERT_BADFILE;
}
}
if(capath) {
ret = x509_crt_parse_path(&BACKEND->cacert, capath);
if(ret<0) {
error_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
capath, -ret, errorbuf);
if(SSL_CONN_CONFIG(verifypeer))
return CURLE_SSL_CACERT_BADFILE;
}
}
/* Load the client certificate */
memset(&BACKEND->clicert, 0, sizeof(x509_crt));
if(SSL_SET_OPTION(cert)) {
ret = x509_crt_parse_file(&BACKEND->clicert,
SSL_SET_OPTION(cert));
if(ret) {
error_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
SSL_SET_OPTION(cert), -ret, errorbuf);
return CURLE_SSL_CERTPROBLEM;
}
}
/* Load the client private key */
if(SSL_SET_OPTION(key)) {
pk_context pk;
pk_init(&pk);
ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key),
SSL_SET_OPTION(key_passwd));
if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
if(ret == 0)
rsa_copy(&BACKEND->rsa, pk_rsa(pk));
else
rsa_free(&BACKEND->rsa);
pk_free(&pk);
if(ret) {
error_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
SSL_SET_OPTION(key), -ret, errorbuf);
return CURLE_SSL_CERTPROBLEM;
}
}
/* Load the CRL */
memset(&BACKEND->crl, 0, sizeof(x509_crl));
if(SSL_SET_OPTION(CRLfile)) {
ret = x509_crl_parse_file(&BACKEND->crl,
SSL_SET_OPTION(CRLfile));
if(ret) {
error_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
SSL_SET_OPTION(CRLfile), -ret, errorbuf);
return CURLE_SSL_CRL_BADFILE;
}
}
infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port);
if(ssl_init(&BACKEND->ssl)) {
failf(data, "PolarSSL: ssl_init failed");
return CURLE_SSL_CONNECT_ERROR;
}
switch(SSL_CONN_CONFIG(version)) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
SSL_MINOR_VERSION_1);
break;
case CURL_SSLVERSION_SSLv3:
ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
SSL_MINOR_VERSION_0);
ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
SSL_MINOR_VERSION_0);
infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
break;
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
CURLcode result = set_ssl_version_min_max(conn, sockindex);
if(result != CURLE_OK)
return result;
break;
}
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
return CURLE_SSL_CONNECT_ERROR;
}
ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT);
ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL);
ssl_set_rng(&BACKEND->ssl, ctr_drbg_random,
&BACKEND->ctr_drbg);
ssl_set_bio(&BACKEND->ssl,
net_recv, &conn->sock[sockindex],
net_send, &conn->sock[sockindex]);
ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites());
/* Check if there's a cached ID we can/should use here! */
if(SSL_SET_OPTION(primary.sessionid)) {
void *old_session = NULL;
Curl_ssl_sessionid_lock(conn);
if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
ret = ssl_set_session(&BACKEND->ssl, old_session);
if(ret) {
Curl_ssl_sessionid_unlock(conn);
failf(data, "ssl_set_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR;
}
infof(data, "PolarSSL re-using session\n");
}
Curl_ssl_sessionid_unlock(conn);
}
ssl_set_ca_chain(&BACKEND->ssl,
&BACKEND->cacert,
&BACKEND->crl,
hostname);
ssl_set_own_cert_rsa(&BACKEND->ssl,
&BACKEND->clicert, &BACKEND->rsa);
if(ssl_set_hostname(&BACKEND->ssl, hostname)) {
/* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name
to set in the SNI extension. So even if curl connects to a host
specified as an IP address, this function must be used. */
failf(data, "couldn't set hostname in PolarSSL");
return CURLE_SSL_CONNECT_ERROR;
}
#ifdef HAS_ALPN
if(conn->bits.tls_enable_alpn) {
static const char *protocols[3];
int cur = 0;
#ifdef USE_NGHTTP2
if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
}
#endif
protocols[cur++] = ALPN_HTTP_1_1;
infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
protocols[cur] = NULL;
ssl_set_alpn_protocols(&BACKEND->ssl, protocols);
}
#endif
#ifdef POLARSSL_DEBUG
ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data);
#endif
connssl->connecting_state = ssl_connect_2;
return CURLE_OK;
}
static CURLcode
polarssl_connect_step2(struct connectdata *conn,
int sockindex)
{
int ret;
struct Curl_easy *data = conn->data;
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
char buffer[1024];
const char * const pinnedpubkey = SSL_IS_PROXY() ?
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
char errorbuf[128];
errorbuf[0] = 0;
conn->recv[sockindex] = polarssl_recv;
conn->send[sockindex] = polarssl_send;
ret = ssl_handshake(&BACKEND->ssl);
switch(ret) {
case 0:
break;
case POLARSSL_ERR_NET_WANT_READ:
connssl->connecting_state = ssl_connect_2_reading;
return CURLE_OK;
case POLARSSL_ERR_NET_WANT_WRITE:
connssl->connecting_state = ssl_connect_2_writing;
return CURLE_OK;
default:
error_strerror(ret, errorbuf, sizeof(errorbuf));
failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
-ret, errorbuf);
return CURLE_SSL_CONNECT_ERROR;
}
infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
ssl_get_ciphersuite(&BACKEND->ssl) );
ret = ssl_get_verify_result(&BACKEND->ssl);
if(ret && SSL_CONN_CONFIG(verifypeer)) {
if(ret & BADCERT_EXPIRED)
failf(data, "Cert verify failed: BADCERT_EXPIRED");
if(ret & BADCERT_REVOKED) {
failf(data, "Cert verify failed: BADCERT_REVOKED");
return CURLE_SSL_CACERT;
}
if(ret & BADCERT_CN_MISMATCH)
failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
if(ret & BADCERT_NOT_TRUSTED)
failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
return CURLE_PEER_FAILED_VERIFICATION;
}
if(ssl_get_peer_cert(&(BACKEND->ssl))) {
/* If the session was resumed, there will be no peer certs */
memset(buffer, 0, sizeof(buffer));
if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
ssl_get_peer_cert(&(BACKEND->ssl))) != -1)
infof(data, "Dumping cert info:\n%s\n", buffer);
}
/* adapted from mbedtls.c */
if(pinnedpubkey) {
int size;
CURLcode result;
x509_crt *p;
unsigned char pubkey[PUB_DER_MAX_BYTES];
const x509_crt *peercert;
peercert = ssl_get_peer_cert(&BACKEND->ssl);
if(!peercert || !peercert->raw.p || !peercert->raw.len) {
failf(data, "Failed due to missing peer certificate");
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
}
p = calloc(1, sizeof(*p));
if(!p)
return CURLE_OUT_OF_MEMORY;
x509_crt_init(p);
/* Make a copy of our const peercert because pk_write_pubkey_der
needs a non-const key, for now.
https://github.com/ARMmbed/mbedtls/issues/396 */
if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
failf(data, "Failed copying peer certificate");
x509_crt_free(p);
free(p);
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
}
size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
if(size <= 0) {
failf(data, "Failed copying public key from peer certificate");
x509_crt_free(p);
free(p);
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
}
/* pk_write_pubkey_der writes data at the end of the buffer. */
result = Curl_pin_peer_pubkey(data,
pinnedpubkey,
&pubkey[PUB_DER_MAX_BYTES - size], size);
if(result) {
x509_crt_free(p);
free(p);
return result;
}
x509_crt_free(p);
free(p);
}
#ifdef HAS_ALPN
if(conn->bits.tls_enable_alpn) {
const char *next_protocol = ssl_get_alpn_protocol(&BACKEND->ssl);
if(next_protocol != NULL) {
infof(data, "ALPN, server accepted to use %s\n", next_protocol);
#ifdef USE_NGHTTP2
if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
NGHTTP2_PROTO_VERSION_ID_LEN)) {
conn->negnpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
conn->negnpn = CURL_HTTP_VERSION_1_1;
}
}
else
infof(data, "ALPN, server did not agree to a protocol\n");
}
#endif
connssl->connecting_state = ssl_connect_3;
infof(data, "SSL connected\n");
return CURLE_OK;
}
static CURLcode
polarssl_connect_step3(struct connectdata *conn,
int sockindex)
{
CURLcode retcode = CURLE_OK;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct Curl_easy *data = conn->data;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
if(SSL_SET_OPTION(primary.sessionid)) {
int ret;
ssl_session *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
our_ssl_sessionid = calloc(1, sizeof(ssl_session));
if(!our_ssl_sessionid)
return CURLE_OUT_OF_MEMORY;
ret = ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
if(ret) {
failf(data, "ssl_get_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR;
}
/* If there's already a matching session in the cache, delete it */
Curl_ssl_sessionid_lock(conn);
if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
Curl_ssl_sessionid_unlock(conn);
if(retcode) {
free(our_ssl_sessionid);
failf(data, "failed to store ssl session");
return retcode;
}
}
connssl->connecting_state = ssl_connect_done;
return CURLE_OK;
}
static ssize_t polarssl_send(struct connectdata *conn,
int sockindex,
const void *mem,
size_t len,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
int ret = -1;
ret = ssl_write(&BACKEND->ssl,
(unsigned char *)mem, len);
if(ret < 0) {
*curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ?
CURLE_AGAIN : CURLE_SEND_ERROR;
ret = -1;
}
return ret;
}
static void Curl_polarssl_close(struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
rsa_free(&BACKEND->rsa);
x509_crt_free(&BACKEND->clicert);
x509_crt_free(&BACKEND->cacert);
x509_crl_free(&BACKEND->crl);
ssl_free(&BACKEND->ssl);
}
static ssize_t polarssl_recv(struct connectdata *conn,
int num,
char *buf,
size_t buffersize,
CURLcode *curlcode)
{
struct ssl_connect_data *connssl = &conn->ssl[num];
int ret = -1;
ssize_t len = -1;
memset(buf, 0, buffersize);
ret = ssl_read(&BACKEND->ssl, (unsigned char *)buf, buffersize);
if(ret <= 0) {
if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
return 0;
*curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ?
CURLE_AGAIN : CURLE_RECV_ERROR;
return -1;
}
len = ret;
return len;
}
static void Curl_polarssl_session_free(void *ptr)
{
ssl_session_free(ptr);
free(ptr);
}
/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and
higher) will be mbed TLS branded.. */
static size_t Curl_polarssl_version(char *buffer, size_t size)
{
unsigned int version = version_get_number();
return snprintf(buffer, size, "%s/%d.%d.%d",
version >= 0x01030A00?"mbedTLS":"PolarSSL",
version>>24, (version>>16)&0xff, (version>>8)&0xff);
}
static CURLcode
polarssl_connect_common(struct connectdata *conn,
int sockindex,
bool nonblocking,
bool *done)
{
CURLcode result;
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
curl_socket_t sockfd = conn->sock[sockindex];
long timeout_ms;
int what;
/* check if the connection has already been established */
if(ssl_connection_complete == connssl->state) {
*done = TRUE;
return CURLE_OK;
}
if(ssl_connect_1 == connssl->connecting_state) {
/* Find out how much more time we're allowed */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
result = polarssl_connect_step1(conn, sockindex);
if(result)
return result;
}
while(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
ssl_connect_2_writing == connssl->connecting_state) {
/* check allowed time left */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* no need to continue if time already is up */
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
/* if ssl is expecting something, check if it's available. */
if(connssl->connecting_state == ssl_connect_2_reading ||
connssl->connecting_state == ssl_connect_2_writing) {
curl_socket_t writefd = ssl_connect_2_writing ==
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
curl_socket_t readfd = ssl_connect_2_reading ==
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
nonblocking?0:timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
return CURLE_SSL_CONNECT_ERROR;
}
else if(0 == what) {
if(nonblocking) {
*done = FALSE;
return CURLE_OK;
}
else {
/* timeout */
failf(data, "SSL connection timeout");
return CURLE_OPERATION_TIMEDOUT;
}
}
/* socket is readable or writable */
}
/* Run transaction, and return to the caller if it failed or if
* this connection is part of a multi handle and this loop would
* execute again. This permits the owner of a multi handle to
* abort a connection attempt before step2 has completed while
* ensuring that a client using select() or epoll() will always
* have a valid fdset to wait on.
*/
result = polarssl_connect_step2(conn, sockindex);
if(result || (nonblocking &&
(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
ssl_connect_2_writing == connssl->connecting_state)))
return result;
} /* repeat step2 until all transactions are done. */
if(ssl_connect_3 == connssl->connecting_state) {
result = polarssl_connect_step3(conn, sockindex);
if(result)
return result;
}
if(ssl_connect_done == connssl->connecting_state) {
connssl->state = ssl_connection_complete;
conn->recv[sockindex] = polarssl_recv;
conn->send[sockindex] = polarssl_send;
*done = TRUE;
}
else
*done = FALSE;
/* Reset our connect state machine */
connssl->connecting_state = ssl_connect_1;
return CURLE_OK;
}
static CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn,
int sockindex, bool *done)
{
return polarssl_connect_common(conn, sockindex, TRUE, done);
}
static CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex)
{
CURLcode result;
bool done = FALSE;
result = polarssl_connect_common(conn, sockindex, FALSE, &done);
if(result)
return result;
DEBUGASSERT(done);
return CURLE_OK;
}
/*
* return 0 error initializing SSL
* return 1 SSL initialized successfully
*/
static int Curl_polarssl_init(void)
{
return Curl_polarsslthreadlock_thread_setup();
}
static void Curl_polarssl_cleanup(void)
{
(void)Curl_polarsslthreadlock_thread_cleanup();
}
static bool Curl_polarssl_data_pending(const struct connectdata *conn,
int sockindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
return ssl_get_bytes_avail(&BACKEND->ssl) != 0;
}
static CURLcode Curl_polarssl_sha256sum(const unsigned char *input,
size_t inputlen,
unsigned char *sha256sum,
size_t sha256len UNUSED_PARAM)
{
(void)sha256len;
sha256(input, inputlen, sha256sum, 0);
return CURLE_OK;
}
static void *Curl_polarssl_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
(void)info;
return &BACKEND->ssl;
}
const struct Curl_ssl Curl_ssl_polarssl = {
{ CURLSSLBACKEND_POLARSSL, "polarssl" }, /* info */
SSLSUPP_CA_PATH |
SSLSUPP_PINNEDPUBKEY,
sizeof(struct ssl_backend_data),
Curl_polarssl_init, /* init */
Curl_polarssl_cleanup, /* cleanup */
Curl_polarssl_version, /* version */
Curl_none_check_cxn, /* check_cxn */
Curl_none_shutdown, /* shutdown */
Curl_polarssl_data_pending, /* data_pending */
/* This might cause libcurl to use a weeker random!
* TODO: use Polarssl's CTR-DRBG or HMAC-DRBG
*/
Curl_none_random, /* random */
Curl_none_cert_status_request, /* cert_status_request */
Curl_polarssl_connect, /* connect */
Curl_polarssl_connect_nonblocking, /* connect_nonblocking */
Curl_polarssl_get_internals, /* get_internals */
Curl_polarssl_close, /* close_one */
Curl_none_close_all, /* close_all */
Curl_polarssl_session_free, /* session_free */
Curl_none_set_engine, /* set_engine */
Curl_none_set_engine_default, /* set_engine_default */
Curl_none_engines_list, /* engines_list */
Curl_none_false_start, /* false_start */
Curl_none_md5sum, /* md5sum */
Curl_polarssl_sha256sum /* sha256sum */
};
#endif /* USE_POLARSSL */

View File

@@ -1,32 +0,0 @@
#ifndef HEADER_CURL_POLARSSL_H
#define HEADER_CURL_POLARSSL_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_POLARSSL
extern const struct Curl_ssl Curl_ssl_polarssl;
#endif /* USE_POLARSSL */
#endif /* HEADER_CURL_POLARSSL_H */

View File

@@ -1,153 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2013-2017, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#if (defined(USE_POLARSSL) || defined(USE_MBEDTLS)) && \
(defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32))
#if defined(USE_THREADS_POSIX)
# ifdef HAVE_PTHREAD_H
# include <pthread.h>
# endif
#elif defined(USE_THREADS_WIN32)
# ifdef HAVE_PROCESS_H
# include <process.h>
# endif
#endif
#include "polarssl_threadlock.h"
#include "curl_printf.h"
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
/* number of thread locks */
#define NUMT 2
/* This array will store all of the mutexes available to PolarSSL. */
static POLARSSL_MUTEX_T *mutex_buf = NULL;
int Curl_polarsslthreadlock_thread_setup(void)
{
int i;
int ret;
mutex_buf = calloc(NUMT * sizeof(POLARSSL_MUTEX_T), 1);
if(!mutex_buf)
return 0; /* error, no number of threads defined */
#ifdef HAVE_PTHREAD_H
for(i = 0; i < NUMT; i++) {
ret = pthread_mutex_init(&mutex_buf[i], NULL);
if(ret)
return 0; /* pthread_mutex_init failed */
}
#elif defined(HAVE_PROCESS_H)
for(i = 0; i < NUMT; i++) {
mutex_buf[i] = CreateMutex(0, FALSE, 0);
if(mutex_buf[i] == 0)
return 0; /* CreateMutex failed */
}
#endif /* HAVE_PTHREAD_H */
return 1; /* OK */
}
int Curl_polarsslthreadlock_thread_cleanup(void)
{
int i;
int ret;
if(!mutex_buf)
return 0; /* error, no threads locks defined */
#ifdef HAVE_PTHREAD_H
for(i = 0; i < NUMT; i++) {
ret = pthread_mutex_destroy(&mutex_buf[i]);
if(ret)
return 0; /* pthread_mutex_destroy failed */
}
#elif defined(HAVE_PROCESS_H)
for(i = 0; i < NUMT; i++) {
ret = CloseHandle(mutex_buf[i]);
if(!ret)
return 0; /* CloseHandle failed */
}
#endif /* HAVE_PTHREAD_H */
free(mutex_buf);
mutex_buf = NULL;
return 1; /* OK */
}
int Curl_polarsslthreadlock_lock_function(int n)
{
int ret;
#ifdef HAVE_PTHREAD_H
if(n < NUMT) {
ret = pthread_mutex_lock(&mutex_buf[n]);
if(ret) {
DEBUGF(fprintf(stderr,
"Error: polarsslthreadlock_lock_function failed\n"));
return 0; /* pthread_mutex_lock failed */
}
}
#elif defined(HAVE_PROCESS_H)
if(n < NUMT) {
ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0);
if(ret) {
DEBUGF(fprintf(stderr,
"Error: polarsslthreadlock_lock_function failed\n"));
return 0; /* pthread_mutex_lock failed */
}
}
#endif /* HAVE_PTHREAD_H */
return 1; /* OK */
}
int Curl_polarsslthreadlock_unlock_function(int n)
{
int ret;
#ifdef HAVE_PTHREAD_H
if(n < NUMT) {
ret = pthread_mutex_unlock(&mutex_buf[n]);
if(ret) {
DEBUGF(fprintf(stderr,
"Error: polarsslthreadlock_unlock_function failed\n"));
return 0; /* pthread_mutex_unlock failed */
}
}
#elif defined(HAVE_PROCESS_H)
if(n < NUMT) {
ret = ReleaseMutex(mutex_buf[n]);
if(!ret) {
DEBUGF(fprintf(stderr,
"Error: polarsslthreadlock_unlock_function failed\n"));
return 0; /* pthread_mutex_lock failed */
}
}
#endif /* HAVE_PTHREAD_H */
return 1; /* OK */
}
#endif /* USE_POLARSSL || USE_MBEDTLS */

View File

@@ -1,53 +0,0 @@
#ifndef HEADER_CURL_POLARSSL_THREADLOCK_H
#define HEADER_CURL_POLARSSL_THREADLOCK_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#if (defined USE_POLARSSL) || (defined USE_MBEDTLS)
#if defined(USE_THREADS_POSIX)
# define POLARSSL_MUTEX_T pthread_mutex_t
#elif defined(USE_THREADS_WIN32)
# define POLARSSL_MUTEX_T HANDLE
#endif
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
int Curl_polarsslthreadlock_thread_setup(void);
int Curl_polarsslthreadlock_thread_cleanup(void);
int Curl_polarsslthreadlock_lock_function(int n);
int Curl_polarsslthreadlock_unlock_function(int n);
#else
#define Curl_polarsslthreadlock_thread_setup() 1
#define Curl_polarsslthreadlock_thread_cleanup() 1
#define Curl_polarsslthreadlock_lock_function(x) 1
#define Curl_polarsslthreadlock_unlock_function(x) 1
#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
#endif /* USE_POLARSSL */
#endif /* HEADER_CURL_POLARSSL_THREADLOCK_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,74 +0,0 @@
#ifndef HEADER_CURL_SCHANNEL_H
#define HEADER_CURL_SCHANNEL_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al.
* Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
#ifdef USE_SCHANNEL
#include <schnlsp.h>
#include <schannel.h>
#include "curl_sspi.h"
#include "urldata.h"
extern const struct Curl_ssl Curl_ssl_schannel;
CURLcode verify_certificate(struct connectdata *conn, int sockindex);
/* structs to expose only in schannel.c and schannel_verify.c */
#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
struct curl_schannel_cred {
CredHandle cred_handle;
TimeStamp time_stamp;
int refcount;
};
struct curl_schannel_ctxt {
CtxtHandle ctxt_handle;
TimeStamp time_stamp;
};
struct ssl_backend_data {
struct curl_schannel_cred *cred;
struct curl_schannel_ctxt *ctxt;
SecPkgContext_StreamSizes stream_sizes;
size_t encdata_length, decdata_length;
size_t encdata_offset, decdata_offset;
unsigned char *encdata_buffer, *decdata_buffer;
/* encdata_is_incomplete: if encdata contains only a partial record that
can't be decrypted without another Curl_read_plain (that is, status is
SEC_E_INCOMPLETE_MESSAGE) then set this true. after Curl_read_plain writes
more bytes into encdata then set this back to false. */
bool encdata_is_incomplete;
unsigned long req_flags, ret_flags;
CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
bool recv_sspi_close_notify; /* true if connection closed by close_notify */
bool recv_connection_closed; /* true if connection closed, regardless how */
bool use_alpn; /* true if ALPN is used for this connection */
bool use_manual_cred_validation; /* true if manual cred validation is used */
};
#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */
#endif /* USE_SCHANNEL */
#endif /* HEADER_CURL_SCHANNEL_H */

View File

@@ -1,551 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de>
* Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
* Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
* Source file for SChannel-specific certificate verification. This code should
* only be invoked by code in schannel.c.
*/
#include "curl_setup.h"
#ifdef USE_SCHANNEL
#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
#ifndef USE_WINDOWS_SSPI
# error "Can't compile SCHANNEL support without SSPI."
#endif
#include "schannel.h"
#include "vtls.h"
#include "sendf.h"
#include "strerror.h"
#include "curl_multibyte.h"
#include "curl_printf.h"
#include "hostcheck.h"
#include "system_win32.h"
/* The last #include file should be: */
#include "curl_memory.h"
#include "memdebug.h"
#define BACKEND connssl->backend
#define MAX_CAFILE_SIZE 1048576 /* 1 MiB */
#define BEGIN_CERT "-----BEGIN CERTIFICATE-----\n"
#define END_CERT "\n-----END CERTIFICATE-----"
typedef struct {
DWORD cbSize;
HCERTSTORE hRestrictedRoot;
HCERTSTORE hRestrictedTrust;
HCERTSTORE hRestrictedOther;
DWORD cAdditionalStore;
HCERTSTORE *rghAdditionalStore;
DWORD dwFlags;
DWORD dwUrlRetrievalTimeout;
DWORD MaximumCachedCertificates;
DWORD CycleDetectionModulus;
HCERTSTORE hExclusiveRoot;
HCERTSTORE hExclusiveTrustedPeople;
} CERT_CHAIN_ENGINE_CONFIG_WIN7, *PCERT_CHAIN_ENGINE_CONFIG_WIN7;
static CURLcode add_certs_to_store(HCERTSTORE trust_store,
const char *ca_file,
struct connectdata *conn)
{
CURLcode result;
struct Curl_easy *data = conn->data;
HANDLE ca_file_handle = INVALID_HANDLE_VALUE;
LARGE_INTEGER file_size;
char *ca_file_buffer = NULL;
char *current_ca_file_ptr = NULL;
const TCHAR *ca_file_tstr = NULL;
size_t ca_file_bufsize = 0;
DWORD total_bytes_read = 0;
bool more_certs = 0;
int num_certs = 0;
size_t END_CERT_LEN;
ca_file_tstr = Curl_convert_UTF8_to_tchar(ca_file);
if(!ca_file_tstr) {
failf(data,
"schannel: invalid path name for CA file '%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
/*
* Read the CA file completely into memory before parsing it. This
* optimizes for the common case where the CA file will be relatively
* small ( < 1 MiB ).
*/
ca_file_handle = CreateFile(ca_file_tstr,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(ca_file_handle == INVALID_HANDLE_VALUE) {
failf(data,
"schannel: failed to open CA file '%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
if(!GetFileSizeEx(ca_file_handle, &file_size)) {
failf(data,
"schannel: failed to determine size of CA file '%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
if(file_size.QuadPart > MAX_CAFILE_SIZE) {
failf(data,
"schannel: CA file exceeds max size of %u bytes",
MAX_CAFILE_SIZE);
result = CURLE_OUT_OF_MEMORY;
goto cleanup;
}
ca_file_bufsize = (size_t)file_size.QuadPart;
ca_file_buffer = (char *)malloc(ca_file_bufsize + 1);
if(!ca_file_buffer) {
result = CURLE_OUT_OF_MEMORY;
goto cleanup;
}
result = CURLE_OK;
while(total_bytes_read < ca_file_bufsize) {
DWORD bytes_to_read = (DWORD)(ca_file_bufsize - total_bytes_read);
DWORD bytes_read = 0;
if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read,
bytes_to_read, &bytes_read, NULL)) {
failf(data,
"schannel: failed to read from CA file '%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
if(bytes_read == 0) {
/* Premature EOF -- adjust the bufsize to the new value */
ca_file_bufsize = total_bytes_read;
}
else {
total_bytes_read += bytes_read;
}
}
/* Null terminate the buffer */
ca_file_buffer[ca_file_bufsize] = '\0';
if(result != CURLE_OK) {
goto cleanup;
}
END_CERT_LEN = strlen(END_CERT);
more_certs = 1;
current_ca_file_ptr = ca_file_buffer;
while(more_certs && *current_ca_file_ptr != '\0') {
char *begin_cert_ptr = strstr(current_ca_file_ptr, BEGIN_CERT);
if(!begin_cert_ptr) {
more_certs = 0;
}
else {
char *end_cert_ptr = strstr(begin_cert_ptr, END_CERT);
if(!end_cert_ptr) {
failf(data,
"schannel: CA file '%s' is not correctly formatted",
ca_file);
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
else {
CERT_BLOB cert_blob;
CERT_CONTEXT *cert_context = NULL;
BOOL add_cert_result = FALSE;
DWORD actual_content_type = 0;
DWORD cert_size = (DWORD)
((end_cert_ptr + END_CERT_LEN) - begin_cert_ptr);
cert_blob.pbData = (BYTE *)begin_cert_ptr;
cert_blob.cbData = cert_size;
if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB,
&cert_blob,
CERT_QUERY_CONTENT_FLAG_CERT,
CERT_QUERY_FORMAT_FLAG_ALL,
0,
NULL,
&actual_content_type,
NULL,
NULL,
NULL,
&cert_context)) {
failf(data,
"schannel: failed to extract certificate from CA file "
"'%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
else {
current_ca_file_ptr = begin_cert_ptr + cert_size;
/* Sanity check that the cert_context object is the right type */
if(CERT_QUERY_CONTENT_CERT != actual_content_type) {
failf(data,
"schannel: unexpected content type '%d' when extracting "
"certificate from CA file '%s'",
actual_content_type, ca_file);
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
else {
add_cert_result =
CertAddCertificateContextToStore(trust_store,
cert_context,
CERT_STORE_ADD_ALWAYS,
NULL);
CertFreeCertificateContext(cert_context);
if(!add_cert_result) {
failf(data,
"schannel: failed to add certificate from CA file '%s'"
"to certificate store: %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
else {
num_certs++;
}
}
}
}
}
}
if(result == CURLE_OK) {
if(!num_certs) {
infof(data,
"schannel: did not add any certificates from CA file '%s'\n",
ca_file);
}
else {
infof(data,
"schannel: added %d certificate(s) from CA file '%s'\n",
num_certs, ca_file);
}
}
cleanup:
if(ca_file_handle != INVALID_HANDLE_VALUE) {
CloseHandle(ca_file_handle);
}
Curl_safefree(ca_file_buffer);
Curl_unicodefree(ca_file_tstr);
return result;
}
static CURLcode verify_host(struct Curl_easy *data,
CERT_CONTEXT *pCertContextServer,
const char * const conn_hostname)
{
CURLcode result = CURLE_PEER_FAILED_VERIFICATION;
TCHAR *cert_hostname_buff = NULL;
size_t cert_hostname_buff_index = 0;
DWORD len = 0;
DWORD actual_len = 0;
/* CertGetNameString will provide the 8-bit character string without
* any decoding */
DWORD name_flags = CERT_NAME_DISABLE_IE4_UTF8_FLAG;
#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
name_flags |= CERT_NAME_SEARCH_ALL_NAMES_FLAG;
#endif
/* Determine the size of the string needed for the cert hostname */
len = CertGetNameString(pCertContextServer,
CERT_NAME_DNS_TYPE,
name_flags,
NULL,
NULL,
0);
if(len == 0) {
failf(data,
"schannel: CertGetNameString() returned no "
"certificate name information");
result = CURLE_PEER_FAILED_VERIFICATION;
goto cleanup;
}
/* CertGetNameString guarantees that the returned name will not contain
* embedded null bytes. This appears to be undocumented behavior.
*/
cert_hostname_buff = (LPTSTR)malloc(len * sizeof(TCHAR));
actual_len = CertGetNameString(pCertContextServer,
CERT_NAME_DNS_TYPE,
name_flags,
NULL,
(LPTSTR) cert_hostname_buff,
len);
/* Sanity check */
if(actual_len != len) {
failf(data,
"schannel: CertGetNameString() returned certificate "
"name information of unexpected size");
result = CURLE_PEER_FAILED_VERIFICATION;
goto cleanup;
}
/* If HAVE_CERT_NAME_SEARCH_ALL_NAMES is available, the output
* will contain all DNS names, where each name is null-terminated
* and the last DNS name is double null-terminated. Due to this
* encoding, use the length of the buffer to iterate over all names.
*/
result = CURLE_PEER_FAILED_VERIFICATION;
while(cert_hostname_buff_index < len &&
cert_hostname_buff[cert_hostname_buff_index] != TEXT('\0') &&
result == CURLE_PEER_FAILED_VERIFICATION) {
char *cert_hostname;
/* Comparing the cert name and the connection hostname encoded as UTF-8
* is acceptable since both values are assumed to use ASCII
* (or some equivalent) encoding
*/
cert_hostname = Curl_convert_tchar_to_UTF8(
&cert_hostname_buff[cert_hostname_buff_index]);
if(!cert_hostname) {
result = CURLE_OUT_OF_MEMORY;
}
else {
int match_result;
match_result = Curl_cert_hostcheck(cert_hostname, conn_hostname);
if(match_result == CURL_HOST_MATCH) {
infof(data,
"schannel: connection hostname (%s) validated "
"against certificate name (%s)\n",
conn_hostname, cert_hostname);
result = CURLE_OK;
}
else {
size_t cert_hostname_len;
infof(data,
"schannel: connection hostname (%s) did not match "
"against certificate name (%s)\n",
conn_hostname, cert_hostname);
cert_hostname_len = _tcslen(
&cert_hostname_buff[cert_hostname_buff_index]);
/* Move on to next cert name */
cert_hostname_buff_index += cert_hostname_len + 1;
result = CURLE_PEER_FAILED_VERIFICATION;
}
Curl_unicodefree(cert_hostname);
}
}
if(result == CURLE_PEER_FAILED_VERIFICATION) {
failf(data,
"schannel: CertGetNameString() failed to match "
"connection hostname (%s) against server certificate names",
conn_hostname);
}
else if(result != CURLE_OK)
failf(data, "schannel: server certificate name verification failed");
cleanup:
Curl_unicodefree(cert_hostname_buff);
return result;
}
CURLcode verify_certificate(struct connectdata *conn, int sockindex)
{
SECURITY_STATUS status;
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode result = CURLE_OK;
CERT_CONTEXT *pCertContextServer = NULL;
const CERT_CHAIN_CONTEXT *pChainContext = NULL;
HCERTCHAINENGINE cert_chain_engine = NULL;
HCERTSTORE trust_store = NULL;
const char * const conn_hostname = SSL_IS_PROXY() ?
conn->http_proxy.host.name :
conn->host.name;
status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&pCertContextServer);
if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
failf(data, "schannel: Failed to read remote certificate context: %s",
Curl_sspi_strerror(conn, status));
result = CURLE_PEER_FAILED_VERIFICATION;
}
if(result == CURLE_OK && SSL_CONN_CONFIG(CAfile) &&
BACKEND->use_manual_cred_validation) {
/*
* Create a chain engine that uses the certificates in the CA file as
* trusted certificates. This is only supported on Windows 7+.
*/
if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_LESS_THAN)) {
failf(data, "schannel: this version of Windows is too old to support "
"certificate verification via CA bundle file.");
result = CURLE_SSL_CACERT_BADFILE;
}
else {
/* Open the certificate store */
trust_store = CertOpenStore(CERT_STORE_PROV_MEMORY,
0,
(HCRYPTPROV)NULL,
CERT_STORE_CREATE_NEW_FLAG,
NULL);
if(!trust_store) {
failf(data, "schannel: failed to create certificate store: %s",
Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
}
else {
result = add_certs_to_store(trust_store, SSL_CONN_CONFIG(CAfile),
conn);
}
}
if(result == CURLE_OK) {
CERT_CHAIN_ENGINE_CONFIG_WIN7 engine_config;
BOOL create_engine_result;
memset(&engine_config, 0, sizeof(engine_config));
engine_config.cbSize = sizeof(engine_config);
engine_config.hExclusiveRoot = trust_store;
/* CertCreateCertificateChainEngine will check the expected size of the
* CERT_CHAIN_ENGINE_CONFIG structure and fail if the specified size
* does not match the expected size. When this occurs, it indicates that
* CAINFO is not supported on the version of Windows in use.
*/
create_engine_result =
CertCreateCertificateChainEngine(
(CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine);
if(!create_engine_result) {
failf(data,
"schannel: failed to create certificate chain engine: %s",
Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
}
}
}
if(result == CURLE_OK) {
CERT_CHAIN_PARA ChainPara;
memset(&ChainPara, 0, sizeof(ChainPara));
ChainPara.cbSize = sizeof(ChainPara);
if(!CertGetCertificateChain(cert_chain_engine,
pCertContextServer,
NULL,
pCertContextServer->hCertStore,
&ChainPara,
(data->set.ssl.no_revoke ? 0 :
CERT_CHAIN_REVOCATION_CHECK_CHAIN),
NULL,
&pChainContext)) {
failf(data, "schannel: CertGetCertificateChain failed: %s",
Curl_sspi_strerror(conn, GetLastError()));
pChainContext = NULL;
result = CURLE_PEER_FAILED_VERIFICATION;
}
if(result == CURLE_OK) {
CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
if(dwTrustErrorMask) {
if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_REVOKED");
else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_PARTIAL_CHAIN");
else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_UNTRUSTED_ROOT");
else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_NOT_TIME_VALID");
else if(dwTrustErrorMask & CERT_TRUST_REVOCATION_STATUS_UNKNOWN)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_REVOCATION_STATUS_UNKNOWN");
else
failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
dwTrustErrorMask);
result = CURLE_PEER_FAILED_VERIFICATION;
}
}
}
if(result == CURLE_OK) {
if(SSL_CONN_CONFIG(verifyhost)) {
result = verify_host(conn->data, pCertContextServer, conn_hostname);
}
}
if(cert_chain_engine) {
CertFreeCertificateChainEngine(cert_chain_engine);
}
if(trust_store) {
CertCloseStore(trust_store, 0);
}
if(pChainContext)
CertFreeCertificateChain(pChainContext);
if(pCertContextServer)
CertFreeCertificateContext(pCertContextServer);
return result;
}
#endif /* USE_SCHANNEL */

File diff suppressed because it is too large Load Diff

View File

@@ -1,275 +0,0 @@
#ifndef HEADER_CURL_VTLS_H
#define HEADER_CURL_VTLS_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "curl_setup.h"
struct connectdata;
struct ssl_connect_data;
#define SSLSUPP_CA_PATH (1<<0) /* supports CAPATH */
#define SSLSUPP_CERTINFO (1<<1) /* supports CURLOPT_CERTINFO */
#define SSLSUPP_PINNEDPUBKEY (1<<2) /* supports CURLOPT_PINNEDPUBLICKEY */
#define SSLSUPP_SSL_CTX (1<<3) /* supports CURLOPT_SSL_CTX */
#define SSLSUPP_HTTPS_PROXY (1<<4) /* supports access via HTTPS proxies */
struct Curl_ssl {
/*
* This *must* be the first entry to allow returning the list of available
* backends in curl_global_sslset().
*/
curl_ssl_backend info;
unsigned int supports; /* bitfield, see above */
size_t sizeof_ssl_backend_data;
int (*init)(void);
void (*cleanup)(void);
size_t (*version)(char *buffer, size_t size);
int (*check_cxn)(struct connectdata *cxn);
int (*shutdown)(struct connectdata *conn, int sockindex);
bool (*data_pending)(const struct connectdata *conn,
int connindex);
/* return 0 if a find random is filled in */
CURLcode (*random)(struct Curl_easy *data, unsigned char *entropy,
size_t length);
bool (*cert_status_request)(void);
CURLcode (*connect)(struct connectdata *conn, int sockindex);
CURLcode (*connect_nonblocking)(struct connectdata *conn, int sockindex,
bool *done);
void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info);
void (*close_one)(struct connectdata *conn, int sockindex);
void (*close_all)(struct Curl_easy *data);
void (*session_free)(void *ptr);
CURLcode (*set_engine)(struct Curl_easy *data, const char *engine);
CURLcode (*set_engine_default)(struct Curl_easy *data);
struct curl_slist *(*engines_list)(struct Curl_easy *data);
bool (*false_start)(void);
CURLcode (*md5sum)(unsigned char *input, size_t inputlen,
unsigned char *md5sum, size_t md5sumlen);
CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen,
unsigned char *sha256sum, size_t sha256sumlen);
};
#ifdef USE_SSL
extern const struct Curl_ssl *Curl_ssl;
#endif
int Curl_none_init(void);
void Curl_none_cleanup(void);
int Curl_none_shutdown(struct connectdata *conn, int sockindex);
int Curl_none_check_cxn(struct connectdata *conn);
CURLcode Curl_none_random(struct Curl_easy *data, unsigned char *entropy,
size_t length);
void Curl_none_close_all(struct Curl_easy *data);
void Curl_none_session_free(void *ptr);
bool Curl_none_data_pending(const struct connectdata *conn, int connindex);
bool Curl_none_cert_status_request(void);
CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine);
CURLcode Curl_none_set_engine_default(struct Curl_easy *data);
struct curl_slist *Curl_none_engines_list(struct Curl_easy *data);
bool Curl_none_false_start(void);
CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
unsigned char *md5sum, size_t md5len);
#include "openssl.h" /* OpenSSL versions */
#include "gtls.h" /* GnuTLS versions */
#include "nssg.h" /* NSS versions */
#include "gskit.h" /* Global Secure ToolKit versions */
#include "polarssl.h" /* PolarSSL versions */
#include "axtls.h" /* axTLS versions */
#include "cyassl.h" /* CyaSSL versions */
#include "schannel.h" /* Schannel SSPI version */
#include "darwinssl.h" /* SecureTransport (Darwin) version */
#include "mbedtls.h" /* mbedTLS versions */
#ifndef MAX_PINNED_PUBKEY_SIZE
#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
#endif
#ifndef MD5_DIGEST_LENGTH
#ifndef LIBWOLFSSL_VERSION_HEX /* because WolfSSL borks this */
#define MD5_DIGEST_LENGTH 16 /* fixed size */
#endif
#endif
#ifndef CURL_SHA256_DIGEST_LENGTH
#define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */
#endif
/* see https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */
#define ALPN_HTTP_1_1_LENGTH 8
#define ALPN_HTTP_1_1 "http/1.1"
/* set of helper macros for the backends to access the correct fields. For the
proxy or for the remote host - to properly support HTTPS proxy */
#define SSL_IS_PROXY() (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \
ssl_connection_complete != conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \
CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
#define SSL_SET_OPTION(var) (SSL_IS_PROXY() ? data->set.proxy_ssl.var : \
data->set.ssl.var)
#define SSL_CONN_CONFIG(var) (SSL_IS_PROXY() ? \
conn->proxy_ssl_config.var : conn->ssl_config.var)
bool Curl_ssl_config_matches(struct ssl_primary_config* data,
struct ssl_primary_config* needle);
bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
struct ssl_primary_config *dest);
void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc);
int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
int Curl_ssl_backend(void);
#ifdef USE_SSL
int Curl_ssl_init(void);
void Curl_ssl_cleanup(void);
CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex);
CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn,
int sockindex,
bool *done);
/* tell the SSL stuff to close down all open information regarding
connections (and thus session ID caching etc) */
void Curl_ssl_close_all(struct Curl_easy *data);
void Curl_ssl_close(struct connectdata *conn, int sockindex);
CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex);
CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine);
/* Sets engine as default for all SSL operations */
CURLcode Curl_ssl_set_engine_default(struct Curl_easy *data);
struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data);
/* init the SSL session ID cache */
CURLcode Curl_ssl_initsessions(struct Curl_easy *, size_t);
size_t Curl_ssl_version(char *buffer, size_t size);
bool Curl_ssl_data_pending(const struct connectdata *conn,
int connindex);
int Curl_ssl_check_cxn(struct connectdata *conn);
/* Certificate information list handling. */
void Curl_ssl_free_certinfo(struct Curl_easy *data);
CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num);
CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, int certnum,
const char *label, const char *value,
size_t valuelen);
CURLcode Curl_ssl_push_certinfo(struct Curl_easy *data, int certnum,
const char *label, const char *value);
/* Functions to be used by SSL library adaptation functions */
/* Lock session cache mutex.
* Call this before calling other Curl_ssl_*session* functions
* Caller should unlock this mutex as soon as possible, as it may block
* other SSL connection from making progress.
* The purpose of explicitly locking SSL session cache data is to allow
* individual SSL engines to manage session lifetime in their specific way.
*/
void Curl_ssl_sessionid_lock(struct connectdata *conn);
/* Unlock session cache mutex */
void Curl_ssl_sessionid_unlock(struct connectdata *conn);
/* extract a session ID
* Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
* Caller must make sure that the ownership of returned sessionid object
* is properly taken (e.g. its refcount is incremented
* under sessionid mutex).
*/
bool Curl_ssl_getsessionid(struct connectdata *conn,
void **ssl_sessionid,
size_t *idsize, /* set 0 if unknown */
int sockindex);
/* add a new session ID
* Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
* Caller must ensure that it has properly shared ownership of this sessionid
* object with cache (e.g. incrementing refcount on success)
*/
CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
void *ssl_sessionid,
size_t idsize,
int sockindex);
/* Kill a single session ID entry in the cache
* Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
* This will call engine-specific curlssl_session_free function, which must
* take sessionid object ownership from sessionid cache
* (e.g. decrement refcount).
*/
void Curl_ssl_kill_session(struct curl_ssl_session *session);
/* delete a session from the cache
* Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
* This will call engine-specific curlssl_session_free function, which must
* take sessionid object ownership from sessionid cache
* (e.g. decrement refcount).
*/
void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
/* get N random bytes into the buffer */
CURLcode Curl_ssl_random(struct Curl_easy *data, unsigned char *buffer,
size_t length);
CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
size_t tmplen,
unsigned char *md5sum, /* output */
size_t md5len);
/* Check pinned public key. */
CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
const char *pinnedpubkey,
const unsigned char *pubkey, size_t pubkeylen);
bool Curl_ssl_cert_status_request(void);
bool Curl_ssl_false_start(void);
#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
#else
/* When SSL support is not present, just define away these function calls */
#define Curl_ssl_init() 1
#define Curl_ssl_cleanup() Curl_nop_stmt
#define Curl_ssl_connect(x,y) CURLE_NOT_BUILT_IN
#define Curl_ssl_close_all(x) Curl_nop_stmt
#define Curl_ssl_close(x,y) Curl_nop_stmt
#define Curl_ssl_shutdown(x,y) CURLE_NOT_BUILT_IN
#define Curl_ssl_set_engine(x,y) CURLE_NOT_BUILT_IN
#define Curl_ssl_set_engine_default(x) CURLE_NOT_BUILT_IN
#define Curl_ssl_engines_list(x) NULL
#define Curl_ssl_send(a,b,c,d,e) -1
#define Curl_ssl_recv(a,b,c,d,e) -1
#define Curl_ssl_initsessions(x,y) CURLE_OK
#define Curl_ssl_version(x,y) 0
#define Curl_ssl_data_pending(x,y) 0
#define Curl_ssl_check_cxn(x) 0
#define Curl_ssl_free_certinfo(x) Curl_nop_stmt
#define Curl_ssl_connect_nonblocking(x,y,z) CURLE_NOT_BUILT_IN
#define Curl_ssl_kill_session(x) Curl_nop_stmt
#define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN)
#define Curl_ssl_cert_status_request() FALSE
#define Curl_ssl_false_start() FALSE
#endif
#endif /* HEADER_CURL_VTLS_H */