canl_cred_load_chain_file() implemented,
authorMarcel Poul <marcel.poul@cern.ch>
Sat, 28 Jan 2012 21:57:50 +0000 (21:57 +0000)
committerMarcel Poul <marcel.poul@cern.ch>
Sat, 28 Jan 2012 21:57:50 +0000 (21:57 +0000)
emi.canl.canl-c/src/canl_cert.c
emi.canl.canl-c/src/canl_cred.c
emi.canl.canl-c/src/canl_locl.h

index 2a16500..ebbbceb 100644 (file)
@@ -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;
+}
index 650a5d7..c3a59ee 100644 (file)
@@ -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;
index 9484b30..a15c61f 100644 (file)
@@ -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