aboutsummaryrefslogtreecommitdiff
path: root/lib/vtls/nss.c
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2017-07-28 22:09:35 +0200
committerDaniel Stenberg <daniel@haxx.se>2017-08-28 14:56:58 +0200
commit70f1db321a2b39c75f679b5b052aa1ac0636bd50 (patch)
tree12aaca0592e90c31d856d0cfc4dd8e23bc8a667c /lib/vtls/nss.c
parentd65e6cc4fc9f68da4cbf8788c27714622ef9eead (diff)
vtls: encapsulate SSL backend-specific data
So far, all of the SSL backends' private data has been declared as part of the ssl_connect_data struct, in one big #if .. #elif .. #endif block. This can only work as long as the SSL backend is a compile-time option, something we want to change in the next commits. Therefore, let's encapsulate the exact data needed by each SSL backend into a private struct, and let's avoid bleeding any SSL backend-specific information into urldata.h. This is also necessary to allow multiple SSL backends to be compiled in at the same time, as e.g. OpenSSL's and CyaSSL's headers cannot be included in the same .c file. To avoid too many malloc() calls, we simply append the private structs to the connectdata struct in allocate_conn(). This requires us to take extra care of alignment issues: struct fields often need to be aligned on certain boundaries e.g. 32-bit values need to be stored at addresses that divide evenly by 4 (= 32 bit / 8 bit-per-byte). We do that by assuming that no SSL backend's private data contains any fields that need to be aligned on boundaries larger than `long long` (typically 64-bit) would need. Under this assumption, we simply add a dummy field of type `long long` to the `struct connectdata` struct. This field will never be accessed but acts as a placeholder for the four instances of ssl_backend_data instead. the size of each ssl_backend_data struct is stored in the SSL backend-specific metadata, to allow allocate_conn() to know how much extra space to allocate, and how to initialize the ssl[sockindex]->backend and proxy_ssl[sockindex]->backend pointers. This would appear to be a little complicated at first, but is really necessary to encapsulate the private data of each SSL backend correctly. And we need to encapsulate thusly if we ever want to allow selecting CyaSSL and OpenSSL at runtime, as their headers cannot be included within the same .c file (there are just too many conflicting definitions and declarations for that). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Diffstat (limited to 'lib/vtls/nss.c')
-rw-r--r--lib/vtls/nss.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index 95dbb9a2f..2d132f5b1 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -78,7 +78,15 @@
/* enough to fit the string "PEM Token #[0|1]" */
#define SLOTSIZE 13
-#define BACKEND connssl
+struct ssl_backend_data {
+ PRFileDesc *handle;
+ char *client_nickname;
+ struct Curl_easy *data;
+ struct curl_llist obj_list;
+ PK11GenericObject *obj_clicert;
+};
+
+#define BACKEND connssl->backend
static PRLock *nss_initlock = NULL;
static PRLock *nss_crllock = NULL;
@@ -1480,7 +1488,7 @@ static void Curl_nss_close(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
- if(BACKEND->handle || connssl_proxy->handle) {
+ if(BACKEND->handle || connssl_proxy->backend->handle) {
/* NSS closes the socket we previously handed to it, so we must mark it
as closed to avoid double close */
fake_sclose(conn->sock[sockindex]);
@@ -1489,9 +1497,9 @@ static void Curl_nss_close(struct connectdata *conn, int sockindex)
if(BACKEND->handle)
/* nss_close(connssl) will transitively close also
- connssl_proxy->handle if both are used. Clear it to avoid
+ connssl_proxy->backend->handle if both are used. Clear it to avoid
a double close leading to crash. */
- connssl_proxy->handle = NULL;
+ connssl_proxy->backend->handle = NULL;
nss_close(connssl);
nss_close(connssl_proxy);
@@ -1911,8 +1919,8 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
if(conn->proxy_ssl[sockindex].use) {
DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
- DEBUGASSERT(conn->proxy_ssl[sockindex].handle != NULL);
- nspr_io = conn->proxy_ssl[sockindex].handle;
+ DEBUGASSERT(conn->proxy_ssl[sockindex].backend->handle != NULL);
+ nspr_io = conn->proxy_ssl[sockindex].backend->handle;
second_layer = TRUE;
}
else {
@@ -2343,6 +2351,8 @@ const struct Curl_ssl Curl_ssl_nss = {
0, /* have_ssl_ctx */
1, /* support_https_proxy */
+ sizeof(struct ssl_backend_data),
+
Curl_nss_init, /* init */
Curl_nss_cleanup, /* cleanup */
Curl_nss_version, /* version */