summaryrefslogtreecommitdiffstats
path: root/engines
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2008-05-30 17:03:16 +0000
committerDr. Stephen Henson <steve@openssl.org>2008-05-30 17:03:16 +0000
commit3aaeb5c1e505cca00bf88dc68a86ad9b945fa680 (patch)
tree4106d55777022c67dbd29d9bd68245aacf8da107 /engines
parent80ec6cc8068db1b4b010abe85de7313ca6aa7349 (diff)
Untested initial CryptoAPI dsa signing code.
Diffstat (limited to 'engines')
-rw-r--r--engines/e_capi.c77
1 files changed, 74 insertions, 3 deletions
diff --git a/engines/e_capi.c b/engines/e_capi.c
index 8af6b8edde..a30a12b2a6 100644
--- a/engines/e_capi.c
+++ b/engines/e_capi.c
@@ -414,6 +414,7 @@ static int bind_capi(ENGINE *e)
|| !ENGINE_set_finish_function(e, capi_finish)
|| !ENGINE_set_destroy_function(e, capi_destroy)
|| !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_cmd_defns(e, capi_cmd_defns)
|| !ENGINE_set_ctrl_function(e, capi_ctrl))
@@ -588,7 +589,7 @@ static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
}
dsa_plen = dp->bitlen / 8;
btmp = (unsigned char *)(dp + 1);
- dkey = DSA_new();
+ dkey = DSA_new_method(eng);
if (!dkey)
goto memerr;
dkey->p = BN_new();
@@ -779,7 +780,8 @@ int capi_rsa_priv_dec(int flen, const unsigned char *from,
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];
+ 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))
@@ -805,10 +807,79 @@ static int capi_rsa_free(RSA *rsa)
return 1;
}
+/* CryptoAPI DSA operations */
+
static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
DSA *dsa)
{
- return NULL;
+ 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_RSA_SIGN, CAPI_R_CANT_GET_KEY);
+ return NULL;
+ }
+
+ if (dlen != 20)
+ {
+ /* Invalid signature length */
+ }
+
+ /* Create the hash object */
+ if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash)) {
+ CAPIerr(CAPI_F_CAPI_RSA_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_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
+ capi_addlasterror();
+ goto err;
+ }
+
+
+ /* Finally sign it */
+ slen = 40;
+ if(!CryptSignHash(hash, AT_SIGNATURE, NULL, 0, csigbuf, &slen))
+ {
+ CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
+ capi_addlasterror();
+ goto err;
+ }
+ else
+ {
+ ret = DSA_SIG_new();
+ if (!ret)
+ 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;
}
static int capi_dsa_free(DSA *dsa)