diff --git a/docs/CIPHERS.md b/docs/CIPHERS.md
index 0e1d3cb284..27de940363 100644
--- a/docs/CIPHERS.md
+++ b/docs/CIPHERS.md
@@ -165,71 +165,6 @@ When specifying multiple cipher names, separate them with colon (`:`).
`TLS_AES_128_CCM_8_SHA256`
`TLS_AES_128_CCM_SHA256`
-## GSKit
-
-Ciphers are internally defined as [numeric
-codes](https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/apis/gsk_attribute_set_buffer.htm). libcurl
-maps them to the following case-insensitive names.
-
-### SSL2 cipher suites (insecure: disabled by default)
-
-`rc2-md5`
-`rc4-md5`
-`exp-rc2-md5`
-`exp-rc4-md5`
-`des-cbc-md5`
-`des-cbc3-md5`
-
-### SSL3 cipher suites
-
-`null-md5`
-`null-sha`
-`rc4-md5`
-`rc4-sha`
-`exp-rc2-cbc-md5`
-`exp-rc4-md5`
-`exp-des-cbc-sha`
-`des-cbc3-sha`
-
-### TLS v1.0 cipher suites
-
-`null-md5`
-`null-sha`
-`rc4-md5`
-`rc4-sha`
-`exp-rc2-cbc-md5`
-`exp-rc4-md5`
-`exp-des-cbc-sha`
-`des-cbc3-sha`
-`aes128-sha`
-`aes256-sha`
-
-### TLS v1.1 cipher suites
-
-`null-md5`
-`null-sha`
-`rc4-md5`
-`rc4-sha`
-`exp-des-cbc-sha`
-`des-cbc3-sha`
-`aes128-sha`
-`aes256-sha`
-
-### TLS v1.2 cipher suites
-
-`null-md5`
-`null-sha`
-`null-sha256`
-`rc4-md5`
-`rc4-sha`
-`des-cbc3-sha`
-`aes128-sha`
-`aes256-sha`
-`aes128-sha256`
-`aes256-sha256`
-`aes128-gcm-sha256`
-`aes256-gcm-sha384`
-
## WolfSSL
`RC4-SHA`,
diff --git a/docs/DEPRECATE.md b/docs/DEPRECATE.md
index b873e4a83f..61607ed776 100644
--- a/docs/DEPRECATE.md
+++ b/docs/DEPRECATE.md
@@ -6,18 +6,6 @@ email the
as soon as possible and explain to us why this is a problem for you and
how your use case cannot be satisfied properly using a workaround.
-## gskit
-
-We remove support for building curl with the gskit TLS library in August 2023.
-
-- This is a niche TLS library, only running on some IBM systems
-- no regular curl contributors use this backend
-- no CI builds use or verify this backend
-- gskit, or the curl adaption for it, lacks many modern TLS features making it
- an inferior solution
-- build breakages in this code take weeks or more to get detected
-- fixing gskit code is mostly done "flying blind"
-
## mingw v1
We remove support for building curl with the original legacy mingw version 1
@@ -57,3 +45,5 @@ curl will remove the support for space-separated names in July 2024.
- NPN
- Support for systems without 64 bit data types
- NSS
+ - gskit
+
diff --git a/docs/FAQ b/docs/FAQ
index 6a9cab951e..aacf48615e 100644
--- a/docs/FAQ
+++ b/docs/FAQ
@@ -423,9 +423,9 @@ FAQ
curl can be built to use one of the following SSL alternatives: OpenSSL,
libressl, BoringSSL, AWS-LC, GnuTLS, wolfSSL, mbedTLS, Secure Transport
- (native iOS/OS X), Schannel (native Windows), GSKit (native IBM i), BearSSL,
- or Rustls. They all have their pros and cons, and we try to maintain a
- comparison of them here: https://curl.se/docs/ssl-compared.html
+ (native iOS/OS X), Schannel (native Windows), BearSSL or Rustls. They all
+ have their pros and cons, and we try to maintain a comparison of them here:
+ https://curl.se/docs/ssl-compared.html
2.4 Does curl support SOCKS (RFC 1928) ?
diff --git a/docs/INTERNALS.md b/docs/INTERNALS.md
index d63a3c2a38..d7513a8ff3 100644
--- a/docs/INTERNALS.md
+++ b/docs/INTERNALS.md
@@ -27,7 +27,6 @@ versions of libs and build tools.
- wolfSSL 2.0.0
- OpenLDAP 2.0
- MIT Kerberos 1.2.4
- - GSKit V5R3M0
- Heimdal ?
- nghttp2 1.15.0
- WinSock 2.2 (on Windows 95+ and Windows CE .NET 4.1+)
diff --git a/docs/cmdline-opts/page-footer b/docs/cmdline-opts/page-footer
index ef33fe2ec9..6ead563bd5 100644
--- a/docs/cmdline-opts/page-footer
+++ b/docs/cmdline-opts/page-footer
@@ -60,9 +60,8 @@ the case insensitive name of the particular backend to use when curl is
invoked. Setting a name that is not a built-in alternative will make curl
stay with the default.
-SSL backend names (case-insensitive): **bearssl**, **gnutls**, **gskit**,
-**mbedtls**, **openssl**, **rustls**, **schannel**, **secure-transport**,
-**wolfssl**
+SSL backend names (case-insensitive): **bearssl**, **gnutls**, **mbedtls**,
+**openssl**, **rustls**, **schannel**, **secure-transport**, **wolfssl**
.IP "HOME
"
If set, this is used to find the home directory when that is needed. Like when
looking for the default .curlrc. *CURL_HOME* and *XDG_CONFIG_HOME*
diff --git a/docs/cmdline-opts/pinnedpubkey.d b/docs/cmdline-opts/pinnedpubkey.d
index 628278d3cf..ef619d78d2 100644
--- a/docs/cmdline-opts/pinnedpubkey.d
+++ b/docs/cmdline-opts/pinnedpubkey.d
@@ -23,7 +23,7 @@ abort the connection before sending or receiving any data.
PEM/DER support:
-7.39.0: OpenSSL, GnuTLS and GSKit
+7.39.0: OpenSSL and GnuTLS
7.43.0: wolfSSL
diff --git a/docs/cmdline-opts/write-out.d b/docs/cmdline-opts/write-out.d
index 16f973dafd..6d008ae99b 100644
--- a/docs/cmdline-opts/write-out.d
+++ b/docs/cmdline-opts/write-out.d
@@ -49,7 +49,7 @@ The variables available are:
.TP 15
**certs**
Output the certificate chain with details. Supported only by the OpenSSL,
-GnuTLS, Schannel, GSKit and Secure Transport backends. (Added in 7.88.0)
+GnuTLS, Schannel and Secure Transport backends. (Added in 7.88.0)
.TP
**content_type**
The Content-Type of the requested document, if there was any.
@@ -105,7 +105,7 @@ The http method used in the most recent HTTP request. (Added in 7.72.0)
.TP
**num_certs**
Number of server certificates received in the TLS handshake. Supported only by
-the OpenSSL, GnuTLS, Schannel, GSKit and Secure Transport backends. (Added
+the OpenSSL, GnuTLS, Schannel and Secure Transport backends. (Added
in 7.88.0)
.TP
**num_connects**
diff --git a/docs/libcurl/curl_global_sslset.3 b/docs/libcurl/curl_global_sslset.3
index 17ea484ad5..c856906650 100644
--- a/docs/libcurl/curl_global_sslset.3
+++ b/docs/libcurl/curl_global_sslset.3
@@ -38,7 +38,7 @@ typedef enum {
CURLSSLBACKEND_OPENSSL = 1, /* or one of its forks */
CURLSSLBACKEND_GNUTLS = 2,
CURLSSLBACKEND_NSS = 3,
- CURLSSLBACKEND_GSKIT = 5,
+ CURLSSLBACKEND_GSKIT = 5, /* deprecated */
CURLSSLBACKEND_POLARSSL = 6, /* deprecated */
CURLSSLBACKEND_WOLFSSL = 7,
CURLSSLBACKEND_SCHANNEL = 8,
diff --git a/docs/libcurl/libcurl-env.3 b/docs/libcurl/libcurl-env.3
index fa7d0ecc8d..a7b5504bc8 100644
--- a/docs/libcurl/libcurl-env.3
+++ b/docs/libcurl/libcurl-env.3
@@ -50,7 +50,7 @@ specific backend at first use. If no selection is done by the program using
libcurl, this variable's selection will be used. Setting a name that is not a
built-in alternative will make libcurl stay with the default.
-SSL backend names (case-insensitive): BearSSL, GnuTLS, gskit, mbedTLS,
+SSL backend names (case-insensitive): BearSSL, GnuTLS, mbedTLS,
nss, OpenSSL, rustls, Schannel, Secure-Transport, wolfSSL
.IP HOME
When the netrc feature is used (\fICURLOPT_NETRC(3)\fP), this variable is
diff --git a/docs/libcurl/opts/CURLINFO_CERTINFO.3 b/docs/libcurl/opts/CURLINFO_CERTINFO.3
index 514d50b9d4..97ed1fb73a 100644
--- a/docs/libcurl/opts/CURLINFO_CERTINFO.3
+++ b/docs/libcurl/opts/CURLINFO_CERTINFO.3
@@ -75,7 +75,7 @@ if(curl) {
}
.fi
.SH AVAILABILITY
-This option is only working in libcurl built with OpenSSL, Schannel, GSKit or
+This option is only working in libcurl built with OpenSSL, Schannel or
Secure Transport support. Schannel support added in 7.50.0. Secure Transport
support added in 7.79.0.
diff --git a/docs/libcurl/opts/CURLINFO_TLS_SESSION.3 b/docs/libcurl/opts/CURLINFO_TLS_SESSION.3
index 8278bb67cf..df179e09a5 100644
--- a/docs/libcurl/opts/CURLINFO_TLS_SESSION.3
+++ b/docs/libcurl/opts/CURLINFO_TLS_SESSION.3
@@ -63,8 +63,8 @@ if(curl) {
}
.fi
.SH AVAILABILITY
-Added in 7.34.0. Deprecated since 7.48.0 and supported OpenSSL, GnuTLS,
-NSS and gskit only up until this version was released.
+Added in 7.34.0. Deprecated since 7.48.0 and supported OpenSSL, GnuTLS, and
+NSS only up until this version was released.
.SH RETURN VALUE
Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
.SH "SEE ALSO"
diff --git a/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3 b/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3
index 1c4d07a644..040d7cc03a 100644
--- a/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3
+++ b/docs/libcurl/opts/CURLINFO_TLS_SSL_PTR.3
@@ -57,18 +57,15 @@ struct curl_tlssessioninfo {
The \fIbackend\fP struct member is one of the defines in the CURLSSLBACKEND_*
series: CURLSSLBACKEND_NONE (when built without TLS support),
CURLSSLBACKEND_WOLFSSL, CURLSSLBACKEND_SECURETRANSPORT, CURLSSLBACKEND_GNUTLS,
-CURLSSLBACKEND_GSKIT, CURLSSLBACKEND_MBEDTLS, CURLSSLBACKEND_NSS,
-CURLSSLBACKEND_OPENSSL, CURLSSLBACKEND_SCHANNEL or
-CURLSSLBACKEND_MESALINK. (Note that the OpenSSL forks are all reported as just
-OpenSSL here.)
+CURLSSLBACKEND_MBEDTLS, CURLSSLBACKEND_NSS, CURLSSLBACKEND_OPENSSL,
+CURLSSLBACKEND_SCHANNEL or CURLSSLBACKEND_MESALINK. (Note that the OpenSSL
+forks are all reported as just OpenSSL here.)
The \fIinternals\fP struct member will point to a TLS library specific pointer
for the active ("in use") SSL connection, with the following underlying types:
.RS
.IP GnuTLS
\fBgnutls_session_t\fP
-.IP gskit
-\fBgsk_handle\fP
.IP NSS
\fBPRFileDesc *\fP
.IP OpenSSL
diff --git a/docs/libcurl/opts/CURLOPT_CERTINFO.3 b/docs/libcurl/opts/CURLOPT_CERTINFO.3
index 179d746762..6efe4075fc 100644
--- a/docs/libcurl/opts/CURLOPT_CERTINFO.3
+++ b/docs/libcurl/opts/CURLOPT_CERTINFO.3
@@ -74,7 +74,7 @@ if(curl) {
}
.fi
.SH AVAILABILITY
-This option is supported by the OpenSSL, GnuTLS, Schannel, GSKit and Secure
+This option is supported by the OpenSSL, GnuTLS, Schannel and Secure
Transport backends. Schannel support added in 7.50.0. Secure Transport support
added in 7.79.0.
.SH RETURN VALUE
diff --git a/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3 b/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
index a64352f28e..3c317e1232 100644
--- a/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
+++ b/docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
@@ -102,8 +102,6 @@ PEM/DER support:
7.39.0: OpenSSL, GnuTLS
- 7.39.0-7.48.0,7.58.1+: GSKit
-
7.43.0: wolfSSL
7.47.0: mbedTLS
diff --git a/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3 b/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3
index eb2d283adc..dd8d9fdda5 100644
--- a/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3
+++ b/docs/libcurl/opts/CURLOPT_PROXY_PINNEDPUBLICKEY.3
@@ -98,7 +98,7 @@ footer:
.SH AVAILABILITY
PEM/DER support:
- 7.52.0: GSKit, GnuTLS, OpenSSL, mbedTLS, wolfSSL
+ 7.52.0: GnuTLS, OpenSSL, mbedTLS, wolfSSL
sha256 support:
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 82ce1e27ef..a35e686e69 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -161,7 +161,7 @@ typedef enum {
CURLSSLBACKEND_GNUTLS = 2,
CURLSSLBACKEND_NSS = 3,
CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */
- CURLSSLBACKEND_GSKIT = 5,
+ CURLSSLBACKEND_GSKIT CURL_DEPRECATED(8.3.0, "") = 5,
CURLSSLBACKEND_POLARSSL CURL_DEPRECATED(7.69.0, "") = 6,
CURLSSLBACKEND_WOLFSSL = 7,
CURLSSLBACKEND_SCHANNEL = 8,
@@ -2824,8 +2824,8 @@ CURL_EXTERN void curl_slist_free_all(struct curl_slist *list);
*/
CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
-/* info about the certificate chain, only for OpenSSL, GnuTLS, Schannel, NSS
- and GSKit builds. Asked for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+/* info about the certificate chain, only for OpenSSL, GnuTLS, Schannel and
+ NSS builds. Asked for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
struct curl_certinfo {
int num_of_certs; /* number of certificates with information */
struct curl_slist **certinfo; /* for each index in this array, there's a
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index d851f909a9..a08180b531 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -44,7 +44,6 @@ LIB_VAUTH_HFILES = \
LIB_VTLS_CFILES = \
vtls/bearssl.c \
- vtls/gskit.c \
vtls/gtls.c \
vtls/hostcheck.c \
vtls/keylog.c \
@@ -61,7 +60,6 @@ LIB_VTLS_CFILES = \
LIB_VTLS_HFILES = \
vtls/bearssl.h \
- vtls/gskit.h \
vtls/gtls.h \
vtls/hostcheck.h \
vtls/keylog.h \
diff --git a/lib/config-os400.h b/lib/config-os400.h
index 083fb316d6..2d0291d16d 100644
--- a/lib/config-os400.h
+++ b/lib/config-os400.h
@@ -338,9 +338,6 @@
/* Define to the function return type for send. */
#define SEND_TYPE_RETV int
-/* Define to use the GSKit package. */
-#define USE_GSKIT
-
/* Define to use the OS/400 crypto library. */
#define USE_OS400CRYPTO
diff --git a/lib/curl_setup.h b/lib/curl_setup.h
index 1c06fbb0ab..183a8d78fb 100644
--- a/lib/curl_setup.h
+++ b/lib/curl_setup.h
@@ -647,7 +647,7 @@
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \
defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
- defined(USE_GSKIT) || defined(USE_BEARSSL) || defined(USE_RUSTLS)
+ defined(USE_BEARSSL) || defined(USE_RUSTLS)
#define USE_SSL /* SSL support has been enabled */
#endif
diff --git a/lib/rand.c b/lib/rand.c
index 3e6bce0729..a5620ea6eb 100644
--- a/lib/rand.c
+++ b/lib/rand.c
@@ -188,7 +188,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
* 'rnd' points to.
*
* If libcurl is built without TLS support or with a TLS backend that lacks a
- * proper random API (rustls, Gskit or mbedTLS), this function will use "weak"
+ * proper random API (rustls or mbedTLS), this function will use "weak"
* random.
*
* When built *with* TLS support and a backend that offers strong random, it
diff --git a/lib/rand.h b/lib/rand.h
index cbe05677a1..45ce3e7c4e 100644
--- a/lib/rand.h
+++ b/lib/rand.h
@@ -24,20 +24,6 @@
*
***************************************************************************/
-/*
- * Curl_rand() stores 'num' number of random unsigned characters in the buffer
- * 'rnd' points to.
- *
- * If libcurl is built without TLS support or with a TLS backend that lacks a
- * proper random API (Gskit or mbedTLS), this function will use "weak" random.
- *
- * When built *with* TLS support and a backend that offers strong random, it
- * will return error if it cannot provide strong random values.
- *
- * NOTE: 'data' may be passed in as NULL when coming from external API without
- * easy handle!
- *
- */
CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num);
/*
diff --git a/lib/setup-os400.h b/lib/setup-os400.h
index 759583466c..7d8967b151 100644
--- a/lib/setup-os400.h
+++ b/lib/setup-os400.h
@@ -57,94 +57,6 @@ extern int Curl_getnameinfo_a(const struct sockaddr *sa,
int flags);
#define getnameinfo Curl_getnameinfo_a
-
-/* GSKit wrappers. */
-
-extern int Curl_gsk_environment_open(gsk_handle * my_env_handle);
-#define gsk_environment_open Curl_gsk_environment_open
-
-extern int Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
- gsk_handle * my_session_handle);
-#define gsk_secure_soc_open Curl_gsk_secure_soc_open
-
-extern int Curl_gsk_environment_close(gsk_handle * my_env_handle);
-#define gsk_environment_close Curl_gsk_environment_close
-
-extern int Curl_gsk_secure_soc_close(gsk_handle * my_session_handle);
-#define gsk_secure_soc_close Curl_gsk_secure_soc_close
-
-extern int Curl_gsk_environment_init(gsk_handle my_env_handle);
-#define gsk_environment_init Curl_gsk_environment_init
-
-extern int Curl_gsk_secure_soc_init(gsk_handle my_session_handle);
-#define gsk_secure_soc_init Curl_gsk_secure_soc_init
-
-extern int Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle,
- GSK_BUF_ID bufID,
- const char *buffer,
- int bufSize);
-#define gsk_attribute_set_buffer Curl_gsk_attribute_set_buffer_a
-
-extern int Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle,
- GSK_ENUM_ID enumID,
- GSK_ENUM_VALUE enumValue);
-#define gsk_attribute_set_enum Curl_gsk_attribute_set_enum
-
-extern int Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
- GSK_NUM_ID numID,
- int numValue);
-#define gsk_attribute_set_numeric_value Curl_gsk_attribute_set_numeric_value
-
-extern int Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
- GSK_CALLBACK_ID callBackID,
- void *callBackAreaPtr);
-#define gsk_attribute_set_callback Curl_gsk_attribute_set_callback
-
-extern int Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle,
- GSK_BUF_ID bufID,
- const char **buffer,
- int *bufSize);
-#define gsk_attribute_get_buffer Curl_gsk_attribute_get_buffer_a
-
-extern int Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle,
- GSK_ENUM_ID enumID,
- GSK_ENUM_VALUE *enumValue);
-#define gsk_attribute_get_enum Curl_gsk_attribute_get_enum
-
-extern int Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
- GSK_NUM_ID numID,
- int *numValue);
-#define gsk_attribute_get_numeric_value Curl_gsk_attribute_get_numeric_value
-
-extern int Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
- GSK_CERT_ID certID,
- const gsk_cert_data_elem **certDataElem,
- int *certDataElementCount);
-#define gsk_attribute_get_cert_info Curl_gsk_attribute_get_cert_info
-
-extern int Curl_gsk_secure_soc_misc(gsk_handle my_session_handle,
- GSK_MISC_ID miscID);
-#define gsk_secure_soc_misc Curl_gsk_secure_soc_misc
-
-extern int Curl_gsk_secure_soc_read(gsk_handle my_session_handle,
- char *readBuffer,
- int readBufSize, int *amtRead);
-#define gsk_secure_soc_read Curl_gsk_secure_soc_read
-
-extern int Curl_gsk_secure_soc_write(gsk_handle my_session_handle,
- char *writeBuffer,
- int writeBufSize, int *amtWritten);
-#define gsk_secure_soc_write Curl_gsk_secure_soc_write
-
-extern const char * Curl_gsk_strerror_a(int gsk_return_value);
-#define gsk_strerror Curl_gsk_strerror_a
-
-extern int Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
- int IOCompletionPort,
- Qso_OverlappedIO_t * communicationsArea);
-#define gsk_secure_soc_startInit Curl_gsk_secure_soc_startInit
-
-
/* GSSAPI wrappers. */
extern OM_uint32 Curl_gss_import_name_a(OM_uint32 * minor_status,
diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c
deleted file mode 100644
index c12829329b..0000000000
--- a/lib/vtls/gskit.c
+++ /dev/null
@@ -1,1329 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) Daniel Stenberg, , 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.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.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
-
-#include "curl_setup.h"
-
-#ifdef USE_GSKIT
-
-#include
-#include
-#undef HAVE_SOCKETPAIR /* because the native one isn't good enough */
-#include "socketpair.h"
-#include "strerror.h"
-
-/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
-#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
-#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230
-#endif
-
-#ifndef GSK_TLSV10_CIPHER_SPECS
-#define GSK_TLSV10_CIPHER_SPECS 236
-#endif
-
-#ifndef GSK_TLSV11_CIPHER_SPECS
-#define GSK_TLSV11_CIPHER_SPECS 237
-#endif
-
-#ifndef GSK_TLSV12_CIPHER_SPECS
-#define GSK_TLSV12_CIPHER_SPECS 238
-#endif
-
-#ifndef GSK_PROTOCOL_TLSV11
-#define GSK_PROTOCOL_TLSV11 437
-#endif
-
-#ifndef GSK_PROTOCOL_TLSV12
-#define GSK_PROTOCOL_TLSV12 438
-#endif
-
-#ifndef GSK_FALSE
-#define GSK_FALSE 0
-#endif
-
-#ifndef GSK_TRUE
-#define GSK_TRUE 1
-#endif
-
-
-#include
-
-#include
-#include "urldata.h"
-#include "sendf.h"
-#include "gskit.h"
-#include "vtls.h"
-#include "vtls_int.h"
-#include "connect.h" /* for the connect timeout */
-#include "select.h"
-#include "strcase.h"
-#include "timediff.h"
-#include "x509asn1.h"
-#include "curl_printf.h"
-
-#include "curl_memory.h"
-/* The last #include file should be: */
-#include "memdebug.h"
-
-
-/* Directions. */
-#define SOS_READ 0x01
-#define SOS_WRITE 0x02
-
-/* SSL version flags. */
-#define CURL_GSKPROTO_SSLV2 0
-#define CURL_GSKPROTO_SSLV2_MASK (1 << CURL_GSKPROTO_SSLV2)
-#define CURL_GSKPROTO_SSLV3 1
-#define CURL_GSKPROTO_SSLV3_MASK (1 << CURL_GSKPROTO_SSLV3)
-#define CURL_GSKPROTO_TLSV10 2
-#define CURL_GSKPROTO_TLSV10_MASK (1 << CURL_GSKPROTO_TLSV10)
-#define CURL_GSKPROTO_TLSV11 3
-#define CURL_GSKPROTO_TLSV11_MASK (1 << CURL_GSKPROTO_TLSV11)
-#define CURL_GSKPROTO_TLSV12 4
-#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12)
-#define CURL_GSKPROTO_LAST 5
-
-struct gskit_ssl_backend_data {
- gsk_handle handle;
- int iocport;
- int localfd;
- int remotefd;
-};
-
-#define BACKEND ((struct gskit_ssl_backend_data *)connssl->backend)
-
-/* Supported ciphers. */
-struct gskit_cipher {
- const char *name; /* Cipher name. */
- const char *gsktoken; /* Corresponding token for GSKit String. */
- unsigned int versions; /* SSL version flags. */
-};
-
-static const struct gskit_cipher ciphertable[] = {
- { "null-md5", "01",
- CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
- CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
- { "null-sha", "02",
- CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
- CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
- { "exp-rc4-md5", "03",
- CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
- { "rc4-md5", "04",
- CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
- CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
- { "rc4-sha", "05",
- CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
- CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
- { "exp-rc2-cbc-md5", "06",
- CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
- { "exp-des-cbc-sha", "09",
- CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
- CURL_GSKPROTO_TLSV11_MASK },
- { "des-cbc3-sha", "0A",
- CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
- CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
- { "aes128-sha", "2F",
- CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
- CURL_GSKPROTO_TLSV12_MASK },
- { "aes256-sha", "35",
- CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
- CURL_GSKPROTO_TLSV12_MASK },
- { "null-sha256", "3B", CURL_GSKPROTO_TLSV12_MASK },
- { "aes128-sha256", "3C", CURL_GSKPROTO_TLSV12_MASK },
- { "aes256-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK },
- { "aes128-gcm-sha256",
- "9C", CURL_GSKPROTO_TLSV12_MASK },
- { "aes256-gcm-sha384",
- "9D", CURL_GSKPROTO_TLSV12_MASK },
- { "rc4-md5", "1", CURL_GSKPROTO_SSLV2_MASK },
- { "exp-rc4-md5", "2", CURL_GSKPROTO_SSLV2_MASK },
- { "rc2-md5", "3", CURL_GSKPROTO_SSLV2_MASK },
- { "exp-rc2-md5", "4", CURL_GSKPROTO_SSLV2_MASK },
- { "des-cbc-md5", "6", CURL_GSKPROTO_SSLV2_MASK },
- { "des-cbc3-md5", "7", CURL_GSKPROTO_SSLV2_MASK },
- { (const char *) NULL, (const char *) NULL, 0 }
-};
-
-
-static bool is_separator(char c)
-{
- /* Return whether character is a cipher list separator. */
- switch(c) {
- case ' ':
- case '\t':
- case ':':
- case ',':
- case ';':
- return true;
- }
- return false;
-}
-
-
-static CURLcode gskit_status(struct Curl_easy *data, int rc,
- const char *procname, CURLcode defcode)
-{
- char buffer[STRERROR_LEN];
- /* Process GSKit status and map it to a CURLcode. */
- switch(rc) {
- case GSK_OK:
- case GSK_OS400_ASYNCHRONOUS_SOC_INIT:
- return CURLE_OK;
- case GSK_KEYRING_OPEN_ERROR:
- case GSK_OS400_ERROR_NO_ACCESS:
- return CURLE_SSL_CACERT_BADFILE;
- case GSK_INSUFFICIENT_STORAGE:
- return CURLE_OUT_OF_MEMORY;
- case GSK_ERROR_BAD_V2_CIPHER:
- case GSK_ERROR_BAD_V3_CIPHER:
- case GSK_ERROR_NO_CIPHERS:
- return CURLE_SSL_CIPHER;
- case GSK_OS400_ERROR_NOT_TRUSTED_ROOT:
- case GSK_ERROR_CERT_VALIDATION:
- return CURLE_PEER_FAILED_VERIFICATION;
- case GSK_OS400_ERROR_TIMED_OUT:
- return CURLE_OPERATION_TIMEDOUT;
- case GSK_WOULD_BLOCK:
- return CURLE_AGAIN;
- case GSK_OS400_ERROR_NOT_REGISTERED:
- break;
- case GSK_ERROR_IO:
- switch(errno) {
- case ENOMEM:
- return CURLE_OUT_OF_MEMORY;
- default:
- failf(data, "%s I/O error: %s", procname,
- Curl_strerror(errno, buffer, sizeof(buffer)));
- break;
- }
- break;
- default:
- failf(data, "%s: %s", procname, gsk_strerror(rc));
- break;
- }
- return defcode;
-}
-
-
-static CURLcode set_enum(struct Curl_easy *data, gsk_handle h,
- GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok)
-{
- char buffer[STRERROR_LEN];
- int rc = gsk_attribute_set_enum(h, id, value);
-
- switch(rc) {
- case GSK_OK:
- return CURLE_OK;
- case GSK_ERROR_IO:
- failf(data, "gsk_attribute_set_enum() I/O error: %s",
- Curl_strerror(errno, buffer, sizeof(buffer)));
- break;
- case GSK_ATTRIBUTE_INVALID_ID:
- if(unsupported_ok)
- return CURLE_UNSUPPORTED_PROTOCOL;
- default:
- failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
- break;
- }
- return CURLE_SSL_CONNECT_ERROR;
-}
-
-
-static CURLcode set_buffer(struct Curl_easy *data, gsk_handle h,
- GSK_BUF_ID id, const char *buf, bool unsupported_ok)
-{
- char buffer[STRERROR_LEN];
- int rc = gsk_attribute_set_buffer(h, id, buf, 0);
-
- switch(rc) {
- case GSK_OK:
- return CURLE_OK;
- case GSK_ERROR_IO:
- failf(data, "gsk_attribute_set_buffer() I/O error: %s",
- Curl_strerror(errno, buffer, sizeof(buffer)));
- break;
- case GSK_ATTRIBUTE_INVALID_ID:
- if(unsupported_ok)
- return CURLE_UNSUPPORTED_PROTOCOL;
- default:
- failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
- break;
- }
- return CURLE_SSL_CONNECT_ERROR;
-}
-
-
-static CURLcode set_numeric(struct Curl_easy *data,
- gsk_handle h, GSK_NUM_ID id, int value)
-{
- char buffer[STRERROR_LEN];
- int rc = gsk_attribute_set_numeric_value(h, id, value);
-
- switch(rc) {
- case GSK_OK:
- return CURLE_OK;
- case GSK_ERROR_IO:
- failf(data, "gsk_attribute_set_numeric_value() I/O error: %s",
- Curl_strerror(errno, buffer, sizeof(buffer)));
- break;
- default:
- failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc));
- break;
- }
- return CURLE_SSL_CONNECT_ERROR;
-}
-
-
-static CURLcode set_ciphers(struct Curl_cfilter *cf, struct Curl_easy *data,
- gsk_handle h, unsigned int *protoflags)
-{
- struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
- struct connectdata *conn = data->conn;
- const char *cipherlist = conn_config->cipher_list;
- const char *clp;
- const struct gskit_cipher *ctp;
- int i;
- int l;
- bool unsupported;
- CURLcode result;
- struct {
- char *buf;
- char *ptr;
- } ciphers[CURL_GSKPROTO_LAST];
-
- /* Compile cipher list into GSKit-compatible cipher lists. */
-
- if(!cipherlist)
- return CURLE_OK;
- while(is_separator(*cipherlist)) /* Skip initial separators. */
- cipherlist++;
- if(!*cipherlist)
- return CURLE_OK;
-
- /* We allocate GSKit buffers of the same size as the input string: since
- GSKit tokens are always shorter than their cipher names, allocated buffers
- will always be large enough to accommodate the result. */
- l = strlen(cipherlist) + 1;
- memset(ciphers, 0, sizeof(ciphers));
- for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
- ciphers[i].buf = malloc(l);
- if(!ciphers[i].buf) {
- while(i--)
- free(ciphers[i].buf);
- return CURLE_OUT_OF_MEMORY;
- }
- ciphers[i].ptr = ciphers[i].buf;
- *ciphers[i].ptr = '\0';
- }
-
- /* Process each cipher in input string. */
- unsupported = FALSE;
- result = CURLE_OK;
- for(;;) {
- for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
- cipherlist++;
- l = cipherlist - clp;
- if(!l)
- break;
- /* Search the cipher in our table. */
- for(ctp = ciphertable; ctp->name; ctp++)
- if(strncasecompare(ctp->name, clp, l) && !ctp->name[l])
- break;
- if(!ctp->name) {
- failf(data, "Unknown cipher %.*s", l, clp);
- result = CURLE_SSL_CIPHER;
- }
- else {
- unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
- CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK));
- for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
- if(ctp->versions & (1 << i)) {
- strcpy(ciphers[i].ptr, ctp->gsktoken);
- ciphers[i].ptr += strlen(ctp->gsktoken);
- }
- }
- }
-
- /* Advance to next cipher name or end of string. */
- while(is_separator(*cipherlist))
- cipherlist++;
- }
-
- /* Disable protocols with empty cipher lists. */
- for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
- if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) {
- *protoflags &= ~(1 << i);
- ciphers[i].buf[0] = '\0';
- }
- }
-
- /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
- if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
- result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
- ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
- if(result == CURLE_UNSUPPORTED_PROTOCOL) {
- result = CURLE_OK;
- if(unsupported) {
- failf(data, "TLSv1.1-only ciphers are not yet supported");
- result = CURLE_SSL_CIPHER;
- }
- }
- }
- if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
- result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
- ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
- if(result == CURLE_UNSUPPORTED_PROTOCOL) {
- result = CURLE_OK;
- if(unsupported) {
- failf(data, "TLSv1.2-only ciphers are not yet supported");
- result = CURLE_SSL_CIPHER;
- }
- }
- }
-
- /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to
- the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */
- if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
- result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
- ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
- if(result == CURLE_UNSUPPORTED_PROTOCOL) {
- result = CURLE_OK;
- strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr,
- ciphers[CURL_GSKPROTO_TLSV10].ptr);
- }
- }
-
- /* Set-up other ciphers. */
- if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
- result = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
- ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
- if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
- result = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
- ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
-
- /* Clean-up. */
- for(i = 0; i < CURL_GSKPROTO_LAST; i++)
- free(ciphers[i].buf);
-
- return result;
-}
-
-
-static int gskit_init(void)
-{
- /* No initialization needed. */
- return 1;
-}
-
-
-static void gskit_cleanup(void)
-{
- /* Nothing to do. */
-}
-
-
-static CURLcode init_environment(struct Curl_easy *data,
- gsk_handle *envir, const char *appid,
- const char *file, const char *label,
- const char *password)
-{
- int rc;
- CURLcode result;
- gsk_handle h;
-
- /* Creates the GSKit environment. */
-
- rc = gsk_environment_open(&h);
- switch(rc) {
- case GSK_OK:
- break;
- case GSK_INSUFFICIENT_STORAGE:
- return CURLE_OUT_OF_MEMORY;
- default:
- failf(data, "gsk_environment_open(): %s", gsk_strerror(rc));
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- result = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
- if(!result && appid)
- result = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
- if(!result && file)
- result = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
- if(!result && label)
- result = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
- if(!result && password)
- result = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
-
- if(!result) {
- /* Locate CAs, Client certificate and key according to our settings.
- Note: this call may be blocking for some tenths of seconds. */
- result = gskit_status(data, gsk_environment_init(h),
- "gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
- if(!result) {
- *envir = h;
- return result;
- }
- }
- /* Error: rollback. */
- gsk_environment_close(&h);
- return result;
-}
-
-
-static void cancel_async_handshake(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- Qso_OverlappedIO_t cstat;
-
- (void)data;
- DEBUGASSERT(BACKEND);
-
- if(QsoCancelOperation(Curl_conn_cf_get_socket(cf, data), 0) > 0)
- QsoWaitForIOCompletion(BACKEND->iocport, &cstat, (struct timeval *) NULL);
-}
-
-
-static void close_async_handshake(struct ssl_connect_data *connssl)
-{
- DEBUGASSERT(BACKEND);
- QsoDestroyIOCompletionPort(BACKEND->iocport);
- BACKEND->iocport = -1;
-}
-
-static int pipe_ssloverssl(struct Curl_cfilter *cf, struct Curl_easy *data,
- int directions)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
- struct ssl_connect_data *connssl_next = cf_ssl_next?
- cf_ssl_next->ctx : NULL;
- struct gskit_ssl_backend_data *backend_next;
- struct pollfd fds[2];
- int n;
- int m;
- int i;
- int ret = 0;
- char buf[CURL_MAX_WRITE_SIZE];
-
- DEBUGASSERT(BACKEND);
-
- if(!connssl_next)
- return 0; /* No SSL over SSL: OK. */
-
- DEBUGASSERT(connssl_next->backend);
- backend_next = (struct gskit_ssl_backend_data *)connssl_next->backend;
-
- n = 1;
- fds[0].fd = BACKEND->remotefd;
- fds[1].fd = Curl_conn_cf_get_socket(cf, data);
-
- if(directions & SOS_READ) {
- fds[0].events |= POLLOUT;
- }
- if(directions & SOS_WRITE) {
- n = 2;
- fds[0].events |= POLLIN;
- fds[1].events |= POLLOUT;
- }
- i = Curl_poll(fds, n, 0);
- if(i < 0)
- return -1; /* Select error. */
-
- if(fds[0].revents & POLLOUT) {
- /* Try getting data from HTTPS proxy and pipe it upstream. */
- n = 0;
- i = gsk_secure_soc_read(backend_next->handle, buf, sizeof(buf), &n);
- switch(i) {
- case GSK_OK:
- if(n) {
- i = write(BACKEND->remotefd, buf, n);
- if(i < 0)
- return -1;
- ret = 1;
- }
- break;
- case GSK_OS400_ERROR_TIMED_OUT:
- case GSK_WOULD_BLOCK:
- break;
- default:
- return -1;
- }
- }
-
- if((fds[0].revents & POLLIN) && (fds[1].revents & POLLOUT)) {
- /* Pipe data to HTTPS proxy. */
- n = read(BACKEND->remotefd, buf, sizeof(buf));
- if(n < 0)
- return -1;
- if(n) {
- i = gsk_secure_soc_write(backend_next->handle, buf, n, &m);
- if(i != GSK_OK || n != m)
- return -1;
- ret = 1;
- }
- }
-
- return ret; /* OK */
-}
-
-
-static void close_one(struct Curl_cfilter *cf, struct Curl_easy *data)
-{
- struct ssl_connect_data *connssl = cf->ctx;
-
- DEBUGASSERT(BACKEND);
- if(BACKEND->handle) {
- gskit_status(data, gsk_secure_soc_close(&BACKEND->handle),
- "gsk_secure_soc_close()", 0);
- /* Last chance to drain output. */
- while(pipe_ssloverssl(cf, data, SOS_WRITE) > 0)
- ;
- BACKEND->handle = (gsk_handle) NULL;
- if(BACKEND->localfd >= 0) {
- close(BACKEND->localfd);
- BACKEND->localfd = -1;
- }
- if(BACKEND->remotefd >= 0) {
- close(BACKEND->remotefd);
- BACKEND->remotefd = -1;
- }
- }
- if(BACKEND->iocport >= 0)
- close_async_handshake(connssl);
-}
-
-
-static ssize_t gskit_send(struct Curl_cfilter *cf, struct Curl_easy *data,
- const void *mem, size_t len, CURLcode *curlcode)
-{
- struct connectdata *conn = cf->conn;
- struct ssl_connect_data *connssl = cf->ctx;
- CURLcode cc = CURLE_SEND_ERROR;
- int written;
-
- DEBUGASSERT(BACKEND);
-
- if(pipe_ssloverssl(cf, data, SOS_WRITE) >= 0) {
- cc = gskit_status(data,
- gsk_secure_soc_write(BACKEND->handle,
- (char *) mem, (int) len, &written),
- "gsk_secure_soc_write()", CURLE_SEND_ERROR);
- if(cc == CURLE_OK)
- if(pipe_ssloverssl(cf, data, SOS_WRITE) < 0)
- cc = CURLE_SEND_ERROR;
- }
- if(cc != CURLE_OK) {
- *curlcode = cc;
- written = -1;
- }
- return (ssize_t) written; /* number of bytes */
-}
-
-
-static ssize_t gskit_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
- char *buf, size_t buffersize, CURLcode *curlcode)
-{
- struct connectdata *conn = cf->conn;
- struct ssl_connect_data *connssl = cf->ctx;
- int nread;
- CURLcode cc = CURLE_RECV_ERROR;
-
- (void)data;
- DEBUGASSERT(BACKEND);
-
- if(pipe_ssloverssl(cf, data, SOS_READ) >= 0) {
- int buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
- cc = gskit_status(data, gsk_secure_soc_read(BACKEND->handle,
- buf, buffsize, &nread),
- "gsk_secure_soc_read()", CURLE_RECV_ERROR);
- }
- switch(cc) {
- case CURLE_OK:
- break;
- case CURLE_OPERATION_TIMEDOUT:
- cc = CURLE_AGAIN;
- default:
- *curlcode = cc;
- nread = -1;
- break;
- }
- return (ssize_t) nread;
-}
-
-static CURLcode
-set_ssl_version_min_max(unsigned int *protoflags,
- struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
- struct connectdata *conn = data->conn;
- long ssl_version = conn_config->version;
- long ssl_version_max = conn_config->version_max;
- long i = ssl_version;
- switch(ssl_version_max) {
- case CURL_SSLVERSION_MAX_NONE:
- case CURL_SSLVERSION_MAX_DEFAULT:
- ssl_version_max = CURL_SSLVERSION_TLSv1_2;
- break;
- }
- for(; i <= (ssl_version_max >> 16); ++i) {
- switch(i) {
- case CURL_SSLVERSION_TLSv1_0:
- *protoflags |= CURL_GSKPROTO_TLSV10_MASK;
- break;
- case CURL_SSLVERSION_TLSv1_1:
- *protoflags |= CURL_GSKPROTO_TLSV11_MASK;
- break;
- case CURL_SSLVERSION_TLSv1_2:
- *protoflags |= CURL_GSKPROTO_TLSV11_MASK;
- break;
- case CURL_SSLVERSION_TLSv1_3:
- failf(data, "GSKit: TLS 1.3 is not yet supported");
- return CURLE_SSL_CONNECT_ERROR;
- }
- }
-
- return CURLE_OK;
-}
-
-static CURLcode gskit_connect_step1(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
- struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
- struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
- struct ssl_connect_data *connssl_next = cf_ssl_next?
- cf_ssl_next->ctx : NULL;
- gsk_handle envir;
- CURLcode result;
- const char * const keyringfile = conn_config->CAfile;
- const char * const keyringpwd = ssl_config->key_passwd;
- const char * const keyringlabel = ssl_config->primary.clientcert;
- const long int ssl_version = conn_config->version;
- const bool verifypeer = conn_config->verifypeer;
- const char *hostname = connssl->hostname;
- const char *sni;
- unsigned int protoflags = 0;
- Qso_OverlappedIO_t commarea;
- int sockpair[2];
- static const int sobufsize = CURL_MAX_WRITE_SIZE;
-
- /* Create SSL environment, start (preferably asynchronous) handshake. */
- DEBUGASSERT(BACKEND);
-
- BACKEND->handle = (gsk_handle) NULL;
- BACKEND->iocport = -1;
- BACKEND->localfd = -1;
- BACKEND->remotefd = -1;
-
- /* GSKit supports two ways of specifying an SSL context: either by
- * application identifier (that should have been defined at the system
- * level) or by keyring file, password and certificate label.
- * Local certificate name (CURLOPT_SSLCERT) is used to hold either the
- * application identifier of the certificate label.
- * Key password (CURLOPT_KEYPASSWD) holds the keyring password.
- * It is not possible to have different keyrings for the CAs and the
- * local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
- * the keyring file.
- * If no key password is given and the keyring is the system keyring,
- * application identifier mode is tried first, as recommended in IBM doc.
- */
-
- envir = (gsk_handle) NULL;
-
- if(keyringlabel && *keyringlabel && !keyringpwd &&
- !strcmp(keyringfile, CURL_CA_BUNDLE)) {
- /* Try application identifier mode. */
- init_environment(data, &envir, keyringlabel, (const char *) NULL,
- (const char *) NULL, (const char *) NULL);
- }
-
- if(!envir) {
- /* Use keyring mode. */
- result = init_environment(data, &envir, (const char *) NULL,
- keyringfile, keyringlabel, keyringpwd);
- if(result)
- return result;
- }
-
- /* Create secure session. */
- result = gskit_status(data, gsk_secure_soc_open(envir, &BACKEND->handle),
- "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
- gsk_environment_close(&envir);
- if(result)
- return result;
-
- /* Establish a pipelining socket pair for SSL over SSL. */
- if(connssl_next) {
- if(Curl_socketpair(0, 0, 0, sockpair))
- return CURLE_SSL_CONNECT_ERROR;
- BACKEND->localfd = sockpair[0];
- BACKEND->remotefd = sockpair[1];
- setsockopt(BACKEND->localfd, SOL_SOCKET, SO_RCVBUF,
- (void *) &sobufsize, sizeof(sobufsize));
- setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_RCVBUF,
- (void *) &sobufsize, sizeof(sobufsize));
- setsockopt(BACKEND->localfd, SOL_SOCKET, SO_SNDBUF,
- (void *) &sobufsize, sizeof(sobufsize));
- setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_SNDBUF,
- (void *) &sobufsize, sizeof(sobufsize));
- curlx_nonblock(BACKEND->localfd, TRUE);
- curlx_nonblock(BACKEND->remotefd, TRUE);
- }
-
- /* Determine which SSL/TLS version should be enabled. */
- sni = hostname;
- switch(ssl_version) {
- case CURL_SSLVERSION_SSLv2:
- protoflags = CURL_GSKPROTO_SSLV2_MASK;
- sni = NULL;
- break;
- case CURL_SSLVERSION_SSLv3:
- protoflags = CURL_GSKPROTO_SSLV3_MASK;
- sni = NULL;
- break;
- case CURL_SSLVERSION_DEFAULT:
- case CURL_SSLVERSION_TLSv1:
- protoflags = CURL_GSKPROTO_TLSV10_MASK |
- CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
- break;
- case CURL_SSLVERSION_TLSv1_0:
- case CURL_SSLVERSION_TLSv1_1:
- case CURL_SSLVERSION_TLSv1_2:
- case CURL_SSLVERSION_TLSv1_3:
- result = set_ssl_version_min_max(&protoflags, cf, data);
- if(result != CURLE_OK)
- return result;
- break;
- default:
- failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
- return CURLE_SSL_CONNECT_ERROR;
- }
-
- /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
- if(sni) {
- char *snihost = Curl_ssl_snihost(data, sni, NULL);
- if(!snihost) {
- failf(data, "Failed to set SNI");
- return CURLE_SSL_CONNECT_ERROR;
- }
- result = set_buffer(data, BACKEND->handle,
- GSK_SSL_EXTN_SERVERNAME_REQUEST, snihost, TRUE);
- if(result == CURLE_UNSUPPORTED_PROTOCOL)
- result = CURLE_OK;
- }
-
- /* Set session parameters. */
- if(!result) {
- /* Compute the handshake timeout. Since GSKit granularity is 1 second,
- we round up the required value. */
- timediff_t timeout = Curl_timeleft(data, NULL, TRUE);
- if(timeout < 0)
- result = CURLE_OPERATION_TIMEDOUT;
- else
- result = set_numeric(data, BACKEND->handle, GSK_HANDSHAKE_TIMEOUT,
- (timeout + 999) / 1000);
- }
- if(!result)
- result = set_numeric(data, BACKEND->handle, GSK_OS400_READ_TIMEOUT, 1);
- if(!result)
- result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0?
- BACKEND->localfd: Curl_conn_cf_get_socket(cf, data));
- if(!result)
- result = set_ciphers(cf, data, BACKEND->handle, &protoflags);
- if(!protoflags) {
- failf(data, "No SSL protocol/cipher combination enabled");
- result = CURLE_SSL_CIPHER;
- }
- if(!result)
- result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_SSLV2,
- (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
- GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
- if(!result)
- result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_SSLV3,
- (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
- GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
- if(!result)
- result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV1,
- (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
- GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
- if(!result) {
- result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV11,
- (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
- GSK_TRUE: GSK_FALSE, TRUE);
- if(result == CURLE_UNSUPPORTED_PROTOCOL) {
- result = CURLE_OK;
- if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
- failf(data, "TLS 1.1 not yet supported");
- result = CURLE_SSL_CIPHER;
- }
- }
- }
- if(!result) {
- result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV12,
- (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
- GSK_TRUE: GSK_FALSE, TRUE);
- if(result == CURLE_UNSUPPORTED_PROTOCOL) {
- result = CURLE_OK;
- if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
- failf(data, "TLS 1.2 not yet supported");
- result = CURLE_SSL_CIPHER;
- }
- }
- }
- if(!result)
- result = set_enum(data, BACKEND->handle, GSK_SERVER_AUTH_TYPE,
- verifypeer? GSK_SERVER_AUTH_FULL:
- GSK_SERVER_AUTH_PASSTHRU, FALSE);
-
- if(!result) {
- /* Start handshake. Try asynchronous first. */
- memset(&commarea, 0, sizeof(commarea));
- BACKEND->iocport = QsoCreateIOCompletionPort();
- if(BACKEND->iocport != -1) {
- result = gskit_status(data,
- gsk_secure_soc_startInit(BACKEND->handle,
- BACKEND->iocport,
- &commarea),
- "gsk_secure_soc_startInit()",
- CURLE_SSL_CONNECT_ERROR);
- if(!result) {
- connssl->connecting_state = ssl_connect_2;
- return CURLE_OK;
- }
- else
- close_async_handshake(connssl);
- }
- else if(errno != ENOBUFS)
- result = gskit_status(data, GSK_ERROR_IO,
- "QsoCreateIOCompletionPort()", 0);
- else if(connssl_next) {
- /* Cannot pipeline while handshaking synchronously. */
- result = CURLE_SSL_CONNECT_ERROR;
- }
- else {
- /* No more completion port available. Use synchronous IO. */
- result = gskit_status(data, gsk_secure_soc_init(BACKEND->handle),
- "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
- if(!result) {
- connssl->connecting_state = ssl_connect_3;
- return CURLE_OK;
- }
- }
- }
-
- /* Error: rollback. */
- close_one(cf, data);
- return result;
-}
-
-
-static CURLcode gskit_connect_step2(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- bool nonblocking)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- Qso_OverlappedIO_t cstat;
- struct timeval stmv;
- CURLcode result;
-
- /* Poll or wait for end of SSL asynchronous handshake. */
- DEBUGASSERT(BACKEND);
-
- for(;;) {
- timediff_t timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
- stmv.tv_sec = 0;
- stmv.tv_usec = 0;
- if(timeout_ms < 0)
- timeout_ms = 0;
- switch(QsoWaitForIOCompletion(BACKEND->iocport, &cstat,
- curlx_mstotv(&stmv, timeout_ms))) {
- case 1: /* Operation complete. */
- break;
- case -1: /* An error occurred: handshake still in progress. */
- if(errno == EINTR) {
- if(nonblocking)
- return CURLE_OK;
- continue; /* Retry. */
- }
- if(errno != ETIME) {
- char buffer[STRERROR_LEN];
- failf(data, "QsoWaitForIOCompletion() I/O error: %s",
- Curl_strerror(errno, buffer, sizeof(buffer)));
- cancel_async_handshake(cf, data);
- close_async_handshake(connssl);
- return CURLE_SSL_CONNECT_ERROR;
- }
- /* FALL INTO... */
- case 0: /* Handshake in progress, timeout occurred. */
- if(nonblocking)
- return CURLE_OK;
- cancel_async_handshake(cf, data);
- close_async_handshake(connssl);
- return CURLE_OPERATION_TIMEDOUT;
- }
- break;
- }
- result = gskit_status(data, cstat.returnValue, "SSL handshake",
- CURLE_SSL_CONNECT_ERROR);
- if(!result)
- connssl->connecting_state = ssl_connect_3;
- close_async_handshake(connssl);
- return result;
-}
-
-
-static CURLcode gskit_connect_step3(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- const gsk_cert_data_elem *cdev;
- int cdec;
- const gsk_cert_data_elem *p;
- const char *cert = (const char *) NULL;
- const char *certend = (const char *) NULL;
- const char *ptr;
- CURLcode result;
-
- /* SSL handshake done: gather certificate info and verify host. */
- DEBUGASSERT(BACKEND);
-
- if(gskit_status(data, gsk_attribute_get_cert_info(BACKEND->handle,
- GSK_PARTNER_CERT_INFO,
- &cdev, &cdec),
- "gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
- CURLE_OK) {
- int i;
-
- infof(data, "Server certificate:");
- p = cdev;
- for(i = 0; i++ < cdec; p++)
- switch(p->cert_data_id) {
- case CERT_BODY_DER:
- cert = p->cert_data_p;
- certend = cert + cdev->cert_data_l;
- break;
- case CERT_DN_PRINTABLE:
- infof(data, "\t subject: %.*s", p->cert_data_l, p->cert_data_p);
- break;
- case CERT_ISSUER_DN_PRINTABLE:
- infof(data, "\t issuer: %.*s", p->cert_data_l, p->cert_data_p);
- break;
- case CERT_VALID_FROM:
- infof(data, "\t start date: %.*s", p->cert_data_l, p->cert_data_p);
- break;
- case CERT_VALID_TO:
- infof(data, "\t expire date: %.*s", p->cert_data_l, p->cert_data_p);
- break;
- }
- }
-
- /* Verify host. */
- result = Curl_verifyhost(cf, data, cert, certend);
- if(result)
- return result;
-
- /* The only place GSKit can get the whole CA chain is a validation
- callback where no user data pointer is available. Therefore it's not
- possible to copy this chain into our structures for CAINFO.
- However the server certificate may be available, thus we can return
- info about it. */
- if(data->set.ssl.certinfo) {
- result = Curl_ssl_init_certinfo(data, 1);
- if(result)
- return result;
-
- if(cert) {
- result = Curl_extract_certinfo(data, 0, cert, certend);
- if(result)
- return result;
- }
- }
-
- /* Check pinned public key. */
- ptr = Curl_ssl_cf_is_proxy(cf)?
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]:
- data->set.str[STRING_SSL_PINNEDPUBLICKEY];
- if(!result && ptr) {
- struct Curl_X509certificate x509;
- struct Curl_asn1Element *p;
-
- memset(&x509, 0, sizeof(x509));
- if(Curl_parseX509(&x509, cert, certend))
- return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
- p = &x509.subjectPublicKeyInfo;
- result = Curl_pin_peer_pubkey(data, ptr, p->header, p->end - p->header);
- if(result) {
- failf(data, "SSL: public key does not match pinned public key");
- return result;
- }
- }
-
- connssl->connecting_state = ssl_connect_done;
- return CURLE_OK;
-}
-
-
-static CURLcode gskit_connect_common(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- bool nonblocking, bool *done)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- timediff_t timeout_ms;
- CURLcode result = CURLE_OK;
-
- *done = connssl->state == ssl_connection_complete;
- if(*done)
- return CURLE_OK;
-
- /* Step 1: create session, start handshake. */
- if(connssl->connecting_state == ssl_connect_1) {
- /* 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");
- result = CURLE_OPERATION_TIMEDOUT;
- }
- else
- result = gskit_connect_step1(cf, data);
- }
-
- /* Handle handshake pipelining. */
- if(!result)
- if(pipe_ssloverssl(cf, data, SOS_READ | SOS_WRITE) < 0)
- result = CURLE_SSL_CONNECT_ERROR;
-
- /* Step 2: check if handshake is over. */
- if(!result && connssl->connecting_state == ssl_connect_2) {
- /* 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");
- result = CURLE_OPERATION_TIMEDOUT;
- }
- else
- result = gskit_connect_step2(cf, data, nonblocking);
- }
-
- /* Handle handshake pipelining. */
- if(!result)
- if(pipe_ssloverssl(cf, data, SOS_READ | SOS_WRITE) < 0)
- result = CURLE_SSL_CONNECT_ERROR;
-
- /* Step 3: gather certificate info, verify host. */
- if(!result && connssl->connecting_state == ssl_connect_3)
- result = gskit_connect_step3(cf, data);
-
- if(result)
- close_one(cf, data);
- else if(connssl->connecting_state == ssl_connect_done) {
- connssl->state = ssl_connection_complete;
- connssl->connecting_state = ssl_connect_1;
- *done = TRUE;
- }
-
- return result;
-}
-
-
-static CURLcode gskit_connect_nonblocking(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- bool *done)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- CURLcode result;
-
- result = gskit_connect_common(cf, data, TRUE, done);
- if(*done || result)
- connssl->connecting_state = ssl_connect_1;
- return result;
-}
-
-
-static CURLcode gskit_connect(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- CURLcode result;
- bool done;
-
- connssl->connecting_state = ssl_connect_1;
- result = gskit_connect_common(cf, data, FALSE, &done);
- if(result)
- return result;
-
- DEBUGASSERT(done);
-
- return CURLE_OK;
-}
-
-
-static void gskit_close(struct Curl_cfilter *cf, struct Curl_easy *data)
-{
- close_one(cf, data);
-}
-
-
-static int gskit_shutdown(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- int what;
- int rc;
- char buf[120];
- int loop = 10; /* don't get stuck */
-
- DEBUGASSERT(BACKEND);
-
- if(!BACKEND->handle)
- return 0;
-
-#ifndef CURL_DISABLE_FTP
- if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
- return 0;
-#endif
-
- close_one(cf, data);
- rc = 0;
- what = SOCKET_READABLE(Curl_conn_cf_get_socket(cf, data),
- SSL_SHUTDOWN_TIMEOUT);
-
- while(loop--) {
- ssize_t nread;
-
- if(what < 0) {
- /* anything that gets here is fatally bad */
- failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
- rc = -1;
- break;
- }
-
- if(!what) { /* timeout */
- failf(data, "SSL shutdown timeout");
- break;
- }
-
- /* Something to read, let's do it and hope that it is the close
- notify alert from the server. No way to gsk_secure_soc_read() now, so
- use read(). */
-
- nread = read(Curl_conn_cf_get_socket(cf, data), buf, sizeof(buf));
-
- if(nread < 0) {
- char buffer[STRERROR_LEN];
- failf(data, "read: %s", Curl_strerror(errno, buffer, sizeof(buffer)));
- rc = -1;
- }
-
- if(nread <= 0)
- break;
-
- what = SOCKET_READABLE(Curl_conn_cf_get_socket(cf, data), 0);
- }
-
- return rc;
-}
-
-
-static size_t gskit_version(char *buffer, size_t size)
-{
- return msnprintf(buffer, size, "GSKit");
-}
-
-
-static int gskit_check_cxn(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- struct ssl_connect_data *connssl = cf->ctx;
- int err;
- int errlen;
-
- (void)data;
- /* The only thing that can be tested here is at the socket level. */
- DEBUGASSERT(BACKEND);
-
- if(!BACKEND->handle)
- return 0; /* connection has been closed */
-
- err = 0;
- errlen = sizeof(err);
-
- if(getsockopt(Curl_conn_cf_get_socket(cf, data), SOL_SOCKET, SO_ERROR,
- (unsigned char *) &err, &errlen) ||
- errlen != sizeof(err) || err)
- return 0; /* connection has been closed */
-
- return -1; /* connection status unknown */
-}
-
-static void *gskit_get_internals(struct ssl_connect_data *connssl,
- CURLINFO info UNUSED_PARAM)
-{
- (void)info;
- DEBUGASSERT(BACKEND);
- return BACKEND->handle;
-}
-
-const struct Curl_ssl Curl_ssl_gskit = {
- { CURLSSLBACKEND_GSKIT, "gskit" }, /* info */
-
- SSLSUPP_CERTINFO |
- SSLSUPP_PINNEDPUBKEY,
-
- sizeof(struct gskit_ssl_backend_data),
-
- gskit_init, /* init */
- gskit_cleanup, /* cleanup */
- gskit_version, /* version */
- gskit_check_cxn, /* check_cxn */
- gskit_shutdown, /* shutdown */
- Curl_none_data_pending, /* data_pending */
- Curl_none_random, /* random */
- Curl_none_cert_status_request, /* cert_status_request */
- gskit_connect, /* connect */
- gskit_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_get_select_socks, /* getsock */
- gskit_get_internals, /* get_internals */
- gskit_close, /* close_one */
- Curl_none_close_all, /* close_all */
- /* No session handling for GSKit */
- Curl_none_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 */
- NULL, /* sha256sum */
- NULL, /* associate_connection */
- NULL, /* disassociate_connection */
- NULL, /* free_multi_ssl_backend_data */
- gskit_recv, /* recv decrypted data */
- gskit_send, /* send data to encrypt */
-};
-
-#endif /* USE_GSKIT */
diff --git a/lib/vtls/gskit.h b/lib/vtls/gskit.h
deleted file mode 100644
index c71e6a0117..0000000000
--- a/lib/vtls/gskit.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef HEADER_CURL_GSKIT_H
-#define HEADER_CURL_GSKIT_H
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) Daniel Stenberg, , 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.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.
- *
- * SPDX-License-Identifier: curl
- *
- ***************************************************************************/
-#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 */
diff --git a/lib/vtls/hostcheck.c b/lib/vtls/hostcheck.c
index d061c6356f..2726dca7f2 100644
--- a/lib/vtls/hostcheck.c
+++ b/lib/vtls/hostcheck.c
@@ -24,8 +24,7 @@
#include "curl_setup.h"
-#if defined(USE_OPENSSL) \
- || defined(USE_GSKIT) \
+#if defined(USE_OPENSSL) \
|| defined(USE_SCHANNEL)
/* these backends use functions from this file */
@@ -133,4 +132,4 @@ bool Curl_cert_hostcheck(const char *match, size_t matchlen,
return FALSE;
}
-#endif /* OPENSSL, GSKIT or schannel+wince */
+#endif /* OPENSSL or SCHANNEL */
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index 404f71a178..2dbf27bcb8 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -1240,8 +1240,6 @@ const struct Curl_ssl *Curl_ssl =
&Curl_ssl_sectransp;
#elif defined(USE_GNUTLS)
&Curl_ssl_gnutls;
-#elif defined(USE_GSKIT)
- &Curl_ssl_gskit;
#elif defined(USE_MBEDTLS)
&Curl_ssl_mbedtls;
#elif defined(USE_RUSTLS)
@@ -1266,9 +1264,6 @@ static const struct Curl_ssl *available_backends[] = {
#if defined(USE_GNUTLS)
&Curl_ssl_gnutls,
#endif
-#if defined(USE_GSKIT)
- &Curl_ssl_gskit,
-#endif
#if defined(USE_MBEDTLS)
&Curl_ssl_mbedtls,
#endif
diff --git a/lib/vtls/vtls_int.h b/lib/vtls/vtls_int.h
index ceece84ca9..a6e4544a87 100644
--- a/lib/vtls/vtls_int.h
+++ b/lib/vtls/vtls_int.h
@@ -217,7 +217,6 @@ CURLcode Curl_ssl_addsessionid(struct Curl_cfilter *cf,
#include "openssl.h" /* OpenSSL versions */
#include "gtls.h" /* GnuTLS versions */
-#include "gskit.h" /* Global Secure ToolKit versions */
#include "wolfssl.h" /* wolfSSL versions */
#include "schannel.h" /* Schannel SSPI version */
#include "sectransp.h" /* SecureTransport (Darwin) version */
diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c
index a3feba26d9..c3fd3a30bb 100644
--- a/lib/vtls/x509asn1.c
+++ b/lib/vtls/x509asn1.c
@@ -24,24 +24,18 @@
#include "curl_setup.h"
-#if defined(USE_GSKIT) || defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \
+#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \
defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
-#if defined(USE_GSKIT) || defined(USE_WOLFSSL) || defined(USE_SCHANNEL)
+#if defined(USE_WOLFSSL) || defined(USE_SCHANNEL)
#define WANT_PARSEX509 /* uses Curl_parseX509() */
#endif
-#if defined(USE_GSKIT) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
- defined(USE_SECTRANSP)
+#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
#define WANT_EXTRACT_CERTINFO /* uses Curl_extract_certinfo() */
#define WANT_PARSEX509 /* ... uses Curl_parseX509() */
#endif
-#if defined(USE_GSKIT)
-#define WANT_VERIFYHOST /* uses Curl_verifyhost () */
-#define WANT_PARSEX509 /* ... uses Curl_parseX509() */
-#endif
-
#include
#include "urldata.h"
#include "strcase.h"
@@ -1261,8 +1255,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data,
#endif /* WANT_EXTRACT_CERTINFO */
-#endif /* USE_GSKIT or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL * or
- USE_SECTRANSP */
+#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP */
#ifdef WANT_VERIFYHOST
diff --git a/lib/vtls/x509asn1.h b/lib/vtls/x509asn1.h
index e82545a758..23a67b828a 100644
--- a/lib/vtls/x509asn1.h
+++ b/lib/vtls/x509asn1.h
@@ -27,7 +27,7 @@
#include "curl_setup.h"
-#if defined(USE_GSKIT) || defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \
+#if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \
defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
#include "cfilters.h"
@@ -76,6 +76,5 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, int certnum,
const char *beg, const char *end);
CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data,
const char *beg, const char *end);
-#endif /* USE_GSKIT or USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL
- * or USE_SECTRANSP */
+#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP */
#endif /* HEADER_CURL_X509ASN1_H */
diff --git a/packages/OS400/README.OS400 b/packages/OS400/README.OS400
index 6790f6f251..efaf059723 100644
--- a/packages/OS400/README.OS400
+++ b/packages/OS400/README.OS400
@@ -39,22 +39,6 @@ header files are thus altered during build process to use this pragma, in
order to force libcurl enums of being type int (the pragma disposition in use
before inclusion is restored before resuming the including unit compilation).
- Secure socket layer is provided by the IBM GSKit API: unlike other SSL
-implementations, GSKit is based on "certificate stores" or keyrings
-rather than individual certificate/key files. Certificate stores, as well as
-"certificate labels" are managed by external IBM-defined applications.
- There are two ways to specify an SSL context:
-- By an application identifier.
-- By a keyring file pathname and (optionally) certificate label.
- To identify an SSL context by application identifier, use option
-SETOPT_SSLCERT to specify the application identifier.
- To address an SSL context by keyring and certificate label, use CURLOPT_CAINFO
-to set-up the keyring pathname, CURLOPT_SSLCERT to define the certificate label
-(omitting it will cause the default certificate in keyring to be used) and
-CURLOPT_KEYPASSWD to give the keyring password. If SSL is used without
-defining any of these options, the default (i.e.: system) keyring is used for
-server certificate validation.
-
Non-standard EBCDIC wrapper prototypes are defined in an additional header
file: ccsidcurl.h. These should be self-explanatory to an OS/400-aware
designer. CCSID 0 can be used to select the current job's CCSID.
diff --git a/packages/OS400/os400sys.c b/packages/OS400/os400sys.c
index c37cdb4e21..510c1c4ec4 100644
--- a/packages/OS400/os400sys.c
+++ b/packages/OS400/os400sys.c
@@ -44,11 +44,6 @@
#include
#endif
-#ifdef USE_GSKIT
-#include
-#include
-#endif
-
#ifdef HAVE_GSSAPI
#include
#endif
@@ -344,371 +339,6 @@ Curl_getaddrinfo_a(const char *nodename, const char *servname,
return status;
}
-#ifdef USE_GSKIT
-
-/* ASCII wrappers for the GSKit procedures. */
-
-/*
- * EBCDIC --> ASCII string mapping table.
- * Some strings returned by GSKit are dynamically allocated and automatically
- * released when closing the handle.
- * To provide the same functionality, we use a "private" handle that
- * holds the GSKit handle and a list of string mappings. This will allow
- * avoid conversion of already converted strings and releasing them upon
- * close time.
- */
-
-struct gskstrlist {
- struct gskstrlist *next;
- const char *ebcdicstr;
- const char *asciistr;
-};
-
-struct Curl_gsk_descriptor {
- gsk_handle h;
- struct gskstrlist *strlist;
-};
-
-int Curl_gsk_environment_open(gsk_handle *my_env_handle)
-{
- struct Curl_gsk_descriptor *p;
- int rc;
-
- if(!my_env_handle)
- return GSK_OS400_ERROR_INVALID_POINTER;
- p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
- if(!p)
- return GSK_INSUFFICIENT_STORAGE;
- p->strlist = (struct gskstrlist *) NULL;
- rc = gsk_environment_open(&p->h);
- if(rc != GSK_OK)
- free(p);
- else
- *my_env_handle = (gsk_handle) p;
- return rc;
-}
-
-int Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
- gsk_handle *my_session_handle)
-{
- struct Curl_gsk_descriptor *p;
- gsk_handle h;
- int rc;
-
- if(!my_env_handle)
- return GSK_INVALID_HANDLE;
- if(!my_session_handle)
- return GSK_OS400_ERROR_INVALID_POINTER;
- h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
- p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
- if(!p)
- return GSK_INSUFFICIENT_STORAGE;
- p->strlist = (struct gskstrlist *) NULL;
- rc = gsk_secure_soc_open(h, &p->h);
- if(rc != GSK_OK)
- free(p);
- else
- *my_session_handle = (gsk_handle) p;
- return rc;
-}
-
-static void gsk_free_handle(struct Curl_gsk_descriptor *p)
-{
- struct gskstrlist *q;
-
- while((q = p->strlist)) {
- p->strlist = q;
- free((void *) q->asciistr);
- free(q);
- }
- free(p);
-}
-
-int Curl_gsk_environment_close(gsk_handle *my_env_handle)
-{
- struct Curl_gsk_descriptor *p;
- int rc;
-
- if(!my_env_handle)
- return GSK_OS400_ERROR_INVALID_POINTER;
- if(!*my_env_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) *my_env_handle;
- rc = gsk_environment_close(&p->h);
- if(rc == GSK_OK) {
- gsk_free_handle(p);
- *my_env_handle = (gsk_handle) NULL;
- }
- return rc;
-}
-
-
-int Curl_gsk_secure_soc_close(gsk_handle *my_session_handle)
-{
- struct Curl_gsk_descriptor *p;
- int rc;
-
- if(!my_session_handle)
- return GSK_OS400_ERROR_INVALID_POINTER;
- if(!*my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) *my_session_handle;
- rc = gsk_secure_soc_close(&p->h);
- if(rc == GSK_OK) {
- gsk_free_handle(p);
- *my_session_handle = (gsk_handle) NULL;
- }
- return rc;
-}
-
-int Curl_gsk_environment_init(gsk_handle my_env_handle)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_env_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_env_handle;
- return gsk_environment_init(p->h);
-}
-
-
-int Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_init(p->h);
-}
-
-
-int
-Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
- const char *buffer, int bufSize)
-{
- struct Curl_gsk_descriptor *p;
- char *ebcdicbuf;
- int rc;
-
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- if(!buffer)
- return GSK_OS400_ERROR_INVALID_POINTER;
- if(bufSize < 0)
- return GSK_ATTRIBUTE_INVALID_LENGTH;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- if(!bufSize)
- bufSize = strlen(buffer);
- ebcdicbuf = malloc(bufSize + 1);
- if(!ebcdicbuf)
- return GSK_INSUFFICIENT_STORAGE;
- QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
- ebcdicbuf[bufSize] = '\0';
- rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
- free(ebcdicbuf);
- return rc;
-}
-
-
-int
-Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
- GSK_ENUM_VALUE enumValue)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_set_enum(p->h, enumID, enumValue);
-}
-
-
-int
-Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
- GSK_NUM_ID numID, int numValue)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_set_numeric_value(p->h, numID, numValue);
-}
-
-
-int
-Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
- GSK_CALLBACK_ID callBackID,
- void *callBackAreaPtr)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
-}
-
-
-static int
-cachestring(struct Curl_gsk_descriptor *p,
- const char *ebcdicbuf, int bufsize, const char **buffer)
-{
- int rc;
- char *asciibuf;
- struct gskstrlist *sp;
-
- for(sp = p->strlist; sp; sp = sp->next)
- if(sp->ebcdicstr == ebcdicbuf)
- break;
- if(!sp) {
- sp = (struct gskstrlist *) malloc(sizeof(*sp));
- if(!sp)
- return GSK_INSUFFICIENT_STORAGE;
- asciibuf = malloc(bufsize + 1);
- if(!asciibuf) {
- free(sp);
- return GSK_INSUFFICIENT_STORAGE;
- }
- QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
- asciibuf[bufsize] = '\0';
- sp->ebcdicstr = ebcdicbuf;
- sp->asciistr = asciibuf;
- sp->next = p->strlist;
- p->strlist = sp;
- }
- *buffer = sp->asciistr;
- return GSK_OK;
-}
-
-
-int
-Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
- const char **buffer, int *bufSize)
-{
- struct Curl_gsk_descriptor *p;
- int rc;
- const char *mybuf;
- int mylen;
-
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- if(!buffer || !bufSize)
- return GSK_OS400_ERROR_INVALID_POINTER;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen);
- if(rc != GSK_OK)
- return rc;
- rc = cachestring(p, mybuf, mylen, buffer);
- if(rc == GSK_OK)
- *bufSize = mylen;
- return rc;
-}
-
-
-int
-Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
- GSK_ENUM_VALUE *enumValue)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_get_enum(p->h, enumID, enumValue);
-}
-
-
-int
-Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
- GSK_NUM_ID numID, int *numValue)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- return gsk_attribute_get_numeric_value(p->h, numID, numValue);
-}
-
-
-int
-Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
- GSK_CERT_ID certID,
- const gsk_cert_data_elem **certDataElem,
- int *certDataElementCount)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_gsk_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_gsk_handle;
- /* No need to convert code: text results are already in ASCII. */
- return gsk_attribute_get_cert_info(p->h, certID,
- certDataElem, certDataElementCount);
-}
-
-
-int
-Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_misc(p->h, miscID);
-}
-
-
-int
-Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char *readBuffer,
- int readBufSize, int *amtRead)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
-}
-
-
-int
-Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char *writeBuffer,
- int writeBufSize, int *amtWritten)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
-}
-
-
-const char *
-Curl_gsk_strerror_a(int gsk_return_value)
-{
- return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
-}
-
-int
-Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
- int IOCompletionPort,
- Qso_OverlappedIO_t *communicationsArea)
-{
- struct Curl_gsk_descriptor *p;
-
- if(!my_session_handle)
- return GSK_INVALID_HANDLE;
- p = (struct Curl_gsk_descriptor *) my_session_handle;
- return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
-}
-
-#endif /* USE_GSKIT */
-
#ifdef HAVE_GSSAPI
/* ASCII wrappers for the GSSAPI procedures. */
diff --git a/tests/unit/unit1397.c b/tests/unit/unit1397.c
index 3ae75618d5..bf65d9231a 100644
--- a/tests/unit/unit1397.c
+++ b/tests/unit/unit1397.c
@@ -34,7 +34,7 @@ static void unit_stop(void)
}
/* only these backends define the tested functions */
-#if defined(USE_OPENSSL) || defined(USE_GSKIT) || defined(USE_SCHANNEL)
+#if defined(USE_OPENSSL) || defined(USE_SCHANNEL)
#include "vtls/hostcheck.h"
struct testcase {
const char *host;
diff --git a/tests/unit/unit1651.c b/tests/unit/unit1651.c
index 3e3a0071d8..58d2f10762 100644
--- a/tests/unit/unit1651.c
+++ b/tests/unit/unit1651.c
@@ -34,8 +34,7 @@ static void unit_stop(void)
{
}
-#if defined(USE_GSKIT) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
- defined(USE_SECTRANSP)
+#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP)
/* cert captured from gdb when connecting to curl.se on October 26
2018 */