aboutsummaryrefslogtreecommitdiff
path: root/lib/ssluse.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2009-11-14 07:53:34 +0000
committerDaniel Stenberg <daniel@haxx.se>2009-11-14 07:53:34 +0000
commit9c49e51f7e223d7e48c2551e888d92a5e3cf76a6 (patch)
tree6d3f2a055ee6d080195386fc167bae4da8f109ac /lib/ssluse.c
parent90bc6ee8f38eec0dd6c7c8dbea22b0cba2998ee2 (diff)
- Camille Moncelier added support for the file type SSL_FILETYPE_ENGINE for
the client certificate. It also disable the key name test as some engines can select a private key/cert automatically (When there is only one key and/or certificate on the hardware device used by the engine)
Diffstat (limited to 'lib/ssluse.c')
-rw-r--r--lib/ssluse.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/lib/ssluse.c b/lib/ssluse.c
index 8cf834b14..67509eee8 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -310,9 +310,10 @@ int cert_stuff(struct connectdata *conn,
const char *key_type)
{
struct SessionHandle *data = conn->data;
- int file_type;
- if(cert_file != NULL) {
+ int file_type = do_file_type(cert_type);
+
+ if(cert_file != NULL || file_type == SSL_FILETYPE_ENGINE) {
SSL *ssl;
X509 *x509;
int cert_done = 0;
@@ -337,7 +338,6 @@ int cert_stuff(struct connectdata *conn,
SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
}
- file_type = do_file_type(cert_type);
#define SSL_CLIENT_CERT_ERR \
"unable to use client certificate (no key found or wrong pass phrase?)"
@@ -364,8 +364,56 @@ int cert_stuff(struct connectdata *conn,
}
break;
case SSL_FILETYPE_ENGINE:
+#ifdef HAVE_OPENSSL_ENGINE_H
+ {
+ if(data->state.engine) {
+ const char *cmd_name = "LOAD_CERT_CTRL";
+ struct {
+ const char *cert_id;
+ X509 *cert;
+ } params;
+
+ params.cert_id = cert_file;
+ params.cert = NULL;
+
+ /* Does the engine supports LOAD_CERT_CTRL ? */
+ if (!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
+ 0, (void *)cmd_name, NULL)) {
+ failf(data, "ssl engine does not support loading certificates");
+ return 0;
+ }
+ /* Load the certificate from the engine */
+ if (!ENGINE_ctrl_cmd(data->state.engine, cmd_name,
+ 0, &params, NULL, 1)) {
+ failf(data, "ssl engine cannot load client cert with id"
+ " '%s' [%s]", cert_file,
+ ERR_error_string(ERR_get_error(), NULL));
+ return 0;
+ }
+
+ if (!params.cert) {
+ failf(data, "ssl engine didn't initialized the certificate "
+ "properly.");
+ return 0;
+ }
+
+ if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
+ failf(data, "unable to set client certificate");
+ X509_free(params.cert);
+ return 0;
+ }
+ X509_free(params.cert); /* we don't need the handle any more... */
+ }
+ else {
+ failf(data, "crypto engine not set, can't load certificate");
+ return 0;
+ }
+ }
+ break;
+#else
failf(data, "file type ENG for certificate not implemented");
return 0;
+#endif
case SSL_FILETYPE_PKCS12:
{
@@ -481,10 +529,6 @@ int cert_stuff(struct connectdata *conn,
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
UI_METHOD *ui_method = UI_OpenSSL();
#endif
- if(!key_file || !key_file[0]) {
- failf(data, "no key set to load from crypto engine");
- return 0;
- }
/* the typecast below was added to please mingw32 */
priv_key = (EVP_PKEY *)
ENGINE_load_private_key(data->state.engine,key_file,
@@ -1475,7 +1519,7 @@ ossl_connect_step1(struct connectdata *conn,
SSL_CTX_ctrl(connssl->ctx, BIO_C_SET_NBIO, 1, NULL);
#endif
- if(data->set.str[STRING_CERT]) {
+ if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) {
if(!cert_stuff(conn,
connssl->ctx,
data->set.str[STRING_CERT],