RSA signature verification in gpg-agent?
NIIBE Yutaka
gniibe at fsij.org
Mon Sep 28 08:33:34 CEST 2015
Hello,
So, here is the change to move signature checking to gpg-agent.
It goes through 'make check' without failure.
diff --git a/agent/pksign.c b/agent/pksign.c
index 1d3d3d8..243c49d 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -290,10 +290,12 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
const void *overridedata, size_t overridedatalen)
{
gcry_sexp_t s_skey = NULL, s_sig = NULL;
+ gcry_sexp_t s_hash = NULL;
unsigned char *shadow_info = NULL;
unsigned int rc = 0; /* FIXME: gpg-error? */
const unsigned char *data;
int datalen;
+ int check_signature = 0;
if (overridedata)
{
@@ -352,6 +354,7 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
if (is_RSA)
{
+ check_signature = 1;
if (*buf & 0x80)
{
len++;
@@ -431,8 +434,7 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
else
{
/* No smartcard, but a private key */
- gcry_sexp_t s_hash = NULL;
- int dsaalgo;
+ int dsaalgo = 0;
/* Put the hash into a sexp */
if (agent_is_eddsa_key (s_skey))
@@ -454,6 +456,10 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
if (rc)
goto leave;
+ if (dsaalgo == 0 && GCRYPT_VERSION_NUMBER < 0x010700)
+ /* It's RSA and Libgcrypt < 1.7 */
+ check_signature = 1;
+
if (DBG_CRYPTO)
{
gcry_log_debugsxp ("skey", s_skey);
@@ -462,7 +468,6 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
/* sign */
rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
- gcry_sexp_release (s_hash);
if (rc)
{
log_error ("signing failed: %s\n", gpg_strerror (rc));
@@ -473,11 +478,42 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
gcry_log_debugsxp ("rslt", s_sig);
}
+ /* Check that the signature verification worked and nothing is
+ * fooling us e.g. by a bug in the signature create code or by
+ * deliberately introduced faults. Because Libgcrypt 1.7 does this
+ * for RSA internally there is no need to do it here again. */
+ if (check_signature)
+ {
+ if (s_hash == NULL)
+ {
+ if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1)
+ rc = do_encode_raw_pkcs1 (data, datalen,
+ gcry_pk_get_nbits (s_skey),
+ &s_hash);
+ else
+ rc = do_encode_md (data, datalen,
+ ctrl->digest.algo,
+ &s_hash,
+ ctrl->digest.raw_value);
+ }
+
+ rc = gcry_pk_verify (s_sig, s_hash, s_skey);
+
+ if (rc)
+ {
+ log_error (_("checking created signature failed: %s\n"),
+ gpg_strerror (rc));
+ gcry_sexp_release (s_sig);
+ s_sig = NULL;
+ }
+ }
+
leave:
*signature_sexp = s_sig;
gcry_sexp_release (s_skey);
+ gcry_sexp_release (s_hash);
xfree (shadow_info);
return rc;
diff --git a/g10/sign.c b/g10/sign.c
index 7a8d697..4a30f1e 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -229,7 +229,6 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
gcry_md_hd_t md, int mdalgo, const char *cache_nonce)
{
gpg_error_t err;
- gcry_mpi_t frame;
byte *dp;
char *hexgrip;
@@ -292,35 +291,6 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
}
xfree (hexgrip);
- /* Check that the signature verification worked and nothing is
- * fooling us e.g. by a bug in the signature create code or by
- * deliberately introduced faults. Because Libgcrypt 1.7 does this
- * for RSA internally there is no need to do it here again. */
- if (!err
-#if GCRYPT_VERSION_NUMBER >= 0x010700 /* Libgcrypt >= 1.7 */
- && !is_RSA (pksk->pubkey_algo)
-#endif /* Libgcrypt >= 1.7 */
- )
- {
- PKT_public_key *pk = xmalloc_clear (sizeof *pk);
-
- if (get_pubkey (pk, sig->keyid ))
- err = gpg_error (GPG_ERR_NO_PUBKEY);
- else
- {
- frame = encode_md_value (pk, md, sig->digest_algo );
- if (!frame)
- err = gpg_error (GPG_ERR_GENERAL);
- else
- err = pk_verify (pk->pubkey_algo, frame, sig->data, pk->pkey);
- gcry_mpi_release (frame);
- }
- if (err)
- log_error (_("checking created signature failed: %s\n"),
- gpg_strerror (err));
- free_public_key (pk);
- }
-
if (err)
log_error (_("signing failed: %s\n"), gpg_strerror (err));
else
--
More information about the Gnupg-devel
mailing list