From 2876fd9cb2d9cdd7389bbc7a5d73a082c5aff3f3 Mon Sep 17 00:00:00 2001 From: Marcel Poul Date: Wed, 29 Feb 2012 01:17:38 +0000 Subject: [PATCH] truly not dependent on auth. mechanism: cert, key in mech. context; structure describing mechanism use void pointer to store mechanism dependent data --- emi.canl.canl-c/src/canl_cert.c | 33 ++++++++++++---------- emi.canl.canl-c/src/canl_cred.c | 16 ++++++----- emi.canl.canl-c/src/canl_locl.h | 58 +++++++++++++++++++------------------- emi.canl.canl-c/src/canl_ssl.c | 62 ++++++++++++++++++++++++----------------- 4 files changed, 94 insertions(+), 75 deletions(-) diff --git a/emi.canl.canl-c/src/canl_cert.c b/emi.canl.canl-c/src/canl_cert.c index 8dae50e..e71b2ce 100644 --- a/emi.canl.canl-c/src/canl_cert.c +++ b/emi.canl.canl-c/src/canl_cert.c @@ -18,15 +18,16 @@ int do_set_ctx_own_cert(glb_ctx *cc, canl_x509 cert, canl_stack_of_x509 chain, is_chain = 1; if (key) is_key = 1; - if (!cc->cert_key){ - cc->cert_key = (cert_key_store *) calloc(1, sizeof(*(cc->cert_key))); - if (!cc->cert_key) { + if (!m_ctx->cert_key){ + m_ctx->cert_key = (cert_key_store *) calloc(1, + sizeof(*(m_ctx->cert_key))); + if (!m_ctx->cert_key) { err = ENOMEM; goto end; } } - if (!cc->cert_key->cert) { + if (!m_ctx->cert_key->cert) { } */ return 0; @@ -37,12 +38,12 @@ static int set_cert(glb_ctx *cc, X509 *cert) int err = 0; CANL_ERROR_ORIGIN err_orig = 0; - if (cc->cert_key->cert) { - free(cc->cert_key->cert); - cc->cert_key->cert = NULL; + if (m_ctx->cert_key->cert) { + free(m_ctx->cert_key->cert); + m_ctx->cert_key->cert = NULL; } - cc->cert_key->cert = (X509 *) malloc (sizeof(X509)); - if (!cc->cert_key->cert) { + m_ctx->cert_key->cert = (X509 *) malloc (sizeof(X509)); + if (!m_ctx->cert_key->cert) { err = ENOMEM; goto end; } @@ -55,26 +56,28 @@ end: #endif //TODO cert -int do_set_ctx_own_cert_file(glb_ctx *cc, char *cert, char *key) +int do_set_ctx_own_cert_file(glb_ctx *cc, mech_glb_ctx *m_ctx, + char *cert, char *key) { int err = 0; - if (!cc->cert_key){ - cc->cert_key = (cert_key_store *) calloc(1, sizeof(*(cc->cert_key))); - if (!cc->cert_key) { + if (!m_ctx->cert_key){ + m_ctx->cert_key = (cert_key_store *) calloc(1, + sizeof(*(m_ctx->cert_key))); + if (!m_ctx->cert_key) { return set_error(cc, ENOMEM, POSIX_ERROR, "not enought memory" " for the certificate storage"); } } if (key) { - err = set_key_file(cc, &cc->cert_key->key, key); + err = set_key_file(cc, &m_ctx->cert_key->key, key); if (err) return err; } if (cert) { - err = set_cert_file(cc, &cc->cert_key->cert, cert); + err = set_cert_file(cc, &m_ctx->cert_key->cert, cert); if (err) return err; } diff --git a/emi.canl.canl-c/src/canl_cred.c b/emi.canl.canl-c/src/canl_cred.c index ee5e241..06d1ddb 100644 --- a/emi.canl.canl-c/src/canl_cred.c +++ b/emi.canl.canl-c/src/canl_cred.c @@ -72,31 +72,33 @@ canl_ctx_set_cred(canl_ctx ctx, canl_cred cred) glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; int ret = 0; + mech_glb_ctx *m_ctx = (mech_glb_ctx*) canl_mech_ssl.glb_ctx; if (!ctx) return EINVAL; - if (!crd || !cc->cert_key) + if (!crd || !m_ctx->cert_key) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); - if (!cc->cert_key){ - cc->cert_key = (cert_key_store *) calloc(1, sizeof(*(cc->cert_key))); - if (!cc->cert_key) { + if (!m_ctx->cert_key){ + m_ctx->cert_key = (cert_key_store *) calloc(1, + sizeof(*(m_ctx->cert_key))); + if (!m_ctx->cert_key) { return set_error(cc, ENOMEM, POSIX_ERROR, "not enought memory" " for the certificate storage"); } } if (crd->c_key) { - if ((ret = pkey_dup(cc, &cc->cert_key->key, crd->c_key))) { + if ((ret = pkey_dup(cc, &m_ctx->cert_key->key, crd->c_key))) { return ret; } } if (crd->c_cert) - cc->cert_key->cert = X509_dup(crd->c_cert); + m_ctx->cert_key->cert = X509_dup(crd->c_cert); if (crd->c_cert_chain) - cc->cert_key->chain = sk_X509_dup(crd->c_cert_chain); + m_ctx->cert_key->chain = sk_X509_dup(crd->c_cert_chain); return 0; } diff --git a/emi.canl.canl-c/src/canl_locl.h b/emi.canl.canl-c/src/canl_locl.h index eb081f2..b57422f 100644 --- a/emi.canl.canl-c/src/canl_locl.h +++ b/emi.canl.canl-c/src/canl_locl.h @@ -51,12 +51,6 @@ typedef enum _CANL_AUTH_MECHANISM GSSAPI, } CANL_AUTH_MECHANISM; -typedef struct _cert_key_store { - X509 *cert; - EVP_PKEY *key; - STACK_OF(X509) *chain; -} cert_key_store; - typedef struct _glb_ctx { char * err_msg; @@ -64,7 +58,6 @@ typedef struct _glb_ctx /* XXX Do we need to keep these two:? */ canl_err_origin err_orig; long original_err_code; - cert_key_store *cert_key; } glb_ctx; typedef struct _asyn_result { @@ -86,38 +79,30 @@ typedef struct _io_handler gss_OID oid; } io_handler; -typedef struct _mech_glb_ctx -{ - void *mech_ctx; //like SSL_CTX * - unsigned int flags; - char *ca_dir; - char *crl_dir; -} mech_glb_ctx; - typedef struct canl_mech { CANL_AUTH_MECHANISM mech; - mech_glb_ctx *glb_ctx; + void *glb_ctx; canl_err_code (*initialize) - (glb_ctx *, mech_glb_ctx **); + (glb_ctx *, void **); canl_err_code (*set_flags) (glb_ctx *cc, unsigned int *mech_flags, unsigned int flags); canl_err_code (*set_ca_dir) - (glb_ctx *, mech_glb_ctx *, const char *); + (glb_ctx *, void *, const char *); canl_err_code (*set_crl_dir) - (glb_ctx *, mech_glb_ctx *, const char *); + (glb_ctx *, void *, const char *); canl_err_code (*finish) (glb_ctx *, void *); canl_err_code (*client_init) - (glb_ctx *, mech_glb_ctx *, void **); + (glb_ctx *, void *, void **); canl_err_code (*server_init) - (glb_ctx *, mech_glb_ctx *, void **); + (glb_ctx *, void *, void **); canl_err_code (*free_ctx) (glb_ctx *, void *); @@ -142,10 +127,33 @@ typedef struct canl_mech { } canl_mech; +/* Openssl specific**************************/ +typedef struct _cert_key_store { + X509 *cert; + EVP_PKEY *key; + STACK_OF(X509) *chain; +} cert_key_store; + +typedef struct _mech_glb_ctx +{ + void *mech_ctx; //like SSL_CTX * + unsigned int flags; + char *ca_dir; + char *crl_dir; + cert_key_store *cert_key; +} mech_glb_ctx; + +int do_set_ctx_own_cert_file(glb_ctx *cc, mech_glb_ctx *m_ctx, + 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); +extern canl_mech canl_mech_ssl; +/* *****************************************/ + struct canl_mech * find_mech(gss_OID oid); -extern struct canl_mech canl_mech_ssl; void reset_error (glb_ctx *cc, unsigned long err_code); canl_err_code set_error (glb_ctx *cc, unsigned long err_code, @@ -156,10 +164,4 @@ void free_hostent(struct hostent *h); //TODO is there some standard funcion to f int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, struct timeval *timeout); -/*TODO maybe move to another haeder file*/ -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 diff --git a/emi.canl.canl-c/src/canl_ssl.c b/emi.canl.canl-c/src/canl_ssl.c index 50f018a..4beb0a4 100644 --- a/emi.canl.canl-c/src/canl_ssl.c +++ b/emi.canl.canl-c/src/canl_ssl.c @@ -13,8 +13,9 @@ static void dbg_print_ssl_error(int errorcode); #endif static canl_err_code -ssl_initialize(glb_ctx *cc, mech_glb_ctx **m_glb_ctx) +ssl_initialize(glb_ctx *cc, void **v_glb_ctx) { + mech_glb_ctx **m_glb_ctx = (mech_glb_ctx **)v_glb_ctx; int err = 0; char *ca_cert_fn, *user_cert_fn, *user_key_fn, *user_proxy_fn; char *ca_cert_dirn = NULL; @@ -111,20 +112,23 @@ ssl_set_dir(glb_ctx *cc, char **target, const char *ca_dir) } static canl_err_code -ssl_set_crl_dir(glb_ctx *cc, mech_glb_ctx *m_ctx, const char *crl_dir) +ssl_set_crl_dir(glb_ctx *cc, void *v_ctx, const char *crl_dir) { + mech_glb_ctx *m_ctx = (mech_glb_ctx *)v_ctx; return ssl_set_dir(cc, &m_ctx->crl_dir, crl_dir); } static canl_err_code -ssl_set_ca_dir(glb_ctx *cc, mech_glb_ctx *m_ctx, const char *ca_dir) +ssl_set_ca_dir(glb_ctx *cc, void *v_ctx, const char *ca_dir) { + mech_glb_ctx *m_ctx = (mech_glb_ctx *)v_ctx; return ssl_set_dir(cc, &m_ctx->ca_dir, ca_dir); } static canl_err_code -ssl_server_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx) +ssl_server_init(glb_ctx *cc, void *v_ctx, void **ctx) { + mech_glb_ctx *m_ctx = (mech_glb_ctx *)v_ctx; SSL_CTX *ssl_ctx = (SSL_CTX *) m_ctx->mech_ctx; SSL *ssl = NULL; char *user_cert_fn, *user_key_fn, *user_proxy_fn; @@ -139,10 +143,10 @@ ssl_server_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx) err = proxy_get_filenames(0, NULL, NULL, &user_proxy_fn, &user_cert_fn, &user_key_fn); - if (!err && (!cc->cert_key || !cc->cert_key->cert || !cc->cert_key->key)) { + if (!err && (!m_ctx->cert_key || !m_ctx->cert_key->cert || !m_ctx->cert_key->key)) { if (user_cert_fn && user_key_fn && !access(user_cert_fn, R_OK) && !access(user_key_fn, R_OK)) { - err = do_set_ctx_own_cert_file(cc, user_cert_fn, user_key_fn); + err = do_set_ctx_own_cert_file(cc, m_ctx, user_cert_fn, user_key_fn); if (err) return err; } @@ -175,9 +179,9 @@ ssl_server_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx) SSL_set_accept_state(ssl); - if (cc->cert_key) { - if (cc->cert_key->cert) { - err = SSL_use_certificate(ssl, cc->cert_key->cert); + if (m_ctx->cert_key) { + if (m_ctx->cert_key->cert) { + err = SSL_use_certificate(ssl, m_ctx->cert_key->cert); if (err != 1) { return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" "use certificate"); @@ -185,8 +189,8 @@ ssl_server_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx) else err = 0; } - if (cc->cert_key->key) { - err = SSL_use_PrivateKey(ssl, cc->cert_key->key); + if (m_ctx->cert_key->key) { + err = SSL_use_PrivateKey(ssl, m_ctx->cert_key->key); if (err != 1) { return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" "use private key"); @@ -210,8 +214,9 @@ ssl_server_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx) } static canl_err_code -ssl_client_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx) +ssl_client_init(glb_ctx *cc, void *v_ctx, void **ctx) { + mech_glb_ctx *m_ctx = (mech_glb_ctx *)v_ctx; SSL_CTX *ssl_ctx = (SSL_CTX *) m_ctx->mech_ctx; SSL *ssl = NULL; int err = 0; @@ -233,20 +238,23 @@ ssl_client_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx) err = proxy_get_filenames(0, NULL, NULL, &user_proxy_fn, &user_cert_fn, &user_key_fn); - if (!err && (!cc->cert_key || !cc->cert_key->cert || !cc->cert_key->key)) { + if (!err && (!m_ctx->cert_key || !m_ctx->cert_key->cert || !m_ctx->cert_key->key)) { if (user_proxy_fn && !access(user_proxy_fn, R_OK)) { - err = do_set_ctx_own_cert_file(cc, user_proxy_fn, user_proxy_fn); + err = do_set_ctx_own_cert_file(cc, m_ctx, user_proxy_fn, + user_proxy_fn); if (err) return err; } else { if (user_cert_fn && !access(user_cert_fn, R_OK)) { - err = do_set_ctx_own_cert_file(cc, user_cert_fn, NULL); + err = do_set_ctx_own_cert_file(cc, m_ctx, + user_cert_fn, NULL); if (err) return err; } if (user_key_fn && !access(user_key_fn, R_OK)) { - err = do_set_ctx_own_cert_file(cc, NULL, user_key_fn); + err = do_set_ctx_own_cert_file(cc, m_ctx, + NULL, user_key_fn); if (err) return err; } @@ -264,16 +272,16 @@ ssl_client_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx) if (!(CANL_ACCEPT_SSLv2 & m_ctx->flags)) SSL_set_options(ssl, SSL_OP_NO_SSLv2); - if (cc->cert_key) { - if (cc->cert_key->key) { - err = SSL_use_PrivateKey(ssl, cc->cert_key->key); + if (m_ctx->cert_key) { + if (m_ctx->cert_key->key) { + err = SSL_use_PrivateKey(ssl, m_ctx->cert_key->key); if (err != 1) { return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" "use private key"); } } - if (cc->cert_key->cert) { - err = SSL_use_certificate(ssl, cc->cert_key->cert); + if (m_ctx->cert_key->cert) { + err = SSL_use_certificate(ssl, m_ctx->cert_key->cert); if (err != 1) { return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" "use certificate"); @@ -281,7 +289,7 @@ ssl_client_init(glb_ctx *cc, mech_glb_ctx *m_ctx, void **ctx) } /*Make sure the key and certificate file match * not mandatory on client side*/ - if (cc->cert_key->cert && cc->cert_key->key) + if (m_ctx->cert_key->cert && m_ctx->cert_key->key) if ( (err = SSL_check_private_key(ssl)) != 1) return set_error(cc, ERR_get_error(), SSL_ERROR, "Private key" " does not match the certificate public key"); @@ -873,6 +881,8 @@ canl_ctx_set_ssl_cred(canl_ctx cc, char *cert, char *key, glb_ctx *glb_cc = (glb_ctx*) cc; int err = 0; + mech_glb_ctx *m_ctx = canl_mech_ssl.glb_ctx; + if (!cc) return EINVAL; if(!cert ) { @@ -880,7 +890,7 @@ canl_ctx_set_ssl_cred(canl_ctx cc, char *cert, char *key, return EINVAL; } - err = do_set_ctx_own_cert_file(glb_cc, cert, key); + err = do_set_ctx_own_cert_file(glb_cc, m_ctx, cert, key); if(err) { // update_error(glb_cc, "can't set cert or key to context"); } @@ -988,9 +998,11 @@ static void dbg_print_ssl_error(int errorcode) } #endif -struct canl_mech canl_mech_ssl = { +mech_glb_ctx ssl_glb_ctx; + +canl_mech canl_mech_ssl = { TLS, - NULL, + &ssl_glb_ctx, ssl_initialize, ssl_set_flags, ssl_set_ca_dir, -- 1.8.2.3