Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spnego_gssapi: implement TLS channel bindings for openssl #7196

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/http_negotiate.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "sendf.h"
#include "http_negotiate.h"
#include "vauth/vauth.h"
#include "vtls/vtls.h"

/* The last 3 #include files should be in this order */
#include "curl_printf.h"
Expand Down Expand Up @@ -106,11 +107,24 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS)
neg_ctx->sslContext = conn->sslContext;
#endif
#ifdef HAVE_GSSAPI
result = Curl_ssl_get_tls_server_end_point(
data, FIRSTSOCKET, &neg_ctx->channel_binding_data,
&neg_ctx->channel_binding_data_len);
if(result) {
Curl_http_auth_cleanup_negotiate(conn);
return result;
}
#endif

/* Initialize the security context and decode our challenge */
result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
host, header, neg_ctx);

#ifdef HAVE_GSSAPI
free(neg_ctx->channel_binding_data);
#endif

if(result)
Curl_http_auth_cleanup_negotiate(conn);

Expand Down
2 changes: 2 additions & 0 deletions lib/urldata.h
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,8 @@ struct negotiatedata {
gss_ctx_id_t context;
gss_name_t spn;
gss_buffer_desc output_token;
char *channel_binding_data;
size_t channel_binding_data_len;
#else
#ifdef USE_WINDOWS_SSPI
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
Expand Down
12 changes: 11 additions & 1 deletion lib/vauth/spnego_gssapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
gss_channel_bindings_t chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
struct gss_channel_bindings_struct chan;

(void) user;
(void) password;
Expand Down Expand Up @@ -148,13 +150,21 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
input_token.length = chlglen;
}

/* Set channel binding data */
if(nego->channel_binding_data) {
memset(&chan, 0, sizeof(struct gss_channel_bindings_struct));
chan.application_data.length = nego->channel_binding_data_len;
chan.application_data.value = nego->channel_binding_data;
chan_bindings = &chan;
}

/* Generate our challenge-response message */
major_status = Curl_gss_init_sec_context(data,
&minor_status,
&nego->context,
nego->spn,
&Curl_spnego_mech_oid,
GSS_C_NO_CHANNEL_BINDINGS,
chan_bindings,
&input_token,
&output_token,
TRUE,
Expand Down
3 changes: 2 additions & 1 deletion lib/vtls/bearssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,8 @@ const struct Curl_ssl Curl_ssl_bearssl = {
Curl_none_false_start, /* false_start */
bearssl_sha256sum, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

#endif /* USE_BEARSSL */
3 changes: 2 additions & 1 deletion lib/vtls/gskit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,8 @@ const struct Curl_ssl Curl_ssl_gskit = {
Curl_none_false_start, /* false_start */
NULL, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

#endif /* USE_GSKIT */
3 changes: 2 additions & 1 deletion lib/vtls/gtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1699,7 +1699,8 @@ const struct Curl_ssl Curl_ssl_gnutls = {
Curl_none_false_start, /* false_start */
gtls_sha256sum, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

#endif /* USE_GNUTLS */
3 changes: 2 additions & 1 deletion lib/vtls/mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,8 @@ const struct Curl_ssl Curl_ssl_mbedtls = {
Curl_none_false_start, /* false_start */
mbedtls_sha256sum, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

#endif /* USE_MBEDTLS */
3 changes: 2 additions & 1 deletion lib/vtls/nss.c
Original file line number Diff line number Diff line change
Expand Up @@ -2531,7 +2531,8 @@ const struct Curl_ssl Curl_ssl_nss = {
nss_false_start, /* false_start */
nss_sha256sum, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

#endif /* USE_NSS */
72 changes: 71 additions & 1 deletion lib/vtls/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4571,6 +4571,75 @@ static void ossl_disassociate_connection(struct Curl_easy *data,
}
}

static CURLcode ossl_get_tls_server_end_point(struct Curl_easy *data,
int sockindex, char **binding,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C:\projects\curl\lib\vtls\openssl.c(4574,51): error C2220: the following warning is treated as an error [C:\projects\curl\lib\libcurl.vcxproj]
C:\projects\curl\lib\vtls\openssl.c(4574,51): warning C4100: 'sockindex': unreferenced formal parameter [C:\projects\curl\lib\libcurl.vcxproj]
C:\projects\curl\lib\vtls\openssl.c(4573,65): warning C4100: 'data': unreferenced formal parameter [C:\projects\curl\lib\libcurl.vcxproj]

AppVeyor is complaining about unused variables.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should only happen if #if OPENSSL_VERSION_NUMBER > 0x10100000L is not satisfied. I can add (void) casts to ignore the parameters in the #else branch.

size_t *len)
{
/* required for X509_get_signature_nid support */
#if OPENSSL_VERSION_NUMBER > 0x10100000L
struct connectdata *conn = data->conn;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
const char prefix[] = "tls-server-end-point:";

X509 *cert;
int algo_nid;
const EVP_MD *algo_type;
const char *algo_name;
unsigned int length;
u_char buf[EVP_MAX_MD_SIZE];

cert = SSL_get_peer_certificate(backend->handle);

Check failure

Code scanning / CodeQL

Certificate not checked

This call to SSL_get_peer_certificate is not followed by a call to SSL_get_verify_result.
if(!cert) {
/* No server certificate, don't do channel binding */
*binding = NULL;
*len = 0;
return CURLE_OK;
}

if(!OBJ_find_sigid_algs(X509_get_signature_nid(cert), &algo_nid, NULL)) {
failf(data,
"Unable to find digest NID for certificate signature algorithm");
return CURLE_SSL_INVALIDCERTSTATUS;
}

/* https://datatracker.ietf.org/doc/html/rfc5929#section-4.1 */
if(algo_nid == NID_md5 || algo_nid == NID_sha1) {
algo_type = EVP_sha256();
}
else {
algo_type = EVP_get_digestbynid(algo_nid);
if(!algo_type) {
algo_name = OBJ_nid2sn(algo_nid);
failf(data, "Could not find digest algorithm %s (NID %d)",
algo_name ? algo_name : "(null)", algo_nid);
return CURLE_SSL_INVALIDCERTSTATUS;
}
}

if(!X509_digest(cert, algo_type, buf, &length)) {
failf(data, "X509_digest() failed");
return CURLE_SSL_INVALIDCERTSTATUS;
}

*binding = malloc(sizeof(prefix) - 1 + length);
if(!*binding)
return CURLE_OUT_OF_MEMORY;
memcpy(*binding, prefix, sizeof(prefix) - 1);
memcpy(*binding + sizeof(prefix) - 1, buf, length);
*len = sizeof(prefix) - 1 + length;

return CURLE_OK;
#else
/* No X509_get_signature_nid support */
(void)data; /* unused */
(void)sockindex; /* unused */
*binding = NULL;
*len = 0;
return CURLE_OK;
#endif
}

const struct Curl_ssl Curl_ssl_openssl = {
{ CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */

Expand Down Expand Up @@ -4611,7 +4680,8 @@ const struct Curl_ssl Curl_ssl_openssl = {
NULL, /* sha256sum */
#endif
ossl_associate_connection, /* associate_connection */
ossl_disassociate_connection /* disassociate_connection */
ossl_disassociate_connection, /* disassociate_connection */
ossl_get_tls_server_end_point /* get_tls_server_end_point */
};

#endif /* USE_OPENSSL */
3 changes: 2 additions & 1 deletion lib/vtls/rustls.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,8 @@ const struct Curl_ssl Curl_ssl_rustls = {
Curl_none_false_start, /* false_start */
NULL, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

#endif /* USE_RUSTLS */
3 changes: 2 additions & 1 deletion lib/vtls/schannel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2809,7 +2809,8 @@ const struct Curl_ssl Curl_ssl_schannel = {
Curl_none_false_start, /* false_start */
schannel_sha256sum, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

#endif /* USE_SCHANNEL */
3 changes: 2 additions & 1 deletion lib/vtls/sectransp.c
Original file line number Diff line number Diff line change
Expand Up @@ -3532,7 +3532,8 @@ const struct Curl_ssl Curl_ssl_sectransp = {
sectransp_false_start, /* false_start */
sectransp_sha256sum, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

#ifdef __clang__
Expand Down
14 changes: 13 additions & 1 deletion lib/vtls/vtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,17 @@ void Curl_ssl_detach_conn(struct Curl_easy *data,
}
}

CURLcode Curl_ssl_get_tls_server_end_point(struct Curl_easy *data,
int sockindex, char **binding,
size_t *len)
{
if(Curl_ssl->get_tls_server_end_point)
return Curl_ssl->get_tls_server_end_point(data, sockindex, binding, len);
*binding = NULL;
*len = 0;
return CURLE_OK;
}

void Curl_ssl_close_all(struct Curl_easy *data)
{
/* kill the session ID cache if not shared */
Expand Down Expand Up @@ -1310,7 +1321,8 @@ static const struct Curl_ssl Curl_ssl_multi = {
Curl_none_false_start, /* false_start */
NULL, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

const struct Curl_ssl *Curl_ssl =
Expand Down
14 changes: 14 additions & 0 deletions lib/vtls/vtls.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ struct Curl_ssl {
struct connectdata *conn,
int sockindex);
void (*disassociate_connection)(struct Curl_easy *data, int sockindex);

CURLcode (*get_tls_server_end_point)(struct Curl_easy *data, int sockindex,
char **binding, size_t *len);
};

#ifdef USE_SSL
Expand Down Expand Up @@ -311,6 +314,17 @@ void Curl_ssl_associate_conn(struct Curl_easy *data,
void Curl_ssl_detach_conn(struct Curl_easy *data,
struct connectdata *conn);

/* Return the tls-server-end-point channel binding, including the
* 'tls-server-end-point:' prefix.
* If successful, a pointer to the data is stored in *binding and the length of
* the data is stored in *len. The caller must free the data with free().
* If getting the channel binding is not supported, *binding will be set to
* NULL.
*/
CURLcode Curl_ssl_get_tls_server_end_point(struct Curl_easy *data,
int sockindex, char **binding,
size_t *len);

#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */

#else /* if not USE_SSL */
Expand Down
3 changes: 2 additions & 1 deletion lib/vtls/wolfssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1241,7 +1241,8 @@ const struct Curl_ssl Curl_ssl_wolfssl = {
Curl_none_false_start, /* false_start */
wolfssl_sha256sum, /* sha256sum */
NULL, /* associate_connection */
NULL /* disassociate_connection */
NULL, /* disassociate_connection */
NULL /* get_tls_server_end_point */
};

#endif