wolfssl: Add ALPN support
This commit is contained in:
Родитель
67a762928e
Коммит
a43b22e05b
|
@ -2206,7 +2206,8 @@ if test "$curl_ssl_msg" = "$init_ssl_msg"; then
|
|||
dnl Recent WolfSSL versions build without SSLv3 by default
|
||||
dnl WolfSSL needs configure --enable-opensslextra to have *get_peer*
|
||||
AC_CHECK_FUNCS(wolfSSLv3_client_method \
|
||||
wolfSSL_get_peer_certificate)
|
||||
wolfSSL_get_peer_certificate \
|
||||
wolfSSL_UseALPN)
|
||||
else
|
||||
dnl Cyassl needs configure --enable-opensslextra to have *get_peer*
|
||||
AC_CHECK_FUNCS(CyaSSL_get_peer_certificate)
|
||||
|
|
|
@ -7,7 +7,8 @@ HTTP/2 with curl
|
|||
Build prerequisites
|
||||
-------------------
|
||||
- nghttp2
|
||||
- OpenSSL, NSS, GnutTLS, PolarSSL or SChannel with a new enough version
|
||||
- OpenSSL, NSS, GnutTLS, PolarSSL, wolfSSL or SChannel with a new enough
|
||||
version.
|
||||
|
||||
[nghttp2](https://nghttp2.org/)
|
||||
-------------------------------
|
||||
|
@ -59,6 +60,7 @@ provide the necessary TLS features. Right now we support:
|
|||
- GnuTLS: ALPN
|
||||
- PolarSSL: ALPN
|
||||
- SChannel: ALPN
|
||||
- wolfSSL: ALPN
|
||||
|
||||
Multiplexing
|
||||
------------
|
||||
|
|
|
@ -77,6 +77,41 @@ and that's a problem since options.h hasn't been included yet. */
|
|||
#define CYASSL_MAX_ERROR_SZ 80
|
||||
#endif
|
||||
|
||||
/* To determine what functions are available we rely on one or both of:
|
||||
- the user's options.h generated by CyaSSL/wolfSSL
|
||||
- the symbols detected by curl's configure
|
||||
Since they are markedly different from one another, and one or the other may
|
||||
not be available, we do some checking below to bring things in sync. */
|
||||
|
||||
/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */
|
||||
#ifndef HAVE_ALPN
|
||||
#ifdef HAVE_WOLFSSL_USEALPN
|
||||
#define HAVE_ALPN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in
|
||||
options.h, but is only seen in >= 3.6.6 since that's when they started
|
||||
disabling SSLv3 by default. */
|
||||
#ifndef WOLFSSL_ALLOW_SSLV3
|
||||
#if (LIBCYASSL_VERSION_HEX < 0x03006006) || \
|
||||
defined(HAVE_WOLFSSLV3_CLIENT_METHOD)
|
||||
#define WOLFSSL_ALLOW_SSLV3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* KEEP_PEER_CERT is a product of the presence of build time symbol
|
||||
OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is
|
||||
in wolfSSL's settings.h, and the latter two are build time symbols in
|
||||
options.h. */
|
||||
#ifndef KEEP_PEER_CERT
|
||||
#if defined(HAVE_CYASSL_GET_PEER_CERTIFICATE) || \
|
||||
defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \
|
||||
(defined(OPENSSL_EXTRA) && !defined(NO_CERTS))
|
||||
#define KEEP_PEER_CERT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static Curl_recv cyassl_recv;
|
||||
static Curl_send cyassl_send;
|
||||
|
||||
|
@ -143,9 +178,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
|||
use_sni(TRUE);
|
||||
break;
|
||||
case CURL_SSLVERSION_SSLv3:
|
||||
/* before WolfSSL SSLv3 was enabled by default, and starting in WolfSSL
|
||||
we check for its presence since it is built without it by default */
|
||||
#if !defined(WOLFSSL_VERSION) || defined(HAVE_WOLFSSLV3_CLIENT_METHOD)
|
||||
#ifdef WOLFSSL_ALLOW_SSLV3
|
||||
req_method = SSLv3_client_method();
|
||||
use_sni(FALSE);
|
||||
#else
|
||||
|
@ -309,6 +342,33 @@ cyassl_connect_step1(struct connectdata *conn,
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
char protocols[128];
|
||||
*protocols = '\0';
|
||||
|
||||
/* wolfSSL's ALPN protocol name list format is a comma separated string of
|
||||
protocols in descending order of preference, eg: "h2,http/1.1" */
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
|
||||
strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ",");
|
||||
infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
|
||||
}
|
||||
#endif
|
||||
|
||||
strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1);
|
||||
infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
|
||||
|
||||
if(wolfSSL_UseALPN(conssl->handle, protocols,
|
||||
(unsigned)strlen(protocols),
|
||||
WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) {
|
||||
failf(data, "SSL: failed setting ALPN protocols");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_ALPN */
|
||||
|
||||
/* 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! */
|
||||
|
@ -413,8 +473,7 @@ cyassl_connect_step2(struct connectdata *conn,
|
|||
}
|
||||
|
||||
if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
|
||||
#if defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \
|
||||
defined(HAVE_CYASSL_GET_PEER_CERTIFICATE)
|
||||
#ifdef KEEP_PEER_CERT
|
||||
X509 *x509;
|
||||
const char *x509_der;
|
||||
int x509_der_len;
|
||||
|
@ -457,6 +516,41 @@ cyassl_connect_step2(struct connectdata *conn,
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
int rc;
|
||||
char *protocol = NULL;
|
||||
unsigned short protocol_len = 0;
|
||||
|
||||
rc = wolfSSL_ALPN_GetProtocol(conssl->handle, &protocol, &protocol_len);
|
||||
|
||||
if(rc == SSL_SUCCESS) {
|
||||
infof(data, "ALPN, server accepted to use %.*s\n", protocol_len,
|
||||
protocol);
|
||||
|
||||
if(protocol_len == ALPN_HTTP_1_1_LENGTH &&
|
||||
!memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
|
||||
conn->negnpn = CURL_HTTP_VERSION_1_1;
|
||||
#ifdef USE_NGHTTP2
|
||||
else if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN &&
|
||||
!memcmp(protocol, NGHTTP2_PROTO_VERSION_ID,
|
||||
NGHTTP2_PROTO_VERSION_ID_LEN))
|
||||
conn->negnpn = CURL_HTTP_VERSION_2;
|
||||
#endif
|
||||
else
|
||||
infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len,
|
||||
protocol);
|
||||
}
|
||||
else if(rc == SSL_ALPN_NOT_FOUND)
|
||||
infof(data, "ALPN, server did not agree to a protocol\n");
|
||||
else {
|
||||
failf(data, "ALPN, failure getting protocol, error %d", rc);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_ALPN */
|
||||
|
||||
conssl->connecting_state = ssl_connect_3;
|
||||
infof(data, "SSL connected\n");
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ These configure flags were used in MinGW to generate the options in this file:
|
|||
--enable-sessioncerts
|
||||
--enable-certgen
|
||||
--enable-testcert
|
||||
--enable-alpn
|
||||
C_EXTRA_FLAGS="-DFP_MAX_BITS=16384 -DTFM_TIMING_RESISTANT"
|
||||
|
||||
Two generated options HAVE_THREAD_LS and _POSIX_THREADS were removed since they
|
||||
|
@ -129,6 +130,8 @@ extern "C" {
|
|||
#undef USE_FAST_MATH
|
||||
#define USE_FAST_MATH
|
||||
|
||||
#undef HAVE_ALPN
|
||||
#define HAVE_ALPN
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче