#include <wincrypt.h>
+/*
+ * This module uses several "new" interfaces, among which is
+ * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is
+ * one of possible values you can pass to function in question. By
+ * checking if it's defined we can see if wincrypt.h and accompanying
+ * crypt32.lib are in shape. The native MingW32 headers up to and
+ * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the
+ * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG,
+ * so we check for these too and avoid compiling.
+ * Yes, it's rather "weak" test and if compilation fails,
+ * then re-configure with -DOPENSSL_NO_CAPIENG.
+ */
+#if defined(CERT_KEY_PROV_INFO_PROP_ID) && \
+ defined(CERT_STORE_PROV_SYSTEM_A) && \
+ defined(CERT_STORE_READONLY_FLAG)
+# define __COMPILE_CAPIENG
+#endif /* CERT_KEY_PROV_INFO_PROP_ID */
+#endif /* OPENSSL_NO_CAPIENG */
+#endif /* OPENSSL_SYS_WIN32 */
+
+#ifdef __COMPILE_CAPIENG
+
#undef X509_EXTENSIONS
#undef X509_CERT_PAIR
#define CERT_STORE_CREATE_NEW_FLAG 0x00002000
#endif
+#ifndef CERT_SYSTEM_STORE_CURRENT_USER
+#define CERT_SYSTEM_STORE_CURRENT_USER 0x00010000
+#endif
+
#include <openssl/engine.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
CAPI_CTX *ctx;
const RSA_METHOD *ossl_rsa_meth;
const DSA_METHOD *ossl_dsa_meth;
- capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
- cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
+
+ if (capi_idx < 0)
+ {
+ capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ if (capi_idx < 0)
+ goto memerr;
+
+ cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
+
+ /* Setup RSA_METHOD */
+ rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ ossl_rsa_meth = RSA_PKCS1_SSLeay();
+ capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
+ capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
+ capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
+ capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;
+
+ /* Setup DSA Method */
+ dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+ ossl_dsa_meth = DSA_OpenSSL();
+ capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
+ capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
+ capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
+ }
ctx = capi_ctx_new();
- if (!ctx || (capi_idx < 0))
+ if (!ctx)
goto memerr;
ENGINE_set_ex_data(e, capi_idx, ctx);
- /* Setup RSA_METHOD */
- rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
- ossl_rsa_meth = RSA_PKCS1_SSLeay();
- capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
- capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
- capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
- capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;
-
- /* Setup DSA Method */
- dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
- ossl_dsa_meth = DSA_OpenSSL();
- capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
- capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
- capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
#ifdef OPENSSL_CAPIENG_DIALOG
{
{
if (!ENGINE_set_id(e, engine_capi_id)
|| !ENGINE_set_name(e, engine_capi_name)
+ || !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL)
|| !ENGINE_set_init_function(e, capi_init)
|| !ENGINE_set_finish_function(e, capi_finish)
|| !ENGINE_set_destroy_function(e, capi_destroy)
}
#endif
-#endif
-#else /* !WIN32 */
+#else /* !__COMPILE_CAPIENG */
#include <openssl/engine.h>
#ifndef OPENSSL_NO_DYNAMIC_ENGINE
OPENSSL_EXPORT
+int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
+OPENSSL_EXPORT
int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
IMPLEMENT_DYNAMIC_CHECK_FN()
+#else
+void ENGINE_load_capi(void){}
#endif
#endif