aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/memdebug.h8
-rw-r--r--lib/setup.h7
-rw-r--r--lib/ssluse.c133
-rw-r--r--lib/url.c70
-rw-r--r--lib/urldata.h17
5 files changed, 220 insertions, 15 deletions
diff --git a/lib/memdebug.h b/lib/memdebug.h
index ebb240928..3c5c090f6 100644
--- a/lib/memdebug.h
+++ b/lib/memdebug.h
@@ -1,6 +1,14 @@
#ifdef MALLOCDEBUG
+#include "setup.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#endif
#include <stdio.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
diff --git a/lib/setup.h b/lib/setup.h
index bb9fc7355..cdec0f9d6 100644
--- a/lib/setup.h
+++ b/lib/setup.h
@@ -34,9 +34,9 @@
#ifdef HAVE_CONFIG_H
#ifdef VMS
-#include "config-vms.h"
+#include "../config-vms.h"
#else
-#include "config.h" /* the configure script results */
+#include "../config.h" /* the configure script results */
#endif
#else
@@ -46,13 +46,14 @@
#endif
#ifdef macintosh
/* hand-modified MacOS config.h! */
-#include "config-mac.h"
+#include "../config-mac.h"
#endif
#endif
#ifndef __cplusplus /* (rabe) */
typedef char bool;
+#define typedef_bool
#endif /* (rabe) */
#ifdef NEED_REENTRANT
diff --git a/lib/ssluse.c b/lib/ssluse.c
index df891e2db..55b0a2e09 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* In order to be useful for every potential user, curl and libcurl are
* dual-licensed under the MPL and the MIT/X-derivate licenses.
@@ -22,11 +22,12 @@
*****************************************************************************/
/*
- * The original SSL code was written by
+ * The original SSL code for curl was written by
* Linas Vepstas <linas@linas.org> and Sampo Kellomaki <sampo@iki.fi>
*/
#include "setup.h"
+
#include <string.h>
#include <stdlib.h>
@@ -171,33 +172,55 @@ int random_the_seed(struct connectdata *conn)
return nread;
}
+#ifndef SSL_FILETYPE_ENGINE
+#define SSL_FILETYPE_ENGINE 42
+#endif
+static int do_file_type(const char *type)
+{
+ if (!type || !type[0])
+ return SSL_FILETYPE_PEM;
+ if (curl_strequal(type, "PEM"))
+ return SSL_FILETYPE_PEM;
+ if (curl_strequal(type, "DER"))
+ return SSL_FILETYPE_ASN1;
+ if (curl_strequal(type, "ENG"))
+ return SSL_FILETYPE_ENGINE;
+ return -1;
+}
+
static
int cert_stuff(struct connectdata *conn,
char *cert_file,
- char *key_file)
+ const char *cert_type,
+ char *key_file,
+ const char *key_type)
{
struct SessionHandle *data = conn->data;
+ int file_type;
+
if (cert_file != NULL) {
SSL *ssl;
X509 *x509;
- if(data->set.cert_passwd) {
+ if(data->set.key_passwd) {
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
/*
* If password has been given, we store that in the global
* area (*shudder*) for a while:
*/
- strcpy(global_passwd, data->set.cert_passwd);
+ strcpy(global_passwd, data->set.key_passwd);
#else
/*
* We set the password in the callback userdata
*/
- SSL_CTX_set_default_passwd_cb_userdata(conn->ssl.ctx, data->set.cert_passwd);
+ SSL_CTX_set_default_passwd_cb_userdata(conn->ssl.ctx,
+ data->set.key_passwd);
#endif
/* Set passwd callback: */
SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback);
}
+#if 0
if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
cert_file,
SSL_FILETYPE_PEM) != 1) {
@@ -213,6 +236,83 @@ int cert_stuff(struct connectdata *conn,
failf(data, "unable to set public key file");
return(0);
}
+#else
+ /* The '#ifdef 0' section above was removed on 17-dec-2001 */
+
+ file_type = do_file_type(cert_type);
+
+ switch(file_type) {
+ case SSL_FILETYPE_PEM:
+ case SSL_FILETYPE_ASN1:
+ if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
+ cert_file,
+ file_type) != 1) {
+ failf(data, "unable to set certificate file (wrong password?)");
+ return 0;
+ }
+ break;
+ case SSL_FILETYPE_ENGINE:
+ failf(data, "file type ENG for certificate not implemented");
+ return 0;
+
+ default:
+ failf(data, "not supported file type '%s' for certificate", cert_type);
+ return 0;
+ }
+
+ file_type = do_file_type(key_type);
+
+ switch(file_type) {
+ case SSL_FILETYPE_PEM:
+ if (key_file == NULL)
+ /* cert & key can only be in PEM case in the same file */
+ key_file=cert_file;
+ case SSL_FILETYPE_ASN1:
+ if (SSL_CTX_use_PrivateKey_file(conn->ssl.ctx,
+ key_file,
+ file_type) != 1) {
+ failf(data, "unable to set private key file\n");
+ return 0;
+ }
+ break;
+ case SSL_FILETYPE_ENGINE:
+#ifdef HAVE_OPENSSL_ENGINE_H
+ { /* XXXX still needs some work */
+ EVP_PKEY *priv_key = NULL;
+ if (conn && conn->data && conn->data->engine) {
+ if (!key_file || !key_file[0]) {
+ failf(data, "no key set to load from crypto engine\n");
+ return 0;
+ }
+ priv_key = ENGINE_load_private_key(conn->data->engine,key_file,
+ data->set.key_passwd);
+ if (!priv_key) {
+ failf(data, "failed to load private key from crypto engine\n");
+ return 0;
+ }
+ if (SSL_CTX_use_PrivateKey(conn->ssl.ctx, priv_key) != 1) {
+ failf(data, "unable to set private key\n");
+ EVP_PKEY_free(priv_key);
+ return 0;
+ }
+ EVP_PKEY_free(priv_key); /* we don't need the handle any more... */
+ }
+ else {
+ failf(data, "crypto engine not set, can't load private key\n");
+ return 0;
+ }
+ }
+#else
+ failf(data, "file type ENG for private key not supported\n");
+ return 0;
+#endif
+ break;
+ default:
+ failf(data, "not supported file type for private key\n");
+ return 0;
+ }
+
+#endif
ssl=SSL_new(conn->ssl.ctx);
x509=SSL_get_certificate(ssl);
@@ -269,6 +369,10 @@ void Curl_SSL_init(void)
init_ssl++; /* never again */
+#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
+ ENGINE_load_builtin_engines();
+#endif
+
/* Lets get nice error messages */
SSL_load_error_strings();
@@ -293,6 +397,10 @@ void Curl_SSL_cleanup(void)
table. */
EVP_cleanup();
+#ifdef HAVE_ENGINE_cleanup
+ ENGINE_cleanup();
+#endif
+
init_ssl=0; /* not inited any more */
}
#else
@@ -428,6 +536,13 @@ int Curl_SSL_Close_All(struct SessionHandle *data)
/* free the cache data */
free(data->state.session);
}
+#ifdef HAVE_OPENSSL_ENGINE_H
+ if (data->engine)
+ {
+ ENGINE_free(data->engine);
+ data->engine = NULL;
+ }
+#endif
return 0;
}
@@ -569,7 +684,11 @@ Curl_SSLConnect(struct connectdata *conn)
}
if(data->set.cert) {
- if (!cert_stuff(conn, data->set.cert, data->set.cert)) {
+ if (!cert_stuff(conn,
+ data->set.cert,
+ data->set.cert_type,
+ data->set.key,
+ data->set.key_type)) {
/* failf() is already done in cert_stuff() */
return CURLE_SSL_CONNECT_ERROR;
}
diff --git a/lib/url.c b/lib/url.c
index 3b5482c2b..808f9c0be 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -790,11 +790,75 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
*/
data->set.cert = va_arg(param, char *);
break;
- case CURLOPT_SSLCERTPASSWD:
+ case CURLOPT_SSLCERTTYPE:
/*
- * String that holds the SSL certificate password.
+ * String that holds file type of the SSL certificate to use
*/
- data->set.cert_passwd = va_arg(param, char *);
+ data->set.cert_type = va_arg(param, char *);
+ break;
+ case CURLOPT_SSLKEY:
+ /*
+ * String that holds file name of the SSL certificate to use
+ */
+ data->set.key = va_arg(param, char *);
+ break;
+ case CURLOPT_SSLKEYTYPE:
+ /*
+ * String that holds file type of the SSL certificate to use
+ */
+ data->set.key_type = va_arg(param, char *);
+ break;
+ case CURLOPT_SSLKEYPASSWD:
+ /*
+ * String that holds the SSL private key password.
+ */
+ data->set.key_passwd = va_arg(param, char *);
+ break;
+ case CURLOPT_SSLENGINE:
+ /*
+ * String that holds the SSL crypto engine.
+ */
+#ifdef HAVE_OPENSSL_ENGINE_H
+ {
+ const char *cpTemp = va_arg(param, char *);
+ ENGINE *e;
+ if (cpTemp && cpTemp[0]) {
+ e = ENGINE_by_id(cpTemp);
+ if (e) {
+ if (data->engine) {
+ ENGINE_free(data->engine);
+ }
+ data->engine = e;
+ }
+ else {
+ failf(data, "SSL Engine '%s' not found", cpTemp);
+ return CURLE_SSL_ENGINE_NOTFOUND;
+ }
+ }
+ }
+#else
+ return CURLE_SSL_ENGINE_NOTFOUND;
+#endif
+ break;
+ case CURLOPT_SSLENGINE_DEFAULT:
+ /*
+ * flag to set engine as default.
+ */
+#ifdef HAVE_OPENSSL_ENGINE_H
+ if (data->engine) {
+ if (ENGINE_set_default(data->engine, ENGINE_METHOD_ALL) > 0) {
+#ifdef DEBUG
+ fprintf(stderr,"set default crypto engine\n");
+#endif
+ }
+ else {
+#ifdef DEBUG
+ failf(data, "set default crypto engine failed");
+#endif
+ return CURLE_SSL_ENGINE_SETFAILED;
+ }
+ }
+#endif
break;
case CURLOPT_CRLF:
/*
diff --git a/lib/urldata.h b/lib/urldata.h
index 3a7509dcd..23aaac379 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -58,6 +58,9 @@
#include "openssl/pem.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
+#ifdef HAVE_OPENSSL_ENGINE_H
+#include <openssl/engine.h>
+#endif
#else
#include "rsa.h"
#include "crypto.h"
@@ -111,6 +114,9 @@ enum protection_level {
};
#endif
+#ifndef HAVE_OPENSSL_ENGINE_H
+typedef void ENGINE;
+#endif
/* struct for data related to SSL and SSL connections */
struct ssl_connect_data {
bool use; /* use ssl encrypted communications TRUE/FALSE */
@@ -525,8 +531,12 @@ struct UserDefined {
char *cookie; /* HTTP cookie string to send */
struct curl_slist *headers; /* linked list of extra headers */
struct HttpPost *httppost; /* linked list of POST data */
- char *cert; /* PEM-formatted certificate */
- char *cert_passwd; /* plain text certificate password */
+ char *cert; /* certificate */
+ char *cert_type; /* format for certificate (default: PEM) */
+ char *key; /* private key */
+ char *key_type; /* format for private key (default: PEM) */
+ char *key_passwd; /* plain text private key password */
+ char *crypto_engine; /* name of the crypto engine to use */
char *cookiejar; /* dump all cookies to this file */
bool crlf; /* convert crlf on ftp upload(?) */
struct curl_slist *quote; /* before the transfer */
@@ -594,6 +604,9 @@ struct SessionHandle {
struct UrlState state; /* struct for fields used for state info and
other dynamic purposes */
struct PureInfo info; /* stats, reports and info data */
+#ifdef USE_SSLEAY
+ ENGINE* engine;
+#endif /* USE_SSLEAY */
};
#define LIBCURL_NAME "libcurl"