From c824e9e35f4a77bdbfb0222d918f148dc8c101d2 Mon Sep 17 00:00:00 2001 From: Marcel Poul Date: Thu, 1 Dec 2011 16:40:31 +0000 Subject: [PATCH] certificate and private key read fctions added --- emi.canl.canl-c/src/canl.c | 31 ++++++++++-- emi.canl.canl-c/src/canl.h | 2 + emi.canl.canl-c/src/canl_cert.c | 108 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 135 insertions(+), 6 deletions(-) diff --git a/emi.canl.canl-c/src/canl.c b/emi.canl.canl-c/src/canl.c index 42dc539..e23f710 100644 --- a/emi.canl.canl-c/src/canl.c +++ b/emi.canl.canl-c/src/canl.c @@ -513,18 +513,39 @@ int canl_set_ctx_own_cert(canl_ctx cc, canl_x509 cert, if (!cc) return EINVAL; - if(!cert || !key) { - err = EINVAL; - set_error(glb_cc, err, posix_error, "invalid parameter value" + if(!cert) { + set_error(glb_cc, EINVAL, posix_error, "invalid parameter value" " (canl_set_ctx_own_cert)"); return err; } - do_set_ctx_own_cert(glb_cc, cert, chain, key); - + err = do_set_ctx_own_cert(glb_cc, cert, chain, key); if(err) { update_error(glb_cc, "can't set cert or key to context" " (canl_set_ctx_own_cert)"); } return err; } + +//TODO callback and userdata process +int canl_set_ctx_own_cert_file(canl_ctx cc, char *cert, char *key, + canl_password_callback cb, void *userdata) +{ + glb_ctx *glb_cc = (glb_ctx*) cc; + int err = 0; + + if (!cc) + return EINVAL; + if(!cert ) { + set_error(glb_cc, EINVAL, posix_error, "invalid parameter value" + " (canl_set_ctx_own_cert_file)"); + return EINVAL; + } + + err = do_set_ctx_own_cert_file(glb_cc, cert, key); + if(err) { + update_error(glb_cc, "can't set cert or key to context" + " (canl_set_ctx_own_cert_file)"); + } + return err; +} diff --git a/emi.canl.canl-c/src/canl.h b/emi.canl.canl-c/src/canl.h index 055a583..a7ad639 100644 --- a/emi.canl.canl-c/src/canl.h +++ b/emi.canl.canl-c/src/canl.h @@ -11,6 +11,8 @@ typedef void *canl_x509; typedef void *canl_stack_of_x509; typedef void *canl_pkey; +typedef char (*canl_password_callback)(canl_ctx cc, void *userdata); + canl_ctx canl_create_ctx(); void canl_free_ctx(canl_ctx cc); canl_io_handler canl_create_io_handler(canl_ctx cc); diff --git a/emi.canl.canl-c/src/canl_cert.c b/emi.canl.canl-c/src/canl_cert.c index accf8b0..be71677 100644 --- a/emi.canl.canl-c/src/canl_cert.c +++ b/emi.canl.canl-c/src/canl_cert.c @@ -1,5 +1,7 @@ #include "canl_locl.h" static int set_cert(glb_ctx *cc, X509 *cert); +static int set_key_file(glb_ctx *cc, char *key); +static int set_cert_file(glb_ctx *cc, char *cert); //TODO just stub int do_set_ctx_own_cert(glb_ctx *cc, canl_x509 cert, canl_stack_of_x509 chain, @@ -52,4 +54,108 @@ end: return err; } -//int authn_set_ctx_own_cert_file(auth_ctx ac, char *cert, char *key, authn_password_callback cb, void *userdata); +//TODO cert +int do_set_ctx_own_cert_file(glb_ctx *cc, char *cert, char *key) +{ + /* otherwise the private key is in cert file*/ + if (key) + set_key_file(cc, key); + + return 0; +} + +static int set_key_file(glb_ctx *cc, char *key) +{ + int err = 0; + FILE * key_file = NULL; + + if (!cc->cert_key){ + cc->cert_key = (cert_key_store *) calloc(1, sizeof(*(cc->cert_key))); + if (!cc->cert_key) { + err = ENOMEM; + set_error(cc, err, posix_error, "not enought memory for the" + " certificate storage (set_key_file)"); + return ENOMEM; + } + } + + if (cc->cert_key->key) { + EVP_PKEY_free(cc->cert_key->key); + cc->cert_key->key = NULL; + } +/* cc->cert_key->key = EVP_PKEY_new(void); + if (!cc->cert_key->key) { + err = ERR_get_error(); + set_error(cc, err, ssl_error, "not enough memory for" + " key storage (set_key_file)"); + return err; + } +*/ + key_file = fopen(key, "rb"); + if (!key_file) { + err = errno; + set_error(cc, err, posix_error, "cannot open file with key" + " (set_key_file)"); + return err; + } + /*TODO NULL NULL, callback and user data*/ + cc->cert_key->key = PEM_read_PrivateKey(key_file, NULL, NULL, NULL); + if (!cc->cert_key->key) { + err = ERR_get_error(); + set_error(cc, err, ssl_error, "error while writing key to context" + " (set_key_file)"); + goto end; + } + +end: + fclose(key_file); + return err; +} + +static int set_cert_file(glb_ctx *cc, char *cert) +{ + int err = 0; + FILE * cert_file = NULL; + + if (!cc->cert_key){ + cc->cert_key = (cert_key_store *) calloc(1, sizeof(*(cc->cert_key))); + if (!cc->cert_key) { + err = ENOMEM; + set_error(cc, err, posix_error, "not enought memory for the" + " certificate storage (set_cert_file)"); + return ENOMEM; + } + } + + if (cc->cert_key->cert) { + X509_free(cc->cert_key->cert); + cc->cert_key->cert = NULL; + } +/* cc->cert_key->cert = EVP_PKEY_new(void); + if (!cc->cert_key->cert) { + err = ERR_get_error(); + set_error(cc, err, ssl_error, "not enough memory for" + " key storage (set_key_file)"); + return err; + } +*/ + cert_file = fopen(cert, "rb"); + if (!cert_file) { + err = errno; + set_error(cc, err, posix_error, "cannot open file with cert" + " (set_key_file)"); + return err; + } + /*TODO NULL NULL, callback and user data*/ + cc->cert_key->cert = PEM_read_X509(cert_file, NULL, NULL, NULL); + if (!cc->cert_key->cert) { + err = ERR_get_error(); + set_error(cc, err, ssl_error, "error while writing certificate" + " to context (set_key_file)"); + goto end; + } + +end: + fclose(cert_file); + return err; +} -- 1.8.2.3