From 012bc0a6233039cb80317a57fa0fa7b2a3c3583d Mon Sep 17 00:00:00 2001 From: Marcel Poul Date: Sat, 28 Jan 2012 21:57:50 +0000 Subject: [PATCH] canl_cred_load_chain_file() implemented, --- emi.canl.canl-c/src/canl_cert.c | 59 +++++++++++++++++++++++++++++++++++++++++ emi.canl.canl-c/src/canl_cred.c | 24 +++++++++++++++-- emi.canl.canl-c/src/canl_locl.h | 1 + 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/emi.canl.canl-c/src/canl_cert.c b/emi.canl.canl-c/src/canl_cert.c index 2a16500..ebbbceb 100644 --- a/emi.canl.canl-c/src/canl_cert.c +++ b/emi.canl.canl-c/src/canl_cert.c @@ -165,3 +165,62 @@ end: } return 1; } + +int set_cert_chain_file(glb_ctx *cc, STACK_OF(X509) **to, const char *file) +{ + unsigned long ssl_err = 0; + FILE * cert_file = NULL; + int count = 0; + int ret = -1; + X509 *x = NULL; + + if (file == NULL) + return set_error(cc, EINVAL, POSIX_ERROR, "Cert. chain file" + "does not exist"); + + if (*to) { + sk_X509_pop_free(*to, X509_free); + *to = NULL; + } + + cert_file = fopen(file, "rb"); + if (!cert_file) + return set_error(cc, errno, POSIX_ERROR, "Cannot " + "open file with cert. chain"); + + for (;;) + { + /* TODO maybe callback can be specified*/ + x = PEM_read_X509(cert_file,NULL, NULL, NULL); + if (x == NULL) + { + ssl_err = ERR_peek_error(); + if ((ERR_GET_REASON(ssl_err) == + PEM_R_NO_START_LINE)) { + /*everything OK*/ + if ((count > 0)) { + ERR_clear_error(); + break; + } + else { + ret = set_error(cc, ssl_err, SSL_ERROR, "Cannot get" + "certificate out of file"); + goto end; + } + } + } + + (void)sk_X509_insert(*to, x, sk_X509_num(*to)); + x = NULL; + count++; + } + return 0; + +end: + if (fclose(cert_file)){ + ret = errno; + return update_error(cc, errno, POSIX_ERROR, "cannot close file with" + " the certificate"); + } + return ret; +} diff --git a/emi.canl.canl-c/src/canl_cred.c b/emi.canl.canl-c/src/canl_cred.c index 650a5d7..c3a59ee 100644 --- a/emi.canl.canl-c/src/canl_cred.c +++ b/emi.canl.canl-c/src/canl_cred.c @@ -195,10 +195,30 @@ canl_cred_load_chain(canl_ctx ctx, canl_cred cred, STACK_OF(X509) *cert_stack) canl_err_code CANL_CALLCONV canl_cred_load_chain_file(canl_ctx ctx, canl_cred cred, const char *chain_file) { - return ENOSYS; + glb_ctx *cc = (glb_ctx*) ctx; + creds *crd = (creds*) cred; + + if (!ctx) + return EINVAL; + + if (!cred) + return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" + " not initialized" ); + + if (!chain_file) + return set_error(cc, EINVAL, POSIX_ERROR, "Invalid chain filename"); + + if (crd->c_cert_chain) { + sk_X509_pop_free(crd->c_cert_chain, X509_free); + crd->c_cert_chain = NULL; + } + else + crd->c_cert_chain = sk_X509_new_null(); + + return set_cert_chain_file(cc, &crd->c_cert_chain, chain_file); } -canl_err_code CANL_CALLCONV + canl_err_code CANL_CALLCONV canl_cred_load_cert(canl_ctx ctx, canl_cred cred, X509 *cert) { glb_ctx *cc = (glb_ctx*) ctx; diff --git a/emi.canl.canl-c/src/canl_locl.h b/emi.canl.canl-c/src/canl_locl.h index 9484b30..a15c61f 100644 --- a/emi.canl.canl-c/src/canl_locl.h +++ b/emi.canl.canl-c/src/canl_locl.h @@ -142,5 +142,6 @@ int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, int do_set_ctx_own_cert_file(glb_ctx *cc, char *cert, char *key); int set_key_file(glb_ctx *cc, EVP_PKEY **to, const char *key); int set_cert_file(glb_ctx *cc, X509 **to, const char *cert); +int set_cert_chain_file(glb_ctx *cc, STACK_OF(X509) **to, const char *cert); #endif -- 1.8.2.3