Hi,
(2010/01/12 9:38), Dr. Stephen Henson wrote:
> On Mon, Jan 11, 2010, NARUSE, Yui wrote:
>> So I request X509_STORE_set_default_paths call this.
>> When this is merge, both Unix user and Windows user can use
>> the system's default root certificates.
>>
>> I should file this to Request Tracker as a bug? (even if this is feature
>> request)
>>
>
> Some CryptoAPI handling code already exists in the CryptoAPI ENGINE and I'd
> suggest that a ctrl for that would be the best place to put it. There are some
> debug options already that can dump a whole store to standard output.
>
> However some additional code would be needed because that just adds the whole
> store without any purpose setting code. This could cause security issues if
> for example client certificate authorities are used for server signing for
> example.
Thank you for your comment.
So I rewrite my patch as you said: use CryptoAPI ENGINE.
How about is this?
--
NARUSE, Yui <[email protected]>
Index: crypto/x509/x509_d2.c
===================================================================
RCS file: /v/openssl/cvs/openssl/crypto/x509/x509_d2.c,v
retrieving revision 1.7
diff -p -u -r1.7 x509_d2.c
--- crypto/x509/x509_d2.c 19 Feb 2001 16:02:21 -0000 1.7
+++ crypto/x509/x509_d2.c 15 Jan 2010 01:00:16 -0000
@@ -59,9 +59,28 @@
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/crypto.h>
+#include <openssl/engine.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_STDIO
+static void X509_STORE_load_windows_systemstore(X509_STORE *ctx)
+ {
+ ENGINE *e;
+ const char *engine_id = "capi";
+ ENGINE_load_builtin_engines();
+ e = ENGINE_by_id(engine_id);
+ if (!e) return;
+ if (!ENGINE_init(e))
+ {
+ ENGINE_free(e);
+ return;
+ }
+ ENGINE_ctrl_cmd_string(e, "store_name", "ROOT", 0);
+ ENGINE_ctrl_cmd(e, "load_certs", 0, ctx, NULL, 0);
+ ENGINE_finish(e);
+ ENGINE_free(e);
+ }
+
int X509_STORE_set_default_paths(X509_STORE *ctx)
{
X509_LOOKUP *lookup;
@@ -77,6 +96,8 @@ int X509_STORE_set_default_paths(X509_ST
/* clear any errors */
ERR_clear_error();
+ X509_STORE_load_windows_systemstore(ctx);
+
return(1);
}
Index: engines/e_capi.c
===================================================================
RCS file: /v/openssl/cvs/openssl/engines/e_capi.c,v
retrieving revision 1.28
diff -u -p -r1.28 e_capi.c
--- engines/e_capi.c 30 Dec 2009 11:46:54 -0000 1.28
+++ engines/e_capi.c 15 Jan 2010 15:18:36 -0000
@@ -121,6 +121,7 @@ static void CAPI_trace(CAPI_CTX *ctx, ch
static int capi_list_providers(CAPI_CTX *ctx, BIO *out);
static int capi_list_containers(CAPI_CTX *ctx, BIO *out);
int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename);
+static int capi_enum_certs(CAPI_CTX *ctx, char *id, void *ptr, int ptype);
void capi_free_key(CAPI_KEY *key);
static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE
hstore);
@@ -225,6 +226,7 @@ static int capi_ctx_set_provname_idx(CAP
#define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11)
#define CAPI_CMD_STORE_NAME (ENGINE_CMD_BASE + 12)
#define CAPI_CMD_STORE_FLAGS (ENGINE_CMD_BASE + 13)
+#define CAPI_CMD_LOAD_CERTS (ENGINE_CMD_BASE + 14)
static const ENGINE_CMD_DEFN capi_cmd_defns[] = {
{CAPI_CMD_LIST_CERTS,
@@ -284,6 +286,10 @@ static const ENGINE_CMD_DEFN capi_cmd_de
"store_flags",
"Certificate store flags: 1 = system store",
ENGINE_CMD_FLAG_NUMERIC},
+ {CAPI_CMD_LOAD_CERTS,
+ "load_certs",
+ "Load certificates in store",
+ ENGINE_CMD_FLAG_NO_INPUT},
{0, NULL, NULL, 0}
};
@@ -315,6 +321,10 @@ static int capi_ctrl(ENGINE *e, int cmd,
ret = capi_list_certs(ctx, out, NULL);
break;
+ case CAPI_CMD_LOAD_CERTS:
+ ret = capi_enum_certs(ctx, NULL, p, CAPI_CMD_LOAD_CERTS);
+ break;
+
case CAPI_CMD_LOOKUP_CERT:
ret = capi_list_certs(ctx, out, p);
break;
@@ -1331,13 +1341,38 @@ HCERTSTORE capi_open_store(CAPI_CTX *ctx
return hstore;
}
-int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id)
+void capi_store_cert(CAPI_CTX *ctx, X509_STORE *xstore, PCCERT_CONTEXT cert)
+ {
+ X509 *x509 = NULL;
+ x509 = d2i_X509(NULL, (const unsigned char**)&cert->pbCertEncoded,
cert->cbCertEncoded);
+ if (x509)
+ {
+ X509_STORE_add_cert(xstore, x509);
+ X509_free(x509);
+ }
+ }
+
+static int capi_enum_certs(CAPI_CTX *ctx, char *id, void *ptr, int ptype)
{
char *storename;
int idx;
int ret = 1;
HCERTSTORE hstore;
PCCERT_CONTEXT cert = NULL;
+ BIO *out = NULL;
+ X509_STORE *xstore = NULL;
+
+ switch (ptype) {
+ case CAPI_CMD_LIST_CERTS:
+ out = (BIO *)ptr;
+ break;
+ case CAPI_CMD_LOAD_CERTS:
+ xstore = (X509_STORE *)ptr;
+ break;
+ default:
+ return 0;
+ break;
+ }
storename = ctx->storename;
if (!storename)
@@ -1355,7 +1390,8 @@ int capi_list_certs(CAPI_CTX *ctx, BIO *
ret = 0;
goto err;
}
- capi_dump_cert(ctx, out, cert);
+ if (out) capi_dump_cert(ctx, out, cert);
+ if (xstore) capi_store_cert(ctx, xstore, cert);
CertFreeCertificateContext(cert);
}
else
@@ -1366,8 +1402,12 @@ int capi_list_certs(CAPI_CTX *ctx, BIO *
cert = CertEnumCertificatesInStore(hstore, cert);
if (!cert)
break;
- BIO_printf(out, "Certificate %d\n", idx);
- capi_dump_cert(ctx, out, cert);
+ if (out)
+ {
+ BIO_printf(out, "Certificate %d\n", idx);
+ capi_dump_cert(ctx, out, cert);
+ }
+ if (xstore) capi_store_cert(ctx, xstore, cert);
}
}
err:
@@ -1375,6 +1415,11 @@ int capi_list_certs(CAPI_CTX *ctx, BIO *
return ret;
}
+int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id)
+ {
+ return capi_enum_certs(ctx, id, (void *)out,
CAPI_CMD_LIST_CERTS);
+ }
+
static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE
hstore)
{
PCCERT_CONTEXT cert = NULL;