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 <nar...@airemix.jp>
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;