#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
#define HAVE_ERR_REMOVE_THREAD_STATE 1
-#if (OPENSSL_VERSION_NUMBER >= 0x10100004L)
-/* OpenSSL 1.1.0-pre4 removed the argument! */
-#define HAVE_ERR_REMOVE_THREAD_STATE_NOARG 1
-#endif
#endif
#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \
!defined(LIBRESSL_VERSION_NUMBER)
-#define SSLeay_add_ssl_algorithms() SSL_library_init()
#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
#define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */
#define HAVE_OPAQUE_EVP_PKEY 1 /* since 1.1.0 -pre3 */
+#define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */
+#define CONST_EXTS const
+#define CONST_ASN1_BIT_STRING const
+#else
+/* For OpenSSL before 1.1.0 */
+#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x)
+#define X509_get0_notBefore(x) X509_get_notBefore(x)
+#define X509_get0_notAfter(x) X509_get_notAfter(x)
+#define CONST_EXTS /* nope */
+#define CONST_ASN1_BIT_STRING /* nope */
+#define OpenSSL_version_num() SSLeay()
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \
#define HAVE_X509_GET0_SIGNATURE 1
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10002003L && \
+ OPENSSL_VERSION_NUMBER <= 0x10002FFFL && \
+ !defined(OPENSSL_NO_COMP)
+#define HAVE_SSL_COMP_FREE_COMPRESSION_METHODS 1
+#endif
+
#if (OPENSSL_VERSION_NUMBER < 0x0090808fL)
/* not present in older OpenSSL */
#define OPENSSL_load_builtin_modules(x)
}
#endif
-static int ossl_seed(struct SessionHandle *data)
+static int ossl_seed(struct Curl_easy *data)
{
char *buf = data->state.buffer; /* point to the big buffer */
int nread=0;
return nread;
}
-static void Curl_ossl_seed(struct SessionHandle *data)
+static void Curl_ossl_seed(struct Curl_easy *data)
{
/* we have the "SSL is seeded" boolean static to prevent multiple
time-consuming seedings in vain */
char *key_file,
const char *key_type)
{
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
int file_type = do_file_type(cert_type);
/* Return error string for last OpenSSL error
*/
-static char *SSL_strerror(unsigned long error, char *buf, size_t size)
+static char *ossl_strerror(unsigned long error, char *buf, size_t size)
{
/* OpenSSL 0.9.6 and later has a function named
ERR_error_string_n() that takes the size of the buffer as a
CONF_MFLAGS_DEFAULT_SECTION|
CONF_MFLAGS_IGNORE_MISSING_FILE);
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+ !defined(LIBRESSL_VERSION_NUMBER)
+ /* OpenSSL 1.1.0+ takes care of initialization itself */
+#else
/* Lets get nice error messages */
SSL_load_error_strings();
return 0;
OpenSSL_add_all_algorithms();
+#endif
return 1;
}
/* Global cleanup */
void Curl_ossl_cleanup(void)
{
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+ !defined(LIBRESSL_VERSION_NUMBER)
+ /* OpenSSL 1.1 deprecates all these cleanup functions and
+ turns them into no-ops in OpenSSL 1.0 compatibility mode */
+#else
/* Free ciphers and digests lists */
EVP_cleanup();
ERR_free_strings();
/* Free thread local error state, destroying hash upon zero refcount */
-#ifdef HAVE_ERR_REMOVE_THREAD_STATE_NOARG
- ERR_remove_thread_state();
-#elif defined(HAVE_ERR_REMOVE_THREAD_STATE)
+#ifdef HAVE_ERR_REMOVE_THREAD_STATE
ERR_remove_thread_state(NULL);
#else
ERR_remove_state(0);
/* Free all memory allocated by all configuration modules */
CONF_modules_free();
+
+#ifdef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS
+ SSL_COMP_free_compression_methods();
+#endif
+#endif
}
/*
- * This function uses SSL_peek to determine connection status.
+ * This function is used to determine connection status.
*
* Return codes:
* 1 means the connection is still in place
*/
int Curl_ossl_check_cxn(struct connectdata *conn)
{
- int rc;
+ /* SSL_peek takes data out of the raw recv buffer without peeking so we use
+ recv MSG_PEEK instead. Bug #795 */
+#ifdef MSG_PEEK
char buf;
-
- rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1);
- if(rc > 0)
- return 1; /* connection still in place */
-
- if(rc == 0)
+ ssize_t nread;
+ nread = recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
+ (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK);
+ if(nread == 0)
return 0; /* connection has been closed */
-
+ else if(nread == 1)
+ return 1; /* connection still in place */
+ else if(nread == -1) {
+ int err = SOCKERRNO;
+ if(err == EINPROGRESS ||
+#if defined(EAGAIN) && (EAGAIN != EWOULDBLOCK)
+ err == EAGAIN ||
+#endif
+ err == EWOULDBLOCK)
+ return 1; /* connection still in place */
+ if(err == ECONNRESET ||
+#ifdef ECONNABORTED
+ err == ECONNABORTED ||
+#endif
+#ifdef ENETDOWN
+ err == ENETDOWN ||
+#endif
+#ifdef ENETRESET
+ err == ENETRESET ||
+#endif
+#ifdef ESHUTDOWN
+ err == ESHUTDOWN ||
+#endif
+#ifdef ETIMEDOUT
+ err == ETIMEDOUT ||
+#endif
+ err == ENOTCONN)
+ return 0; /* connection has been closed */
+ }
+#endif
return -1; /* connection status unknown */
}
/* Selects an OpenSSL crypto engine
*/
-CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine)
+CURLcode Curl_ossl_set_engine(struct Curl_easy *data, const char *engine)
{
#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
ENGINE *e;
ENGINE_free(e);
failf(data, "Failed to initialise SSL Engine '%s':\n%s",
- engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf)));
+ engine, ossl_strerror(ERR_get_error(), buf, sizeof(buf)));
return CURLE_SSL_ENGINE_INITFAILED;
}
data->state.engine = e;
/* Sets engine as default for all SSL operations
*/
-CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data)
+CURLcode Curl_ossl_set_engine_default(struct Curl_easy *data)
{
#ifdef HAVE_OPENSSL_ENGINE_H
if(data->state.engine) {
/* Return list of OpenSSL crypto engine names.
*/
-struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
+struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data)
{
struct curl_slist *list = NULL;
#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
{
int retval = 0;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- struct SessionHandle *data = conn->data;
- char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
- to be at least 120 bytes long. */
+ struct Curl_easy *data = conn->data;
+ char buf[256]; /* We will use this for the OpenSSL error buffer, so it has
+ to be at least 256 bytes long. */
unsigned long sslerror;
ssize_t nread;
int buffsize;
/* openssl/ssl.h says "look at error stack/return value/errno" */
sslerror = ERR_get_error();
failf(conn->data, OSSL_PACKAGE " SSL read: %s, errno %d",
- ERR_error_string(sslerror, buf),
+ ossl_strerror(sslerror, buf, sizeof(buf)),
SOCKERRNO);
done = 1;
break;
* This function is called when the 'data' struct is going away. Close
* down everything and free all resources!
*/
-void Curl_ossl_close_all(struct SessionHandle *data)
+void Curl_ossl_close_all(struct Curl_easy *data)
{
#ifdef HAVE_OPENSSL_ENGINE_H
if(data->state.engine) {
bool matched = FALSE;
int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
size_t addrlen = 0;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
STACK_OF(GENERAL_NAME) *altnames;
#ifdef ENABLE_IPV6
struct in6_addr addr;
struct in_addr addr;
#endif
CURLcode result = CURLE_OK;
+ bool dNSName = FALSE; /* if a dNSName field exists in the cert */
+ bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
#ifdef ENABLE_IPV6
if(conn->bits.ipv6_ip &&
if(altnames) {
int numalts;
int i;
+ bool dnsmatched = FALSE;
+ bool ipmatched = FALSE;
/* get amount of alternatives, RFC2459 claims there MUST be at least
one, but we don't depend on it... */
numalts = sk_GENERAL_NAME_num(altnames);
- /* loop through all alternatives while none has matched */
- for(i=0; (i<numalts) && !matched; i++) {
+ /* loop through all alternatives - until a dnsmatch */
+ for(i=0; (i < numalts) && !dnsmatched; i++) {
/* get a handle to alternative name number i */
const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
+ if(check->type == GEN_DNS)
+ dNSName = TRUE;
+ else if(check->type == GEN_IPADD)
+ iPAddress = TRUE;
+
/* only check alternatives of the same type the target is */
if(check->type == target) {
/* get data and length */
- const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
+ const char *altptr = (char *)ASN1_STRING_get0_data(check->d.ia5);
size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
switch(target) {
/* if this isn't true, there was an embedded zero in the name
string and we cannot match it. */
Curl_cert_hostcheck(altptr, conn->host.name)) {
- matched = TRUE;
+ dnsmatched = TRUE;
infof(data,
" subjectAltName: host \"%s\" matched cert's \"%s\"\n",
conn->host.dispname, altptr);
/* compare alternative IP address if the data chunk is the same size
our server IP address is */
if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) {
- matched = TRUE;
+ ipmatched = TRUE;
infof(data,
" subjectAltName: host \"%s\" matched cert's IP address!\n",
conn->host.dispname);
}
}
GENERAL_NAMES_free(altnames);
+
+ if(dnsmatched || ipmatched)
+ matched = TRUE;
}
if(matched)
/* an alternative name matched */
;
- else if(altnames) {
- /* an alternative name field existed, but didn't match and then we MUST
- fail */
+ else if(dNSName || iPAddress) {
infof(data, " subjectAltName does not match %s\n", conn->host.dispname);
failf(data, "SSL: no alternative certificate subject name matches "
"target host name '%s'", conn->host.dispname);
if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
j = ASN1_STRING_length(tmp);
if(j >= 0) {
- peer_CN = OPENSSL_malloc(j+1);
+ peer_CN = malloc(j+1);
if(peer_CN) {
- memcpy(peer_CN, ASN1_STRING_data(tmp), j);
+ memcpy(peer_CN, ASN1_STRING_get0_data(tmp), j);
peer_CN[j] = '\0';
}
}
CURLcode rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
/* Curl_convert_from_utf8 calls failf if unsuccessful */
if(rc) {
- OPENSSL_free(peer_CN);
+ free(peer_CN);
return rc;
}
}
infof(data, " common name: %s (matched)\n", peer_CN);
}
if(peer_CN)
- OPENSSL_free(peer_CN);
+ free(peer_CN);
}
return result;
int i, ocsp_status;
const unsigned char *p;
CURLcode result = CURLE_OK;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
OCSP_RESPONSE *rsp = NULL;
OCSP_BASICRESP *br = NULL;
const void *buf, size_t len, SSL *ssl,
void *userp)
{
- struct SessionHandle *data;
+ struct Curl_easy *data;
const char *msg_name, *tls_rt_name;
char ssl_buf[1024];
char unknown[32];
{
CURLcode result = CURLE_OK;
char *ciphers;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
SSL_METHOD_QUAL SSL_METHOD *req_method = NULL;
- void *ssl_sessionid = NULL;
X509_LOOKUP *lookup = NULL;
curl_socket_t sockfd = conn->sock[sockindex];
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
SSL_CTX_set_options(connssl->ctx, ctx_options);
#ifdef HAS_NPN
- if(data->set.ssl_enable_npn)
+ if(conn->bits.tls_enable_npn)
SSL_CTX_set_next_proto_select_cb(connssl->ctx, select_next_proto_cb, conn);
#endif
#ifdef HAS_ALPN
- if(data->set.ssl_enable_alpn) {
+ if(conn->bits.tls_enable_alpn) {
int cur = 0;
unsigned char protocols[128];
#endif
/* Check if there's a cached ID we can/should use here! */
- if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
- /* we got a session id, use it! */
- if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
- failf(data, "SSL: SSL_set_session failed: %s",
- ERR_error_string(ERR_get_error(), NULL));
- return CURLE_SSL_CONNECT_ERROR;
+ if(conn->ssl_config.sessionid) {
+ void *ssl_sessionid = NULL;
+
+ Curl_ssl_sessionid_lock(conn);
+ if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) {
+ /* we got a session id, use it! */
+ if(!SSL_set_session(connssl->handle, ssl_sessionid)) {
+ Curl_ssl_sessionid_unlock(conn);
+ failf(data, "SSL: SSL_set_session failed: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ return CURLE_SSL_CONNECT_ERROR;
+ }
+ /* Informational message */
+ infof (data, "SSL re-using session ID\n");
}
- /* Informational message */
- infof (data, "SSL re-using session ID\n");
+ Curl_ssl_sessionid_unlock(conn);
}
/* pass the raw socket into the SSL layers */
static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
{
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
int err;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
lerr = SSL_get_verify_result(connssl->handle);
if(lerr != X509_V_OK) {
+ data->set.ssl.certverifyresult = lerr;
snprintf(error_buffer, sizeof(error_buffer),
"SSL certificate problem: %s",
X509_verify_cert_error_string(lerr));
}
else {
result = CURLE_SSL_CONNECT_ERROR;
- SSL_strerror(errdetail, error_buffer, sizeof(error_buffer));
+ ossl_strerror(errdetail, error_buffer, sizeof(error_buffer));
}
/* detail is already set to the SSL error above */
/* Sets data and len to negotiated protocol, len is 0 if no protocol was
* negotiated
*/
- if(data->set.ssl_enable_alpn) {
+ if(conn->bits.tls_enable_alpn) {
const unsigned char* neg_protocol;
unsigned int len;
SSL_get0_alpn_selected(connssl->handle, &neg_protocol, &len);
break; \
} WHILE_FALSE
-static void pubkey_show(struct SessionHandle *data,
+static void pubkey_show(struct Curl_easy *data,
BIO *mem,
int num,
const char *type,
const char *name,
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ const
+#endif
BIGNUM *bn)
{
char *ptr;
snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
- BN_print(mem, bn);
+ if(bn)
+ BN_print(mem, bn);
push_certinfo(namebuf, num);
}
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#define print_pubkey_BN(_type, _name, _num) \
+ pubkey_show(data, mem, _num, #_type, #_name, _name)
+
+#else
#define print_pubkey_BN(_type, _name, _num) \
do { \
if(_type->_name) { \
pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
} \
} WHILE_FALSE
+#endif
-static int X509V3_ext(struct SessionHandle *data,
+static int X509V3_ext(struct Curl_easy *data,
int certnum,
- STACK_OF(X509_EXTENSION) *exts)
+ CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
{
int i;
size_t j;
CURLcode result;
STACK_OF(X509) *sk;
int i;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
int numcerts;
BIO *mem;
EVP_PKEY *pubkey=NULL;
int j;
char *ptr;
- ASN1_BIT_STRING *psig;
+ CONST_ASN1_BIT_STRING ASN1_BIT_STRING *psig = NULL;
X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
push_certinfo("Subject", i);
#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
{
- X509_ALGOR *palg;
+ const X509_ALGOR *palg = NULL;
ASN1_STRING *a = ASN1_STRING_new();
if(a) {
X509_get0_signature(&psig, &palg, x);
X509_signature_print(mem, palg, a);
ASN1_STRING_free(a);
- }
- i2a_ASN1_OBJECT(mem, palg->algorithm);
- push_certinfo("Public Key Algorithm", i);
+ if(palg) {
+ i2a_ASN1_OBJECT(mem, palg->algorithm);
+ push_certinfo("Public Key Algorithm", i);
+ }
+ }
X509V3_ext(data, i, X509_get0_extensions(x));
}
#else
}
#endif
- ASN1_TIME_print(mem, X509_get_notBefore(x));
+ ASN1_TIME_print(mem, X509_get0_notBefore(x));
push_certinfo("Start date", i);
- ASN1_TIME_print(mem, X509_get_notAfter(x));
+ ASN1_TIME_print(mem, X509_get0_notAfter(x));
push_certinfo("Expire date", i);
pubkey = X509_get_pubkey(x);
#else
rsa = pubkey->pkey.rsa;
#endif
+
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ {
+ const BIGNUM *n;
+ const BIGNUM *e;
+ const BIGNUM *d;
+ const BIGNUM *p;
+ const BIGNUM *q;
+ const BIGNUM *dmp1;
+ const BIGNUM *dmq1;
+ const BIGNUM *iqmp;
+
+ RSA_get0_key(rsa, &n, &e, &d);
+ RSA_get0_factors(rsa, &p, &q);
+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+ BN_print(mem, n);
+ push_certinfo("RSA Public Key", i);
+ print_pubkey_BN(rsa, n, i);
+ print_pubkey_BN(rsa, e, i);
+ print_pubkey_BN(rsa, d, i);
+ print_pubkey_BN(rsa, p, i);
+ print_pubkey_BN(rsa, q, i);
+ print_pubkey_BN(rsa, dmp1, i);
+ print_pubkey_BN(rsa, dmq1, i);
+ print_pubkey_BN(rsa, iqmp, i);
+ }
+#else
BIO_printf(mem, "%d", BN_num_bits(rsa->n));
push_certinfo("RSA Public Key", i);
-
print_pubkey_BN(rsa, n, i);
print_pubkey_BN(rsa, e, i);
print_pubkey_BN(rsa, d, i);
print_pubkey_BN(rsa, dmp1, i);
print_pubkey_BN(rsa, dmq1, i);
print_pubkey_BN(rsa, iqmp, i);
+#endif
+
break;
}
case EVP_PKEY_DSA:
#else
dsa = pubkey->pkey.dsa;
#endif
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ {
+ const BIGNUM *p;
+ const BIGNUM *q;
+ const BIGNUM *g;
+ const BIGNUM *priv_key;
+ const BIGNUM *pub_key;
+
+ DSA_get0_pqg(dsa, &p, &q, &g);
+ DSA_get0_key(dsa, &pub_key, &priv_key);
+
+ print_pubkey_BN(dsa, p, i);
+ print_pubkey_BN(dsa, q, i);
+ print_pubkey_BN(dsa, g, i);
+ print_pubkey_BN(dsa, priv_key, i);
+ print_pubkey_BN(dsa, pub_key, i);
+ }
+#else
print_pubkey_BN(dsa, p, i);
print_pubkey_BN(dsa, q, i);
print_pubkey_BN(dsa, g, i);
print_pubkey_BN(dsa, priv_key, i);
print_pubkey_BN(dsa, pub_key, i);
+#endif
break;
}
case EVP_PKEY_DH:
#else
dh = pubkey->pkey.dh;
#endif
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+ {
+ const BIGNUM *p;
+ const BIGNUM *q;
+ const BIGNUM *g;
+ const BIGNUM *priv_key;
+ const BIGNUM *pub_key;
+ DH_get0_pqg(dh, &p, &q, &g);
+ DH_get0_key(dh, &pub_key, &priv_key);
+ print_pubkey_BN(dh, p, i);
+ print_pubkey_BN(dh, q, i);
+ print_pubkey_BN(dh, g, i);
+ print_pubkey_BN(dh, priv_key, i);
+ print_pubkey_BN(dh, pub_key, i);
+ }
+#else
print_pubkey_BN(dh, p, i);
print_pubkey_BN(dh, g, i);
print_pubkey_BN(dh, priv_key, i);
print_pubkey_BN(dh, pub_key, i);
+#endif
break;
}
#if 0
EVP_PKEY_free(pubkey);
}
- for(j = 0; j < psig->length; j++)
- BIO_printf(mem, "%02x:", psig->data[j]);
- push_certinfo("Signature", i);
+ if(psig) {
+ for(j = 0; j < psig->length; j++)
+ BIO_printf(mem, "%02x:", psig->data[j]);
+ push_certinfo("Signature", i);
+ }
PEM_write_bio_X509(mem, x);
push_certinfo("Cert", i);
* Heavily modified from:
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
*/
-static CURLcode pkp_pin_peer_pubkey(struct SessionHandle *data, X509* cert,
+static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
const char *pinnedpubkey)
{
/* Scratch */
break; /* failed */
/* https://www.openssl.org/docs/crypto/buffer.html */
- buff1 = temp = OPENSSL_malloc(len1);
+ buff1 = temp = malloc(len1);
if(!buff1)
break; /* failed */
/* https://www.openssl.org/docs/crypto/buffer.html */
if(buff1)
- OPENSSL_free(buff1);
+ free(buff1);
return result;
}
CURLcode result = CURLE_OK;
int rc;
long lerr, len;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
X509 *issuer;
FILE *fp;
char *buffer = data->state.buffer;
buffer, BUFSIZE);
infof(data, " subject: %s\n", rc?"[NONE]":buffer);
- ASN1_TIME_print(mem, X509_get_notBefore(connssl->server_cert));
+ ASN1_TIME_print(mem, X509_get0_notBefore(connssl->server_cert));
len = BIO_get_mem_data(mem, (char **) &ptr);
infof(data, " start date: %.*s\n", len, ptr);
rc = BIO_reset(mem);
- ASN1_TIME_print(mem, X509_get_notAfter(connssl->server_cert));
+ ASN1_TIME_print(mem, X509_get0_notAfter(connssl->server_cert));
len = BIO_get_mem_data(mem, (char **) &ptr);
infof(data, " expire date: %.*s\n", len, ptr);
rc = BIO_reset(mem);
static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
{
CURLcode result = CURLE_OK;
- void *old_ssl_sessionid = NULL;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- bool incache;
- SSL_SESSION *our_ssl_sessionid;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
- our_ssl_sessionid = SSL_get1_session(connssl->handle);
+ if(conn->ssl_config.sessionid) {
+ bool incache;
+ SSL_SESSION *our_ssl_sessionid;
+ void *old_ssl_sessionid = NULL;
- /* SSL_get1_session() will increment the reference count and the session
- will stay in memory until explicitly freed with SSL_SESSION_free(3),
- regardless of its state. */
+ our_ssl_sessionid = SSL_get1_session(connssl->handle);
- incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
- if(incache) {
- if(old_ssl_sessionid != our_ssl_sessionid) {
- infof(data, "old SSL session ID is stale, removing\n");
- Curl_ssl_delsessionid(conn, old_ssl_sessionid);
- incache = FALSE;
+ /* SSL_get1_session() will increment the reference count and the session
+ will stay in memory until explicitly freed with SSL_SESSION_free(3),
+ regardless of its state. */
+
+ Curl_ssl_sessionid_lock(conn);
+ incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL));
+ if(incache) {
+ if(old_ssl_sessionid != our_ssl_sessionid) {
+ infof(data, "old SSL session ID is stale, removing\n");
+ Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+ incache = FALSE;
+ }
}
- }
- if(!incache) {
- result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
- 0 /* unknown size */);
- if(result) {
- failf(data, "failed to store ssl session");
- return result;
+ if(!incache) {
+ result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+ 0 /* unknown size */);
+ if(result) {
+ Curl_ssl_sessionid_unlock(conn);
+ failf(data, "failed to store ssl session");
+ return result;
+ }
}
- }
- else {
- /* Session was incache, so refcount already incremented earlier.
- * Avoid further increments with each SSL_get1_session() call.
- * This does not free the session as refcount remains > 0
- */
- SSL_SESSION_free(our_ssl_sessionid);
+ else {
+ /* Session was incache, so refcount already incremented earlier.
+ * Avoid further increments with each SSL_get1_session() call.
+ * This does not free the session as refcount remains > 0
+ */
+ SSL_SESSION_free(our_ssl_sessionid);
+ }
+ Curl_ssl_sessionid_unlock(conn);
}
/*
bool *done)
{
CURLcode result;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
curl_socket_t sockfd = conn->sock[sockindex];
long timeout_ms;
/* SSL_write() is said to return 'int' while write() and send() returns
'size_t' */
int err;
- char error_buffer[120]; /* OpenSSL documents that this must be at least 120
+ char error_buffer[256]; /* OpenSSL documents that this must be at least 256
bytes long. */
unsigned long sslerror;
int memlen;
The OpenSSL error queue contains more information on the error. */
sslerror = ERR_get_error();
failf(conn->data, "SSL_write() error: %s",
- ERR_error_string(sslerror, error_buffer));
+ ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
*curlcode = CURLE_SEND_ERROR;
return -1;
}
size_t buffersize, /* max amount to read */
CURLcode *curlcode)
{
- char error_buffer[120]; /* OpenSSL documents that this must be at
- least 120 bytes long. */
+ char error_buffer[256]; /* OpenSSL documents that this must be at
+ least 256 bytes long. */
unsigned long sslerror;
ssize_t nread;
int buffsize;
/* If the return code was negative or there actually is an error in the
queue */
failf(conn->data, "SSL read: %s, errno %d",
- ERR_error_string(sslerror, error_buffer),
+ ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)),
SOCKERRNO);
*curlcode = CURLE_RECV_ERROR;
return -1;
unsigned long ssleay_value;
sub[2]='\0';
sub[1]='\0';
- ssleay_value=SSLeay();
+ ssleay_value=OpenSSL_version_num();
if(ssleay_value < 0x906000) {
ssleay_value=SSLEAY_VERSION_NUMBER;
sub[0]='\0';
}
/* can be called with data == NULL */
-int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy,
+int Curl_ossl_random(struct Curl_easy *data, unsigned char *entropy,
size_t length)
{
if(data) {