aboutsummaryrefslogtreecommitdiffstats
path: root/g10/pubkey-enc.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2010-04-23 11:36:59 +0000
committerWerner Koch <[email protected]>2010-04-23 11:36:59 +0000
commit8e5010a958ded63ab6df89e1ba4d45ed9f2e572a (patch)
tree7859b79f876bc753dd2732b3d2348684bc766dbc /g10/pubkey-enc.c
parent2010-04-23 Marcus Brinkmann <[email protected]> (diff)
downloadgnupg-8e5010a958ded63ab6df89e1ba4d45ed9f2e572a.tar.gz
gnupg-8e5010a958ded63ab6df89e1ba4d45ed9f2e572a.zip
Decryption and signi via agent is now implemented.
Diffstat (limited to 'g10/pubkey-enc.c')
-rw-r--r--g10/pubkey-enc.c125
1 files changed, 60 insertions, 65 deletions
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index 7959ee845..1a4ec0f96 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -39,7 +39,7 @@
static gpg_error_t get_it (PKT_pubkey_enc *k,
- DEK *dek, PKT_secret_key *sk, u32 *keyid);
+ DEK *dek, PKT_public_key *sk, u32 *keyid);
/* Check that the given algo is mentioned in one of the valid user-ids. */
@@ -74,7 +74,7 @@ is_algo_in_prefs (kbnode_t keyblock, preftype_t type, int algo)
gpg_error_t
get_session_key (PKT_pubkey_enc * k, DEK * dek)
{
- PKT_secret_key *sk = NULL;
+ PKT_public_key *sk = NULL;
int rc;
rc = openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC);
@@ -84,7 +84,7 @@ get_session_key (PKT_pubkey_enc * k, DEK * dek)
if ((k->keyid[0] || k->keyid[1]) && !opt.try_all_secrets)
{
sk = xmalloc_clear (sizeof *sk);
- sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo */
+ sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo. */
if (!(rc = get_seckey (sk, k->keyid)))
rc = get_it (k, dek, sk, k->keyid);
}
@@ -99,9 +99,9 @@ get_session_key (PKT_pubkey_enc * k, DEK * dek)
for (;;)
{
if (sk)
- free_secret_key (sk);
+ free_public_key (sk);
sk = xmalloc_clear (sizeof *sk);
- rc = enum_secret_keys (&enum_context, sk, 1, 0);
+ rc = -1; /* FIXME:enum_secret_keys (&enum_context, sk, 1, 0);*/
if (rc)
{
rc = G10ERR_NO_SECKEY;
@@ -109,7 +109,7 @@ get_session_key (PKT_pubkey_enc * k, DEK * dek)
}
if (sk->pubkey_algo != k->pubkey_algo)
continue;
- keyid_from_sk (sk, keyid);
+ keyid_from_pk (sk, keyid);
log_info (_("anonymous recipient; trying secret key %s ...\n"),
keystr (keyid));
@@ -149,63 +149,59 @@ get_session_key (PKT_pubkey_enc * k, DEK * dek)
leave:
if (sk)
- free_secret_key (sk);
+ free_public_key (sk);
return rc;
}
static gpg_error_t
-get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
+get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
{
- int rc;
- gcry_mpi_t plain_dek = NULL;
+ gpg_error_t err;
byte *frame = NULL;
unsigned int n;
size_t nframe;
u16 csum, csum2;
-
int card = 0;
+ gcry_sexp_t s_data;
+ char *desc;
+ char *keygrip;
- if (sk->is_protected && sk->protect.s2k.mode == 1002)
- { /* Note, that we only support RSA for now. */
-#ifdef ENABLE_CARD_SUPPORT
- unsigned char *rbuf;
- size_t rbuflen;
- char *snbuf;
- unsigned char *indata = NULL;
- size_t indatalen;
-
- snbuf =
- serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
-
- if (gcry_mpi_aprint
- (GCRYMPI_FMT_USG, &indata, &indatalen, enc->data[0]))
- BUG ();
-
- rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
- xfree (snbuf);
- xfree (indata);
- if (rc)
- goto leave;
-
- frame = rbuf;
- nframe = rbuflen;
- card = 1;
-#else
- rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
- goto leave;
-#endif /*!ENABLE_CARD_SUPPORT */
+ /* Get the keygrip. */
+ err = hexkeygrip_from_pk (sk, &keygrip);
+ if (err)
+ goto leave;
+
+ /* Convert the data to an S-expression. */
+ if (sk->pubkey_algo == GCRY_PK_ELG || sk->pubkey_algo == GCRY_PK_ELG_E)
+ {
+ if (!enc->data[0] || !enc->data[1])
+ err = gpg_error (GPG_ERR_BAD_MPI);
+ else
+ err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))",
+ enc->data[0], enc->data[1]);
}
- else
+ else if (sk->pubkey_algo == GCRY_PK_RSA || sk->pubkey_algo == GCRY_PK_RSA_E)
{
- rc = pk_decrypt (sk->pubkey_algo, &plain_dek, enc->data, sk->skey);
- if (rc)
- goto leave;
- if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, plain_dek))
- BUG ();
- gcry_mpi_release (plain_dek);
- plain_dek = NULL;
+ if (!enc->data[0])
+ err = gpg_error (GPG_ERR_BAD_MPI);
+ else
+ err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))",
+ enc->data[0]);
}
+ else
+ err = gpg_error (GPG_ERR_BUG);
+
+ if (err)
+ goto leave;
+
+ /* Decrypt. */
+ desc = xtrystrdup ("FIXME: Format a description");
+ err = agent_pkdecrypt (NULL, keygrip, desc, s_data, &frame, &nframe);
+ xfree (desc);
+ gcry_sexp_release (s_data);
+ if (err)
+ goto leave;
/* Now get the DEK (data encryption key) from the frame
*
@@ -231,18 +227,18 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
{
if (n + 7 > nframe)
{
- rc = G10ERR_WRONG_SECKEY;
+ err = gpg_error (G10ERR_WRONG_SECKEY);
goto leave;
}
if (frame[n] == 1 && frame[nframe - 1] == 2)
{
log_info (_("old encoding of the DEK is not supported\n"));
- rc = G10ERR_CIPHER_ALGO;
+ err = gpg_error (G10ERR_CIPHER_ALGO);
goto leave;
}
- if (frame[n] != 2) /* Somethink is wrong. */
+ if (frame[n] != 2) /* Something went wrong. */
{
- rc = G10ERR_WRONG_SECKEY;
+ err = gpg_error (G10ERR_WRONG_SECKEY);
goto leave;
}
for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */
@@ -252,7 +248,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
if (n + 4 > nframe)
{
- rc = G10ERR_WRONG_SECKEY;
+ err = gpg_error (G10ERR_WRONG_SECKEY);
goto leave;
}
@@ -260,10 +256,10 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
dek->algo = frame[n++];
if (dek->algo == CIPHER_ALGO_IDEA)
write_status (STATUS_RSA_OR_IDEA);
- rc = openpgp_cipher_test_algo (dek->algo);
- if (rc)
+ err = openpgp_cipher_test_algo (dek->algo);
+ if (err)
{
- if (!opt.quiet && gpg_err_code (rc) == GPG_ERR_CIPHER_ALGO)
+ if (!opt.quiet && gpg_err_code (err) == GPG_ERR_CIPHER_ALGO)
{
log_info (_("cipher algorithm %d%s is unknown or disabled\n"),
dek->algo,
@@ -276,7 +272,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
}
if (dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo))
{
- rc = GPG_ERR_WRONG_SECKEY;
+ err = gpg_error (GPG_ERR_WRONG_SECKEY);
goto leave;
}
@@ -288,7 +284,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
csum2 += dek->key[n];
if (csum != csum2)
{
- rc = G10ERR_WRONG_SECKEY;
+ err = gpg_error (GPG_ERR_WRONG_SECKEY);
goto leave;
}
if (DBG_CIPHER)
@@ -301,7 +297,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
if (!pkb)
{
- rc = -1;
+ err = -1;
log_error ("oops: public key not found for preference check\n");
}
else if (pkb->pkt->pkt.public_key->selfsigversion > 3
@@ -310,7 +306,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
&& !is_algo_in_prefs (pkb, PREFTYPE_SYM, dek->algo))
log_info (_("WARNING: cipher algorithm %s not found in recipient"
" preferences\n"), openpgp_cipher_algo_name (dek->algo));
- if (!rc)
+ if (!err)
{
KBNODE k;
@@ -346,14 +342,13 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid)
}
release_kbnode (pkb);
- rc = 0;
+ err = 0;
}
-
-leave:
- gcry_mpi_release (plain_dek);
+ leave:
xfree (frame);
- return rc;
+ xfree (keygrip);
+ return err;
}