mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
Gtz Babin-Ebell's OpenSSL ENGINE patch
This commit is contained in:
parent
558d12d7f6
commit
af6c394785
38
CHANGES
38
CHANGES
@ -6,10 +6,46 @@
|
|||||||
|
|
||||||
History of Changes
|
History of Changes
|
||||||
|
|
||||||
|
Daniel (17 December 2001)
|
||||||
|
- Götz Babin-Ebell dove into the dark dungeons of the OpenSSL ENGINE stuff and
|
||||||
|
made libcurl support it! This allows libcurl to do SSL connections with the
|
||||||
|
private key stored in external hardware.
|
||||||
|
|
||||||
|
To make this good, he had to add a bunch of new library options that'll be
|
||||||
|
useful to others as well:
|
||||||
|
|
||||||
|
CURLOPT_SSLCERTTYPE set SSL cert type (PEM/DER)
|
||||||
|
CURLOPT_SSLKEY set SSL private key (file)
|
||||||
|
CURLOPT_SSLKEYTYPE: set SSL key type (PEM/DER/ENG)
|
||||||
|
CURLOPT_SSLKEYPASSWD: set the passphrase for your private key
|
||||||
|
(CURLOPT_SSLCERTPASSWD is an alias)
|
||||||
|
CURLOPT_SSLENGINE: set the name of the crypto engine
|
||||||
|
(returns CURLE_SSL_ENGINE_NOTFOUND on error)
|
||||||
|
CURLOPT_SSLENGINE_DEFAULT: set the default engine
|
||||||
|
|
||||||
|
There are two new failure codes:
|
||||||
|
|
||||||
|
CURLE_SSL_ENGINE_NOTFOUND
|
||||||
|
CURLE_SSL_ENGINE_SETFAILED
|
||||||
|
|
||||||
Daniel (14 December 2001)
|
Daniel (14 December 2001)
|
||||||
|
- We have "branched" the source-tree at a few places. Checkout the CVS sources
|
||||||
|
with the 'multi-dev' label to get the latest multi interface development
|
||||||
|
tree. The idea is to only branch affected files and to restrict the branch
|
||||||
|
to the v8 multi interface development only.
|
||||||
|
|
||||||
|
*NOTE* that if we get bug reports and patches etc, we might need to apply
|
||||||
|
them in both branches!
|
||||||
|
|
||||||
|
The multi-dev branch is what we are gonna use as main branch in the future
|
||||||
|
if it turns out successful. Thus, we must maintain both now in case we need
|
||||||
|
them. The current main branch will be used if we want to release a 7.9.3 or
|
||||||
|
perhaps a 7.10 release before version 8. Which is very likely.
|
||||||
|
|
||||||
- Marcus Webster provided code for the new CURLFORM_CONTENTHEADER option for
|
- Marcus Webster provided code for the new CURLFORM_CONTENTHEADER option for
|
||||||
curl_formadd(), that lets an application add a set of headers for that
|
curl_formadd(), that lets an application add a set of headers for that
|
||||||
particular part in a multipart/form-post. We need to add
|
particular part in a multipart/form-post. He also provided a section to the
|
||||||
|
man page that describes the new option.
|
||||||
|
|
||||||
Daniel (11 December 2001)
|
Daniel (11 December 2001)
|
||||||
- Ben Greear made me aware of the fact that the Curl_failf() usage internally
|
- Ben Greear made me aware of the fact that the Curl_failf() usage internally
|
||||||
|
@ -392,6 +392,10 @@ else
|
|||||||
OPENSSL_ENABLED=1)
|
OPENSSL_ENABLED=1)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl Check for the OpenSSL engine header, it is kind of "separated"
|
||||||
|
dnl from the main SSL check
|
||||||
|
AC_CHECK_HEADERS(openssl/engine.h)
|
||||||
|
|
||||||
AC_SUBST(OPENSSL_ENABLED)
|
AC_SUBST(OPENSSL_ENABLED)
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
@ -78,3 +78,4 @@ that have contributed with non-trivial parts:
|
|||||||
- John Lask <johnlask@hotmail.com>
|
- John Lask <johnlask@hotmail.com>
|
||||||
- Eric Lavigne <erlavigne@wanadoo.fr>
|
- Eric Lavigne <erlavigne@wanadoo.fr>
|
||||||
- Marcus Webster <marcus.webster@phocis.com>
|
- Marcus Webster <marcus.webster@phocis.com>
|
||||||
|
- Götz Babin-Ebell <babinebell@trustcenter.de>
|
||||||
|
@ -156,6 +156,8 @@ typedef enum {
|
|||||||
CURLE_OBSOLETE, /* 50 - removed after 7.7.3 */
|
CURLE_OBSOLETE, /* 50 - removed after 7.7.3 */
|
||||||
CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */
|
CURLE_SSL_PEER_CERTIFICATE, /* 51 - peer's certificate wasn't ok */
|
||||||
CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
|
CURLE_GOT_NOTHING, /* 52 - when this is a specific error */
|
||||||
|
CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */
|
||||||
|
CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as default */
|
||||||
|
|
||||||
CURL_LAST /* never use! */
|
CURL_LAST /* never use! */
|
||||||
} CURLcode;
|
} CURLcode;
|
||||||
@ -279,8 +281,10 @@ typedef enum {
|
|||||||
/* name of the file keeping your private SSL-certificate */
|
/* name of the file keeping your private SSL-certificate */
|
||||||
CINIT(SSLCERT, OBJECTPOINT, 25),
|
CINIT(SSLCERT, OBJECTPOINT, 25),
|
||||||
|
|
||||||
/* password for the SSL-certificate */
|
/* password for the SSL-private key, keep this for compatibility */
|
||||||
CINIT(SSLCERTPASSWD, OBJECTPOINT, 26),
|
CINIT(SSLCERTPASSWD, OBJECTPOINT, 26),
|
||||||
|
/* password for the SSL private key */
|
||||||
|
CINIT(SSLKEYPASSWD, OBJECTPOINT, 26),
|
||||||
|
|
||||||
/* send TYPE parameter? */
|
/* send TYPE parameter? */
|
||||||
CINIT(CRLF, LONG, 27),
|
CINIT(CRLF, LONG, 27),
|
||||||
@ -467,6 +471,23 @@ typedef enum {
|
|||||||
PASV command. */
|
PASV command. */
|
||||||
CINIT(FTP_USE_EPSV, LONG, 85),
|
CINIT(FTP_USE_EPSV, LONG, 85),
|
||||||
|
|
||||||
|
/* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
|
||||||
|
CINIT(SSLCERTTYPE, OBJECTPOINT, 86),
|
||||||
|
|
||||||
|
/* name of the file keeping your private SSL-key */
|
||||||
|
CINIT(SSLKEY, OBJECTPOINT, 87),
|
||||||
|
|
||||||
|
/* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
|
||||||
|
CINIT(SSLKEYTYPE, OBJECTPOINT, 88),
|
||||||
|
|
||||||
|
/* crypto engine for the SSL-sub system */
|
||||||
|
CINIT(SSLENGINE, OBJECTPOINT, 89),
|
||||||
|
|
||||||
|
/* set the crypto engine for the SSL-sub system as default
|
||||||
|
the param has no meaning...
|
||||||
|
*/
|
||||||
|
CINIT(SSLENGINE_DEFAULT, LONG, 90),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unusued */
|
CURLOPT_LASTENTRY /* the last unusued */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
#ifdef MALLOCDEBUG
|
#ifdef MALLOCDEBUG
|
||||||
|
|
||||||
|
#include "setup.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef HAVE_MEMORY_H
|
#ifdef HAVE_MEMORY_H
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
@ -34,9 +34,9 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
|
||||||
#ifdef VMS
|
#ifdef VMS
|
||||||
#include "config-vms.h"
|
#include "../config-vms.h"
|
||||||
#else
|
#else
|
||||||
#include "config.h" /* the configure script results */
|
#include "../config.h" /* the configure script results */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -46,13 +46,14 @@
|
|||||||
#endif
|
#endif
|
||||||
#ifdef macintosh
|
#ifdef macintosh
|
||||||
/* hand-modified MacOS config.h! */
|
/* hand-modified MacOS config.h! */
|
||||||
#include "config-mac.h"
|
#include "../config-mac.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __cplusplus /* (rabe) */
|
#ifndef __cplusplus /* (rabe) */
|
||||||
typedef char bool;
|
typedef char bool;
|
||||||
|
#define typedef_bool
|
||||||
#endif /* (rabe) */
|
#endif /* (rabe) */
|
||||||
|
|
||||||
#ifdef NEED_REENTRANT
|
#ifdef NEED_REENTRANT
|
||||||
|
133
lib/ssluse.c
133
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
|
* In order to be useful for every potential user, curl and libcurl are
|
||||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
* 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>
|
* Linas Vepstas <linas@linas.org> and Sampo Kellomaki <sampo@iki.fi>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -171,33 +172,55 @@ int random_the_seed(struct connectdata *conn)
|
|||||||
return nread;
|
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
|
static
|
||||||
int cert_stuff(struct connectdata *conn,
|
int cert_stuff(struct connectdata *conn,
|
||||||
char *cert_file,
|
char *cert_file,
|
||||||
char *key_file)
|
const char *cert_type,
|
||||||
|
char *key_file,
|
||||||
|
const char *key_type)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
|
int file_type;
|
||||||
|
|
||||||
if (cert_file != NULL) {
|
if (cert_file != NULL) {
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
X509 *x509;
|
X509 *x509;
|
||||||
|
|
||||||
if(data->set.cert_passwd) {
|
if(data->set.key_passwd) {
|
||||||
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
|
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
|
||||||
/*
|
/*
|
||||||
* If password has been given, we store that in the global
|
* If password has been given, we store that in the global
|
||||||
* area (*shudder*) for a while:
|
* area (*shudder*) for a while:
|
||||||
*/
|
*/
|
||||||
strcpy(global_passwd, data->set.cert_passwd);
|
strcpy(global_passwd, data->set.key_passwd);
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* We set the password in the callback userdata
|
* 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
|
#endif
|
||||||
/* Set passwd callback: */
|
/* Set passwd callback: */
|
||||||
SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback);
|
SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
|
if (SSL_CTX_use_certificate_file(conn->ssl.ctx,
|
||||||
cert_file,
|
cert_file,
|
||||||
SSL_FILETYPE_PEM) != 1) {
|
SSL_FILETYPE_PEM) != 1) {
|
||||||
@ -213,6 +236,83 @@ int cert_stuff(struct connectdata *conn,
|
|||||||
failf(data, "unable to set public key file");
|
failf(data, "unable to set public key file");
|
||||||
return(0);
|
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);
|
ssl=SSL_new(conn->ssl.ctx);
|
||||||
x509=SSL_get_certificate(ssl);
|
x509=SSL_get_certificate(ssl);
|
||||||
@ -269,6 +369,10 @@ void Curl_SSL_init(void)
|
|||||||
|
|
||||||
init_ssl++; /* never again */
|
init_ssl++; /* never again */
|
||||||
|
|
||||||
|
#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
|
||||||
|
ENGINE_load_builtin_engines();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Lets get nice error messages */
|
/* Lets get nice error messages */
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
|
|
||||||
@ -293,6 +397,10 @@ void Curl_SSL_cleanup(void)
|
|||||||
table. */
|
table. */
|
||||||
EVP_cleanup();
|
EVP_cleanup();
|
||||||
|
|
||||||
|
#ifdef HAVE_ENGINE_cleanup
|
||||||
|
ENGINE_cleanup();
|
||||||
|
#endif
|
||||||
|
|
||||||
init_ssl=0; /* not inited any more */
|
init_ssl=0; /* not inited any more */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -428,6 +536,13 @@ int Curl_SSL_Close_All(struct SessionHandle *data)
|
|||||||
/* free the cache data */
|
/* free the cache data */
|
||||||
free(data->state.session);
|
free(data->state.session);
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||||
|
if (data->engine)
|
||||||
|
{
|
||||||
|
ENGINE_free(data->engine);
|
||||||
|
data->engine = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,7 +684,11 @@ Curl_SSLConnect(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(data->set.cert) {
|
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() */
|
/* failf() is already done in cert_stuff() */
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
|
70
lib/url.c
70
lib/url.c
@ -790,11 +790,75 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
|||||||
*/
|
*/
|
||||||
data->set.cert = va_arg(param, char *);
|
data->set.cert = va_arg(param, char *);
|
||||||
break;
|
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;
|
break;
|
||||||
case CURLOPT_CRLF:
|
case CURLOPT_CRLF:
|
||||||
/*
|
/*
|
||||||
|
@ -58,6 +58,9 @@
|
|||||||
#include "openssl/pem.h"
|
#include "openssl/pem.h"
|
||||||
#include "openssl/ssl.h"
|
#include "openssl/ssl.h"
|
||||||
#include "openssl/err.h"
|
#include "openssl/err.h"
|
||||||
|
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
@ -111,6 +114,9 @@ enum protection_level {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_OPENSSL_ENGINE_H
|
||||||
|
typedef void ENGINE;
|
||||||
|
#endif
|
||||||
/* struct for data related to SSL and SSL connections */
|
/* struct for data related to SSL and SSL connections */
|
||||||
struct ssl_connect_data {
|
struct ssl_connect_data {
|
||||||
bool use; /* use ssl encrypted communications TRUE/FALSE */
|
bool use; /* use ssl encrypted communications TRUE/FALSE */
|
||||||
@ -525,8 +531,12 @@ struct UserDefined {
|
|||||||
char *cookie; /* HTTP cookie string to send */
|
char *cookie; /* HTTP cookie string to send */
|
||||||
struct curl_slist *headers; /* linked list of extra headers */
|
struct curl_slist *headers; /* linked list of extra headers */
|
||||||
struct HttpPost *httppost; /* linked list of POST data */
|
struct HttpPost *httppost; /* linked list of POST data */
|
||||||
char *cert; /* PEM-formatted certificate */
|
char *cert; /* certificate */
|
||||||
char *cert_passwd; /* plain text certificate password */
|
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 */
|
char *cookiejar; /* dump all cookies to this file */
|
||||||
bool crlf; /* convert crlf on ftp upload(?) */
|
bool crlf; /* convert crlf on ftp upload(?) */
|
||||||
struct curl_slist *quote; /* before the transfer */
|
struct curl_slist *quote; /* before the transfer */
|
||||||
@ -594,6 +604,9 @@ struct SessionHandle {
|
|||||||
struct UrlState state; /* struct for fields used for state info and
|
struct UrlState state; /* struct for fields used for state info and
|
||||||
other dynamic purposes */
|
other dynamic purposes */
|
||||||
struct PureInfo info; /* stats, reports and info data */
|
struct PureInfo info; /* stats, reports and info data */
|
||||||
|
#ifdef USE_SSLEAY
|
||||||
|
ENGINE* engine;
|
||||||
|
#endif /* USE_SSLEAY */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LIBCURL_NAME "libcurl"
|
#define LIBCURL_NAME "libcurl"
|
||||||
|
51
src/main.c
51
src/main.c
@ -77,7 +77,9 @@
|
|||||||
#define DEFAULT_MAXREDIRS 50L
|
#define DEFAULT_MAXREDIRS 50L
|
||||||
|
|
||||||
#ifndef __cplusplus /* (rabe) */
|
#ifndef __cplusplus /* (rabe) */
|
||||||
|
#ifndef typedef_bool
|
||||||
typedef char bool;
|
typedef char bool;
|
||||||
|
#endif
|
||||||
#endif /* (rabe) */
|
#endif /* (rabe) */
|
||||||
|
|
||||||
#define CURL_PROGRESS_STATS 0 /* default progress display */
|
#define CURL_PROGRESS_STATS 0 /* default progress display */
|
||||||
@ -318,6 +320,11 @@ static void help(void)
|
|||||||
" --egd-file <file> EGD socket path for random data (SSL)\n"
|
" --egd-file <file> EGD socket path for random data (SSL)\n"
|
||||||
" -e/--referer Referer page (H)");
|
" -e/--referer Referer page (H)");
|
||||||
puts(" -E/--cert <cert[:passwd]> Specifies your certificate file and password (HTTPS)\n"
|
puts(" -E/--cert <cert[:passwd]> Specifies your certificate file and password (HTTPS)\n"
|
||||||
|
" --cert-type <type> Specifies your certificate file type (DER/PEM/ENG) (HTTPS)\n"
|
||||||
|
" --key <key> Specifies your private key file (HTTPS)\n"
|
||||||
|
" --key-type <type> Specifies your private key file type (DER/PEM/ENG) (HTTPS)\n"
|
||||||
|
" --pass <pass> Specifies your passphrase for the private key (HTTPS)");
|
||||||
|
puts(" --engine <eng> Specifies the crypto engine to use (HTTPS)\n"
|
||||||
" --cacert <file> CA certifciate to verify peer against (SSL)\n"
|
" --cacert <file> CA certifciate to verify peer against (SSL)\n"
|
||||||
" --ciphers <list> What SSL ciphers to use (SSL)\n"
|
" --ciphers <list> What SSL ciphers to use (SSL)\n"
|
||||||
" --connect-timeout <seconds> Maximum time allowed for connection\n"
|
" --connect-timeout <seconds> Maximum time allowed for connection\n"
|
||||||
@ -420,8 +427,12 @@ struct Configurable {
|
|||||||
|
|
||||||
char *cipher_list;
|
char *cipher_list;
|
||||||
char *cert;
|
char *cert;
|
||||||
|
char *cert_type;
|
||||||
char *cacert;
|
char *cacert;
|
||||||
char *cert_passwd;
|
char *key;
|
||||||
|
char *key_type;
|
||||||
|
char *key_passwd;
|
||||||
|
char *engine;
|
||||||
bool crlf;
|
bool crlf;
|
||||||
char *customrequest;
|
char *customrequest;
|
||||||
char *krb4level;
|
char *krb4level;
|
||||||
@ -884,6 +895,11 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
{"e", "referer", TRUE},
|
{"e", "referer", TRUE},
|
||||||
{"E", "cert", TRUE},
|
{"E", "cert", TRUE},
|
||||||
{"Ea", "cacert", TRUE},
|
{"Ea", "cacert", TRUE},
|
||||||
|
{"Eb","cert-type", TRUE},
|
||||||
|
{"Ec","key", TRUE},
|
||||||
|
{"Ed","key-type", TRUE},
|
||||||
|
{"Ee","pass", TRUE},
|
||||||
|
{"Ef","engine", TRUE},
|
||||||
{"f", "fail", FALSE},
|
{"f", "fail", FALSE},
|
||||||
{"F", "form", TRUE},
|
{"F", "form", TRUE},
|
||||||
{"g", "globoff", FALSE},
|
{"g", "globoff", FALSE},
|
||||||
@ -1180,11 +1196,28 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
if(subletter == 'a') {
|
switch(subletter) {
|
||||||
|
case 'a': /* CA info PEM file */
|
||||||
/* CA info PEM file */
|
/* CA info PEM file */
|
||||||
GetStr(&config->cacert, nextarg);
|
GetStr(&config->cacert, nextarg);
|
||||||
}
|
break;
|
||||||
else {
|
case 'b': /* cert file type */
|
||||||
|
GetStr(&config->cert_type, nextarg);
|
||||||
|
break;
|
||||||
|
case 'c': /* private key file */
|
||||||
|
GetStr(&config->key, nextarg);
|
||||||
|
break;
|
||||||
|
case 'd': /* private key file type */
|
||||||
|
GetStr(&config->key_type, nextarg);
|
||||||
|
break;
|
||||||
|
case 'e': /* private key passphrase */
|
||||||
|
GetStr(&config->key_passwd, nextarg);
|
||||||
|
break;
|
||||||
|
case 'f': /* crypto engine */
|
||||||
|
GetStr(&config->engine, nextarg);
|
||||||
|
break;
|
||||||
|
default: /* certificate file */
|
||||||
|
{
|
||||||
char *ptr = strchr(nextarg, ':');
|
char *ptr = strchr(nextarg, ':');
|
||||||
/* Since we live in a world of weirdness and confusion, the win32
|
/* Since we live in a world of weirdness and confusion, the win32
|
||||||
dudes can use : when using drive letters and thus
|
dudes can use : when using drive letters and thus
|
||||||
@ -1206,10 +1239,11 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
/* we have a password too */
|
/* we have a password too */
|
||||||
*ptr=0;
|
*ptr=0;
|
||||||
ptr++;
|
ptr++;
|
||||||
GetStr(&config->cert_passwd, ptr);
|
GetStr(&config->key_passwd, ptr);
|
||||||
}
|
}
|
||||||
GetStr(&config->cert, nextarg);
|
GetStr(&config->cert, nextarg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
/* fail hard on errors */
|
/* fail hard on errors */
|
||||||
@ -2214,6 +2248,8 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSLENGINE, config->engine);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1);
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_FILE, (FILE *)&outs); /* where to store */
|
curl_easy_setopt(curl, CURLOPT_FILE, (FILE *)&outs); /* where to store */
|
||||||
/* what call to write: */
|
/* what call to write: */
|
||||||
@ -2261,7 +2297,10 @@ operate(struct Configurable *config, int argc, char *argv[])
|
|||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, config->headers);
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, config->headers);
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
|
curl_easy_setopt(curl, CURLOPT_HTTPPOST, config->httppost);
|
||||||
curl_easy_setopt(curl, CURLOPT_SSLCERT, config->cert);
|
curl_easy_setopt(curl, CURLOPT_SSLCERT, config->cert);
|
||||||
curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, config->cert_passwd);
|
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSLKEY, config->key);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, config->key_type);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, config->key_passwd);
|
||||||
|
|
||||||
if(config->cacert) {
|
if(config->cacert) {
|
||||||
curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert);
|
curl_easy_setopt(curl, CURLOPT_CAINFO, config->cacert);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef __SETUP_H
|
#ifndef __CLIENT_SETUP_H
|
||||||
#define __SETUP_H
|
#define __CLIENT_SETUP_H
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* _ _ ____ _
|
* _ _ ____ _
|
||||||
* Project ___| | | | _ \| |
|
* Project ___| | | | _ \| |
|
||||||
|
Loading…
Reference in New Issue
Block a user