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; }
/* * Construct the per-ENGINE context. We create it blindly and then use a lock * to check for a race - if so, all but one of the threads "racing" will have * wasted their time. The alternative involves creating everything inside the * lock which is far worse. */ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) { dynamic_data_ctx *c = OPENSSL_zalloc(sizeof(*c)); if (c == NULL) { ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); return 0; } c->dirs = sk_OPENSSL_STRING_new_null(); if (c->dirs == NULL) { ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); OPENSSL_free(c); return 0; } c->DYNAMIC_F1 = "v_check"; c->DYNAMIC_F2 = "bind_engine"; c->dir_load = 1; CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx)) == NULL) { /* Good, we're the first */ ENGINE_set_ex_data(e, dynamic_ex_data_idx, c); *ctx = c; c = NULL; } CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); /* * If we lost the race to set the context, c is non-NULL and *ctx is the * context of the thread that won. */ OPENSSL_free(c); return 1; }
/* * This function retrieves the context structure from an ENGINE's "ex_data", * or if it doesn't exist yet, sets it up. */ static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e) { dynamic_data_ctx *ctx; if (dynamic_ex_data_idx < 0) { /* * Create and register the ENGINE ex_data, and associate our "free" * function with it to ensure any allocated contexts get freed when * an ENGINE goes underground. */ int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, dynamic_data_ctx_free_func); if (new_idx == -1) { ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX, ENGINE_R_NO_INDEX); return NULL; } CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); /* Avoid a race by checking again inside this lock */ if (dynamic_ex_data_idx < 0) { /* Good, someone didn't beat us to it */ dynamic_ex_data_idx = new_idx; new_idx = -1; } CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); /* * In theory we could "give back" the index here if (new_idx>-1), but * it's not possible and wouldn't gain us much if it were. */ } ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx); /* Check if the context needs to be created */ if ((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx)) /* "set_data" will set errors if necessary */ return NULL; return ctx; }
static int capi_finish(ENGINE *e) { CAPI_CTX *ctx; ctx = ENGINE_get_ex_data(e, capi_idx); capi_ctx_free(ctx); ENGINE_set_ex_data(e, capi_idx, NULL); return 1; }
/* * rsa私钥加密 */ int rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { char *keyid; //获取私钥id keyid = (char *)ENGINE_get_ex_data(rsa->engine, 0); printf("call rsa_priv_enc\n"); printf("use key id: %d\n", keyid); return 1; }
int capi_rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { int i; unsigned char *tmpbuf; CAPI_KEY *capi_key; CAPI_CTX *ctx; ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n"); capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); if (!capi_key) { CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY); return -1; } if(padding != RSA_PKCS1_PADDING) { char errstr[10]; BIO_snprintf(errstr, 10, "%d", padding); CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING); ERR_add_error_data(2, "padding=", errstr); return -1; } /* Create temp reverse order version of input */ if(!(tmpbuf = OPENSSL_malloc(flen)) ) { CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE); return -1; } for(i = 0; i < flen; i++) tmpbuf[flen - i - 1] = from[i]; /* Finally decrypt it */ if(!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen)) { CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR); capi_addlasterror(); OPENSSL_free(tmpbuf); return -1; } else memcpy(to, tmpbuf, flen); OPENSSL_free(tmpbuf); return flen; }
/* * Construct the per-ENGINE context. We create it blindly and then use a lock * to check for a race - if so, all but one of the threads "racing" will have * wasted their time. The alternative involves creating everything inside the * lock which is far worse. */ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) { dynamic_data_ctx *c; c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); if (!c) { ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); return 0; } memset(c, 0, sizeof(dynamic_data_ctx)); c->dynamic_dso = NULL; c->v_check = NULL; c->bind_engine = NULL; c->DYNAMIC_LIBNAME = NULL; c->no_vcheck = 0; c->engine_id = NULL; c->list_add_value = 0; c->DYNAMIC_F1 = "v_check"; c->DYNAMIC_F2 = "bind_engine"; c->dir_load = 1; c->dirs = sk_OPENSSL_STRING_new_null(); if (!c->dirs) { ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); OPENSSL_free(c); return 0; } CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx)) == NULL) { /* Good, we're the first */ ENGINE_set_ex_data(e, dynamic_ex_data_idx, c); *ctx = c; c = NULL; } CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); /* * If we lost the race to set the context, c is non-NULL and *ctx is the * context of the thread that won. */ if (c) { sk_OPENSSL_STRING_free(c->dirs); OPENSSL_free(c); } return 1; }
static ENGINE_CTX *get_ctx(ENGINE *engine) { ENGINE_CTX *ctx; if (pkcs11_idx < 0) { pkcs11_idx = ENGINE_get_ex_new_index(0, "pkcs11", NULL, NULL, 0); if (pkcs11_idx < 0) return NULL; ctx = NULL; } else { ctx = ENGINE_get_ex_data(engine, pkcs11_idx); } if (ctx == NULL) { ctx = pkcs11_new(); ENGINE_set_ex_data(engine, pkcs11_idx, ctx); } return ctx; }
static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, DSA *dsa) { HCRYPTHASH hash; DWORD slen; DSA_SIG *ret = NULL; CAPI_KEY *capi_key; CAPI_CTX *ctx; unsigned char csigbuf[40]; ctx = ENGINE_get_ex_data(dsa->engine, capi_idx); CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n"); capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); if (!capi_key) { CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY); return NULL; } if (dlen != 20) { CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH); return NULL; } /* Create the hash object */ if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash)) { CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); capi_addlasterror(); return NULL; } /* Set the hash value to the value passed */ if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0)) { CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE); capi_addlasterror(); goto err; } /* Finally sign it */ slen = sizeof(csigbuf); if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen)) { CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH); capi_addlasterror(); goto err; } else { ret = DSA_SIG_new(); if (!ret) goto err; ret->r = BN_new(); ret->s = BN_new(); if (!ret->r || !ret->s) goto err; if (!lend_tobn(ret->r, csigbuf, 20) || !lend_tobn(ret->s, csigbuf + 20, 20)) { DSA_SIG_free(ret); ret = NULL; goto err; } } /* Now cleanup */ err: OPENSSL_cleanse(csigbuf, 40); CryptDestroyHash(hash); return ret; }
int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, const RSA *rsa) { ALG_ID alg; HCRYPTHASH hash; DWORD slen; unsigned int i; int ret = -1; CAPI_KEY *capi_key; CAPI_CTX *ctx; ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); CAPI_trace(ctx, "Called CAPI_rsa_sign()\n"); capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); if (!capi_key) { CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY); return -1; } /* Convert the signature type to a CryptoAPI algorithm ID */ switch(dtype) { case NID_sha1: alg = CALG_SHA1; break; case NID_md5: alg = CALG_MD5; break; case NID_md5_sha1: alg = CALG_SSL3_SHAMD5; break; default: { char algstr[10]; BIO_snprintf(algstr, 10, "%lx", dtype); CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID); ERR_add_error_data(2, "NID=0x", algstr); return -1; } } /* Create the hash object */ if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash)) { CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); capi_addlasterror(); return -1; } /* Set the hash value to the value passed */ if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0)) { CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE); capi_addlasterror(); goto err; } /* Finally sign it */ slen = RSA_size(rsa); if(!CryptSignHashA(hash, capi_key->keyspec, NULL, 0, sigret, &slen)) { CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH); capi_addlasterror(); goto err; } else { ret = 1; /* Inplace byte reversal of signature */ for(i = 0; i < slen / 2; i++) { unsigned char c; c = sigret[i]; sigret[i] = sigret[slen - i - 1]; sigret[slen - i - 1] = c; } *siglen = slen; } /* Now cleanup */ err: CryptDestroyHash(hash); return ret; }
static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) { int ret = 1; CAPI_CTX *ctx; BIO *out; if (capi_idx == -1) { CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED); return 0; } ctx = ENGINE_get_ex_data(e, capi_idx); out = BIO_new_fp(stdout, BIO_NOCLOSE); switch (cmd) { case CAPI_CMD_LIST_CSPS: ret = capi_list_providers(ctx, out); break; case CAPI_CMD_LIST_CERTS: ret = capi_list_certs(ctx, out, NULL); break; case CAPI_CMD_LOOKUP_CERT: ret = capi_list_certs(ctx, out, p); break; case CAPI_CMD_LIST_CONTAINERS: ret = capi_list_containers(ctx, out); break; case CAPI_CMD_STORE_NAME: if (ctx->storename) OPENSSL_free(ctx->storename); ctx->storename = BUF_strdup(p); CAPI_trace(ctx, "Setting store name to %s\n", p); break; case CAPI_CMD_STORE_FLAGS: if (i & 1) { ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE; ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER; } else { ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER; ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE; } CAPI_trace(ctx, "Setting flags to %d\n", i); break; case CAPI_CMD_DEBUG_LEVEL: ctx->debug_level = (int)i; CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level); break; case CAPI_CMD_DEBUG_FILE: ctx->debug_file = BUF_strdup(p); CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file); break; case CAPI_CMD_KEYTYPE: ctx->keytype = i; CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype); break; case CAPI_CMD_SET_CSP_IDX: ret = capi_ctx_set_provname_idx(ctx, i); break; case CAPI_CMD_LIST_OPTIONS: ctx->dump_flags = i; break; case CAPI_CMD_LOOKUP_METHOD: if (i < 1 || i > 3) { CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD); return 0; } ctx->lookup_method = i; break; case CAPI_CMD_SET_CSP_NAME: ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1); break; case CAPI_CMD_SET_CSP_TYPE: ctx->csptype = i; break; default: CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND); ret = 0; } BIO_free(out); return ret; }
static int/*bool*/ nss_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) { int ret = 0; NSS_CTX *ctx; CALL_TRACE("nss_ctrl() cmd=%d\n", cmd); /* Put commands that do not require initialisation here*/ switch (cmd) { #ifdef CMD_SO_PATH case CMD_SO_PATH: { /* not implemented */; goto done; } break; #endif } /* Put commands that require initialisation here */ if (nss_eng_ctx_index < 0) { NSSerr(NSS_F_CTRL, NSS_R_ENGINE_NOT_INITIALIZED); return(ret); } ctx = ENGINE_get_ex_data(e, nss_eng_ctx_index); switch (cmd) { case E_NSS_CMD_CONFIG_DIR: { ret = nss_cmd_nss_config_dir(ctx, (char*) p); } break; case E_NSS_CMD_DEBUG_LEVEL: { if (0 <= i && i <= NSS_LOGLEVEL_LAST) { ctx->debug_level = (int) i; ret = 1; } } break; case E_NSS_CMD_ERROR_FILE: { if (ctx->error_file != NULL) OPENSSL_free((void*)ctx->error_file); ctx->error_file = BUF_strdup(p); ret = 1; } break; case E_NSS_CMD_LIST_CERTS: { ret = nss_cmd_list_cert(ctx, i); } break; case E_NSS_CMD_PRINT_CERT: { ret = nss_cmd_print_cert(ctx, (char*) p); } break; case E_NSS_CMD_LOAD_CERT: { ret = nss_cmd_load_cert(ctx, p); } break; case E_NSS_CMD_EVP_CERT: { ret = nss_cmd_evp_cert(ctx, p); } break; default: { nss_trace(ctx, "nss_ctrl() <UNKNOWN=%d>\n", cmd); goto done; } break; } done: return(ret); }
* This is free software; see Copyright file in the source * distribution for preciese wording. * * Copyright (C) 2011 Roumen Petrov */ static EVP_PKEY* nss_load_key(ENGINE *e, const char *key_id, int private, NSS_UI *wincx) { NSS_CTX *ctx; CERTCertificate *cert = NULL; SECKEYPrivateKey *pvtkey = NULL; SECKEYPublicKey *pubkey = NULL; EVP_PKEY *pkey = NULL; NSS_KEYCTX *keyctx = NULL; ctx = ENGINE_get_ex_data(e, nss_eng_ctx_index); nss_verbose(ctx, "nss_load_key(): private=%d, key_id='%s'\n", private, key_id); if (!NSS_IsInitialized()) { nss_trace(ctx, "nss_load_key(): nss is not initialized\n"); NSSerr(NSS_F_LOAD_KEY, NSS_R_DB_IS_NOT_INITIALIZED); goto done; } cert = PK11_FindCertFromNickname(key_id, NULL); if (cert == NULL) { NSSerr(NSS_F_LOAD_KEY, NSS_R_MISSING_CERT); goto done; } nss_debug(ctx, "nss_load_key(): The signer's certificate (%p) was found.\n", cert);