Loading engines/e_capi.c +138 −33 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ #include <stdio.h> #include <string.h> #include <windows.h> #include <wincrypt.h> #include <openssl/crypto.h> #include <openssl/buffer.h> #include <openssl/engine.h> Loading @@ -68,8 +70,6 @@ #define _WIN32_WINNT 0x400 #endif #include <windows.h> #include <wincrypt.h> #include "e_capi_err.h" #include "e_capi_err.c" Loading Loading @@ -109,6 +109,10 @@ static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, DSA *dsa); static int capi_dsa_free(DSA *dsa); static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data); /* This structure contains CAPI ENGINE specific data: * it contains various global options and affects how * other functions behave. Loading @@ -126,6 +130,7 @@ struct CAPI_CTX_st { DWORD csptype; /* Certificate store name to use */ LPTSTR storename; LPTSTR ssl_client_store; /* Lookup string meanings in load_private_key */ /* Substring of subject: uses "storename" */ Loading Loading @@ -428,6 +433,8 @@ static int bind_capi(ENGINE *e) || !ENGINE_set_RSA(e, &capi_rsa_method) || !ENGINE_set_DSA(e, &capi_dsa_method) || !ENGINE_set_load_privkey_function(e, capi_load_privkey) || !ENGINE_set_load_ssl_client_cert_function(e, capi_load_ssl_client_cert) || !ENGINE_set_cmd_defns(e, capi_cmd_defns) || !ENGINE_set_ctrl_function(e, capi_ctrl)) return 0; Loading Loading @@ -494,34 +501,19 @@ static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen) return 1; } static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method, void *callback_data) /* Given a CAPI_KEY get an EVP_PKEY structure */ static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key) { EVP_PKEY *ret = NULL; CAPI_CTX *ctx; CAPI_KEY *key; unsigned char *pubkey = NULL; DWORD len; BLOBHEADER *bh; RSA *rkey = NULL; DSA *dkey = NULL; ctx = ENGINE_get_ex_data(eng, capi_idx); if (!ctx) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT); return NULL; } key = capi_find_key(ctx, key_id); if (!key) return NULL; len = 0; EVP_PKEY *ret = NULL; if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); capi_addlasterror(); return NULL; } Loading @@ -533,7 +525,7 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_PUBKEY_EXPORT_ERROR); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR); capi_addlasterror(); goto err; } Loading @@ -541,7 +533,7 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, bh = (BLOBHEADER *)pubkey; if (bh->bType != PUBLICKEYBLOB) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); goto err; } if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) Loading @@ -554,7 +546,7 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, { char magstr[10]; BIO_snprintf(magstr, 10, "%lx", rp->magic); CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); ERR_add_error_data(2, "magic=0x", magstr); goto err; } Loading Loading @@ -595,7 +587,7 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, { char magstr[10]; BIO_snprintf(magstr, 10, "%lx", dp->magic); CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); ERR_add_error_data(2, "magic=0x", magstr); goto err; } Loading Loading @@ -635,11 +627,12 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, { char algstr[10]; BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg); CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); ERR_add_error_data(2, "aiKeyAlg=0x", algstr); goto err; } err: if (pubkey) OPENSSL_free(pubkey); Loading @@ -649,8 +642,6 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, RSA_free(rkey); if (dkey) DSA_free(dkey); if (key) capi_free_key(key); } return ret; Loading @@ -661,6 +652,33 @@ memerr: } static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method, void *callback_data) { CAPI_CTX *ctx; CAPI_KEY *key; EVP_PKEY *ret; ctx = ENGINE_get_ex_data(eng, capi_idx); if (!ctx) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT); return NULL; } key = capi_find_key(ctx, key_id); if (!key) return NULL; ret = capi_get_pkey(eng, key); if (!ret) capi_free_key(key); return ret; } /* CryptoAPI RSA operations */ int capi_rsa_priv_enc(int flen, const unsigned char *from, Loading Loading @@ -1401,6 +1419,7 @@ static CAPI_CTX *capi_ctx_new() ctx->dump_flags = CAPI_DMP_SUMMARY|CAPI_DMP_FNAME; ctx->keytype = AT_KEYEXCHANGE; ctx->storename = NULL; ctx->ssl_client_store = NULL; ctx->lookup_method = CAPI_LU_SUBSTR; ctx->debug_level = 0; ctx->debug_file = NULL; Loading @@ -1418,6 +1437,8 @@ static void capi_ctx_free(CAPI_CTX *ctx) OPENSSL_free(ctx->debug_file); if (ctx->storename) OPENSSL_free(ctx->storename); if (ctx->ssl_client_store) OPENSSL_free(ctx->ssl_client_store); OPENSSL_free(ctx); } Loading Loading @@ -1450,5 +1471,89 @@ static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx) return capi_ctx_set_provname(ctx, pname, type, 0); } static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x) { int i; X509_NAME *nm; for (i = 0; i < sk_X509_NAME_num(ca_dn); i++) { nm = sk_X509_NAME_value(ca_dn, i); if (!X509_NAME_cmp(nm, X509_get_issuer_name(x))) return 1; } return 0; } static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data) { #if 0 /* For now just one matching key/cert */ STACK_OF(X509) *certs = NULL; STACK_OF(EVP_PKEY) *keys = NULL; #endif X509 *x; EVP_PKEY *pk; char *storename; const char *p; int i; HCERTSTORE hstore; PCCERT_CONTEXT cert = NULL; CAPI_CTX *ctx; ctx = ENGINE_get_ex_data(e, capi_idx); *pcert = NULL; *pkey = NULL; storename = ctx->ssl_client_store; if (!storename) storename = "MY"; hstore = capi_open_store(ctx, storename); if (!hstore) return 0; /* Enumerate all certificates looking for a match */ for(i = 0;!*pcert;i++) { cert = CertEnumCertificatesInStore(hstore, cert); if (!cert) break; p = cert->pbCertEncoded; x = d2i_X509(NULL, &p, cert->cbCertEncoded); if (!x) { CAPI_trace(ctx, "Can't Parse Certificate %d\n", i); continue; } if (cert_issuer_match(ca_dn, x)) { CAPI_KEY *key = capi_get_cert_key(ctx, cert); if (!key) continue; pk = capi_get_pkey(e, key); if (!pk) { capi_free_key(key); continue; } *pcert = x; *pkey = pk; } else X509_free(x); } if (cert) CertFreeCertificateContext(cert); if (*pcert) return 1; else return 0; } #endif #endif engines/e_capi_err.c +2 −1 Original line number Diff line number Diff line /* e_capi_err.c */ /* ==================================================================== * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions Loading Loading @@ -76,6 +76,7 @@ static ERR_STRING_DATA CAPI_str_functs[]= {ERR_FUNC(CAPI_F_CAPI_CTX_SET_PROVNAME), "CAPI_CTX_SET_PROVNAME"}, {ERR_FUNC(CAPI_F_CAPI_DSA_DO_SIGN), "CAPI_DSA_DO_SIGN"}, {ERR_FUNC(CAPI_F_CAPI_GET_KEY), "CAPI_GET_KEY"}, {ERR_FUNC(CAPI_F_CAPI_GET_PKEY), "CAPI_GET_PKEY"}, {ERR_FUNC(CAPI_F_CAPI_GET_PROVNAME), "CAPI_GET_PROVNAME"}, {ERR_FUNC(CAPI_F_CAPI_GET_PROV_INFO), "CAPI_GET_PROV_INFO"}, {ERR_FUNC(CAPI_F_CAPI_INIT), "CAPI_INIT"}, Loading engines/e_capi_err.h +1 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ static void ERR_CAPI_error(int function, int reason, char *file, int line); #define CAPI_F_CAPI_CTX_SET_PROVNAME 102 #define CAPI_F_CAPI_DSA_DO_SIGN 114 #define CAPI_F_CAPI_GET_KEY 103 #define CAPI_F_CAPI_GET_PKEY 115 #define CAPI_F_CAPI_GET_PROVNAME 104 #define CAPI_F_CAPI_GET_PROV_INFO 105 #define CAPI_F_CAPI_INIT 106 Loading Loading
engines/e_capi.c +138 −33 Original line number Diff line number Diff line Loading @@ -54,6 +54,8 @@ #include <stdio.h> #include <string.h> #include <windows.h> #include <wincrypt.h> #include <openssl/crypto.h> #include <openssl/buffer.h> #include <openssl/engine.h> Loading @@ -68,8 +70,6 @@ #define _WIN32_WINNT 0x400 #endif #include <windows.h> #include <wincrypt.h> #include "e_capi_err.h" #include "e_capi_err.c" Loading Loading @@ -109,6 +109,10 @@ static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, DSA *dsa); static int capi_dsa_free(DSA *dsa); static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data); /* This structure contains CAPI ENGINE specific data: * it contains various global options and affects how * other functions behave. Loading @@ -126,6 +130,7 @@ struct CAPI_CTX_st { DWORD csptype; /* Certificate store name to use */ LPTSTR storename; LPTSTR ssl_client_store; /* Lookup string meanings in load_private_key */ /* Substring of subject: uses "storename" */ Loading Loading @@ -428,6 +433,8 @@ static int bind_capi(ENGINE *e) || !ENGINE_set_RSA(e, &capi_rsa_method) || !ENGINE_set_DSA(e, &capi_dsa_method) || !ENGINE_set_load_privkey_function(e, capi_load_privkey) || !ENGINE_set_load_ssl_client_cert_function(e, capi_load_ssl_client_cert) || !ENGINE_set_cmd_defns(e, capi_cmd_defns) || !ENGINE_set_ctrl_function(e, capi_ctrl)) return 0; Loading Loading @@ -494,34 +501,19 @@ static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen) return 1; } static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method, void *callback_data) /* Given a CAPI_KEY get an EVP_PKEY structure */ static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key) { EVP_PKEY *ret = NULL; CAPI_CTX *ctx; CAPI_KEY *key; unsigned char *pubkey = NULL; DWORD len; BLOBHEADER *bh; RSA *rkey = NULL; DSA *dkey = NULL; ctx = ENGINE_get_ex_data(eng, capi_idx); if (!ctx) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT); return NULL; } key = capi_find_key(ctx, key_id); if (!key) return NULL; len = 0; EVP_PKEY *ret = NULL; if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); capi_addlasterror(); return NULL; } Loading @@ -533,7 +525,7 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_PUBKEY_EXPORT_ERROR); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR); capi_addlasterror(); goto err; } Loading @@ -541,7 +533,7 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, bh = (BLOBHEADER *)pubkey; if (bh->bType != PUBLICKEYBLOB) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); goto err; } if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) Loading @@ -554,7 +546,7 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, { char magstr[10]; BIO_snprintf(magstr, 10, "%lx", rp->magic); CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); ERR_add_error_data(2, "magic=0x", magstr); goto err; } Loading Loading @@ -595,7 +587,7 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, { char magstr[10]; BIO_snprintf(magstr, 10, "%lx", dp->magic); CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); ERR_add_error_data(2, "magic=0x", magstr); goto err; } Loading Loading @@ -635,11 +627,12 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, { char algstr[10]; BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg); CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); ERR_add_error_data(2, "aiKeyAlg=0x", algstr); goto err; } err: if (pubkey) OPENSSL_free(pubkey); Loading @@ -649,8 +642,6 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, RSA_free(rkey); if (dkey) DSA_free(dkey); if (key) capi_free_key(key); } return ret; Loading @@ -661,6 +652,33 @@ memerr: } static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method, void *callback_data) { CAPI_CTX *ctx; CAPI_KEY *key; EVP_PKEY *ret; ctx = ENGINE_get_ex_data(eng, capi_idx); if (!ctx) { CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT); return NULL; } key = capi_find_key(ctx, key_id); if (!key) return NULL; ret = capi_get_pkey(eng, key); if (!ret) capi_free_key(key); return ret; } /* CryptoAPI RSA operations */ int capi_rsa_priv_enc(int flen, const unsigned char *from, Loading Loading @@ -1401,6 +1419,7 @@ static CAPI_CTX *capi_ctx_new() ctx->dump_flags = CAPI_DMP_SUMMARY|CAPI_DMP_FNAME; ctx->keytype = AT_KEYEXCHANGE; ctx->storename = NULL; ctx->ssl_client_store = NULL; ctx->lookup_method = CAPI_LU_SUBSTR; ctx->debug_level = 0; ctx->debug_file = NULL; Loading @@ -1418,6 +1437,8 @@ static void capi_ctx_free(CAPI_CTX *ctx) OPENSSL_free(ctx->debug_file); if (ctx->storename) OPENSSL_free(ctx->storename); if (ctx->ssl_client_store) OPENSSL_free(ctx->ssl_client_store); OPENSSL_free(ctx); } Loading Loading @@ -1450,5 +1471,89 @@ static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx) return capi_ctx_set_provname(ctx, pname, type, 0); } static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x) { int i; X509_NAME *nm; for (i = 0; i < sk_X509_NAME_num(ca_dn); i++) { nm = sk_X509_NAME_value(ca_dn, i); if (!X509_NAME_cmp(nm, X509_get_issuer_name(x))) return 1; } return 0; } static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey, STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data) { #if 0 /* For now just one matching key/cert */ STACK_OF(X509) *certs = NULL; STACK_OF(EVP_PKEY) *keys = NULL; #endif X509 *x; EVP_PKEY *pk; char *storename; const char *p; int i; HCERTSTORE hstore; PCCERT_CONTEXT cert = NULL; CAPI_CTX *ctx; ctx = ENGINE_get_ex_data(e, capi_idx); *pcert = NULL; *pkey = NULL; storename = ctx->ssl_client_store; if (!storename) storename = "MY"; hstore = capi_open_store(ctx, storename); if (!hstore) return 0; /* Enumerate all certificates looking for a match */ for(i = 0;!*pcert;i++) { cert = CertEnumCertificatesInStore(hstore, cert); if (!cert) break; p = cert->pbCertEncoded; x = d2i_X509(NULL, &p, cert->cbCertEncoded); if (!x) { CAPI_trace(ctx, "Can't Parse Certificate %d\n", i); continue; } if (cert_issuer_match(ca_dn, x)) { CAPI_KEY *key = capi_get_cert_key(ctx, cert); if (!key) continue; pk = capi_get_pkey(e, key); if (!pk) { capi_free_key(key); continue; } *pcert = x; *pkey = pk; } else X509_free(x); } if (cert) CertFreeCertificateContext(cert); if (*pcert) return 1; else return 0; } #endif #endif
engines/e_capi_err.c +2 −1 Original line number Diff line number Diff line /* e_capi_err.c */ /* ==================================================================== * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions Loading Loading @@ -76,6 +76,7 @@ static ERR_STRING_DATA CAPI_str_functs[]= {ERR_FUNC(CAPI_F_CAPI_CTX_SET_PROVNAME), "CAPI_CTX_SET_PROVNAME"}, {ERR_FUNC(CAPI_F_CAPI_DSA_DO_SIGN), "CAPI_DSA_DO_SIGN"}, {ERR_FUNC(CAPI_F_CAPI_GET_KEY), "CAPI_GET_KEY"}, {ERR_FUNC(CAPI_F_CAPI_GET_PKEY), "CAPI_GET_PKEY"}, {ERR_FUNC(CAPI_F_CAPI_GET_PROVNAME), "CAPI_GET_PROVNAME"}, {ERR_FUNC(CAPI_F_CAPI_GET_PROV_INFO), "CAPI_GET_PROV_INFO"}, {ERR_FUNC(CAPI_F_CAPI_INIT), "CAPI_INIT"}, Loading
engines/e_capi_err.h +1 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ static void ERR_CAPI_error(int function, int reason, char *file, int line); #define CAPI_F_CAPI_CTX_SET_PROVNAME 102 #define CAPI_F_CAPI_DSA_DO_SIGN 114 #define CAPI_F_CAPI_GET_KEY 103 #define CAPI_F_CAPI_GET_PKEY 115 #define CAPI_F_CAPI_GET_PROVNAME 104 #define CAPI_F_CAPI_GET_PROV_INFO 105 #define CAPI_F_CAPI_INIT 106 Loading