diff options
author | Rodger Combs <rodger.combs@gmail.com> | 2018-07-11 02:45:14 -0500 |
---|---|---|
committer | Nick Zitzmann <nickzman@gmail.com> | 2018-07-14 18:32:47 -0500 |
commit | 092f6815c808489f1cea3df8449e16dff2c35e6b (patch) | |
tree | 08a44f61e965ea7b1e11b2f60c1af372f504c003 | |
parent | 8c00412428b3bbe4d56db7905372c7e6d416fbc0 (diff) |
darwinssl: add support for ALPN negotiation
-rw-r--r-- | docs/HTTP2.md | 17 | ||||
-rw-r--r-- | lib/vtls/darwinssl.c | 62 |
2 files changed, 71 insertions, 8 deletions
diff --git a/docs/HTTP2.md b/docs/HTTP2.md index efbe69991..e20ce0cab 100644 --- a/docs/HTTP2.md +++ b/docs/HTTP2.md @@ -55,14 +55,15 @@ The challenge is the ALPN and NPN support and all our different SSL backends. You may need a fairly updated SSL library version for it to provide the necessary TLS features. Right now we support: - - OpenSSL: ALPN and NPN - - libressl: ALPN and NPN - - BoringSSL: ALPN and NPN - - NSS: ALPN and NPN - - GnuTLS: ALPN - - mbedTLS: ALPN - - SChannel: ALPN - - wolfSSL: ALPN + - OpenSSL: ALPN and NPN + - libressl: ALPN and NPN + - BoringSSL: ALPN and NPN + - NSS: ALPN and NPN + - GnuTLS: ALPN + - mbedTLS: ALPN + - SChannel: ALPN + - wolfSSL: ALPN + - Secure Transport: ALPN Multiplexing ------------ diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c index f29b5acad..1aea0dc3d 100644 --- a/lib/vtls/darwinssl.c +++ b/lib/vtls/darwinssl.c @@ -1573,6 +1573,35 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, } #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ +#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(conn->bits.tls_enable_alpn) { + if(__builtin_available(macOS 10.13.4, iOS 11, *)) { + CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0, + &kCFTypeArrayCallBacks); + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) { + CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID)); + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1)); + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + /* expects length prefixed preference ordered list of protocols in wire + * format + */ + err = SSLSetALPNProtocols(BACKEND->ssl_ctx, alpnArr); + if(err != noErr) + infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n", + err); + CFRelease(alpnArr); + } + } +#endif + if(SSL_SET_OPTION(key)) { infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure " "Transport. The private key must be in the Keychain.\n"); @@ -2467,6 +2496,39 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex) break; } +#if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1 + if(conn->bits.tls_enable_alpn) { + if(__builtin_available(macOS 10.13.4, iOS 11, *)) { + CFArrayRef alpnArr = NULL; + CFStringRef chosenProtocol = NULL; + err = SSLCopyALPNProtocols(BACKEND->ssl_ctx, &alpnArr); + + if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1) + chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0); + +#ifdef USE_NGHTTP2 + if(chosenProtocol && + !CFStringCompare(chosenProtocol, CFSTR(NGHTTP2_PROTO_VERSION_ID), + 0)) { + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(chosenProtocol && + !CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) { + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + + /* chosenProtocol is a reference to the string within alpnArr + and doesn't need to be freed separately */ + if(alpnArr) + CFRelease(alpnArr); + } + } +#endif + return CURLE_OK; } } |