aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2017-07-27 11:56:38 +0000
committerWerner Koch <[email protected]>2017-07-27 11:56:38 +0000
commita0d0cbee7654ad7582400efaa92d493cd8e669e9 (patch)
tree20bfb26e2b78690f8ab54dc115dd5543f3331618
parentindent: Wrap an overlong line. (diff)
downloadgnupg-a0d0cbee7654ad7582400efaa92d493cd8e669e9.tar.gz
gnupg-a0d0cbee7654ad7582400efaa92d493cd8e669e9.zip
gpg,sm: Fix compliance checking for decryption.
* common/compliance.c (gnupg_pk_is_compliant): Remove the Elgamal signing check. We don't support Elgamal signing at all. (gnupg_pk_is_allowed) <de-vs>: Revert encryption/decryption for RSA. Check the curvenames for ECDH. * g10/pubkey-enc.c (get_session_key): Print only a warning if the key is not compliant. * sm/decrypt.c (gpgsm_decrypt): Ditto. Use the same string as in gpg so that we have only one translation. -- We always allow decryption and print only a note if the key was not complaint at the encryption site. GnuPG-bug-id: 3308 Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--common/compliance.c46
-rw-r--r--g10/pubkey-enc.c42
-rw-r--r--sm/decrypt.c22
3 files changed, 62 insertions, 48 deletions
diff --git a/common/compliance.c b/common/compliance.c
index 268ea4dbf..951172415 100644
--- a/common/compliance.c
+++ b/common/compliance.c
@@ -99,7 +99,7 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
gcry_mpi_t key[], unsigned int keylength,
const char *curvename)
{
- enum { is_rsa, is_dsa, is_pgp5, is_elg_sign, is_ecc } algotype;
+ enum { is_rsa, is_dsa, is_elg, is_ecc } algotype;
int result = 0;
if (! initialized)
@@ -118,7 +118,7 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
break;
case PUBKEY_ALGO_ELGAMAL_E:
- algotype = is_pgp5;
+ algotype = is_elg;
break;
case PUBKEY_ALGO_ECDH:
@@ -128,8 +128,7 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
break;
case PUBKEY_ALGO_ELGAMAL:
- algotype = is_elg_sign;
- break;
+ return 0; /* Signing with Elgamal is not at all supported. */
default: /* Unknown. */
return 0;
@@ -141,7 +140,7 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
switch (algotype)
{
- case is_pgp5:
+ case is_elg:
result = 0;
break;
@@ -183,11 +182,6 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
}
xfree (curve);
}
- else if (algotype == is_elg_sign)
- {
- /* An Elgamal signing key is only RFC-2440 compliant. */
- result = (compliance == CO_RFC2440);
- }
else
{
result = 1; /* Assume compliance. */
@@ -219,9 +213,9 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
case PUBKEY_ALGO_RSA_S:
switch (use)
{
- case PK_USE_ENCRYPTION:
- return 1;
case PK_USE_DECRYPTION:
+ return 1;
+ case PK_USE_ENCRYPTION:
case PK_USE_SIGNING:
return (keylength == 2048
|| keylength == 3072
@@ -253,10 +247,34 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
case PUBKEY_ALGO_ELGAMAL:
case PUBKEY_ALGO_ELGAMAL_E:
- return use == PK_USE_ENCRYPTION;
+ return use == PK_USE_DECRYPTION;
case PUBKEY_ALGO_ECDH:
- return use == PK_USE_ENCRYPTION;
+ if (use == PK_USE_DECRYPTION)
+ return 1;
+ else if (use == PK_USE_ENCRYPTION)
+ {
+ int result = 0;
+ char *curve = NULL;
+
+ if (!curvename && key)
+ {
+ curve = openpgp_oid_to_str (key[0]);
+ curvename = openpgp_oid_to_curve (curve, 0);
+ if (!curvename)
+ curvename = curve;
+ }
+
+ result = (curvename
+ && (!strcmp (curvename, "brainpoolP256r1")
+ || !strcmp (curvename, "brainpoolP384r1")
+ || !strcmp (curvename, "brainpoolP512r1")));
+
+ xfree (curve);
+ return result;
+ }
+ else
+ return 0;
case PUBKEY_ALGO_ECDSA:
{
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index 0ddb8d7bb..013fd2f1b 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -90,19 +90,16 @@ get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
sk->pubkey_algo = k->pubkey_algo; /* We want a pubkey with this algo. */
if (!(rc = get_seckey (ctrl, sk, k->keyid)))
{
- /* Check compliance. */
- if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
- sk->pubkey_algo,
- sk->pkey, nbits_from_pk (sk), NULL))
- {
- log_info (_("key %s not suitable for decryption"
- " while in %s mode\n"),
- keystr_from_pk (sk),
- gnupg_compliance_option_string (opt.compliance));
- rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
- }
- else
- rc = get_it (ctrl, k, dek, sk, k->keyid);
+ /* Print compliance warning. */
+ if (!gnupg_pk_is_compliant (opt.compliance,
+ sk->pubkey_algo,
+ sk->pkey, nbits_from_pk (sk), NULL))
+ log_info (_("Note: key %s was not suitable for encryption"
+ " in %s mode\n"),
+ keystr_from_pk (sk),
+ gnupg_compliance_option_string (opt.compliance));
+
+ rc = get_it (ctrl, k, dek, sk, k->keyid);
}
}
else if (opt.skip_hidden_recipients)
@@ -131,17 +128,14 @@ get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
log_info (_("anonymous recipient; trying secret key %s ...\n"),
keystr (keyid));
- /* Check compliance. */
- if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
- sk->pubkey_algo,
- sk->pkey, nbits_from_pk (sk), NULL))
- {
- log_info (_("key %s not suitable for decryption"
- " while in %s mode\n"),
- keystr_from_pk (sk),
- gnupg_compliance_option_string (opt.compliance));
- continue;
- }
+ /* Print compliance warning. */
+ if (!gnupg_pk_is_compliant (opt.compliance,
+ sk->pubkey_algo,
+ sk->pkey, nbits_from_pk (sk), NULL))
+ log_info (_("Note: key %s was not suitable for encryption"
+ " in %s mode\n"),
+ keystr_from_pk (sk),
+ gnupg_compliance_option_string (opt.compliance));
rc = get_it (ctrl, k, dek, sk, keyid);
if (!rc)
diff --git a/sm/decrypt.c b/sm/decrypt.c
index 170ad5ad3..3de742a25 100644
--- a/sm/decrypt.c
+++ b/sm/decrypt.c
@@ -480,17 +480,19 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
unsigned int nbits;
int pk_algo = gpgsm_get_key_algo_info (cert, &nbits);
- /* Check compliance. */
- if (! gnupg_pk_is_allowed (opt.compliance,
- PK_USE_DECRYPTION,
- pk_algo, NULL, nbits, NULL))
+ /* Print compliance warning. */
+ if (! gnupg_pk_is_compliant (opt.compliance,
+ pk_algo, NULL, nbits, NULL))
{
- log_error ("certificate ID 0x%08lX not suitable for "
- "decryption while in %s mode\n",
- gpgsm_get_short_fingerprint (cert, NULL),
- gnupg_compliance_option_string (opt.compliance));
- rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
- goto oops;
+ char kidstr[10+1];
+
+ snprintf (kidstr, sizeof kidstr, "0x%08lX",
+ gpgsm_get_short_fingerprint (cert, NULL));
+ log_info
+ (_("Note: key %s was not suitable for encryption"
+ " in %s mode\n"),
+ kidstr,
+ gnupg_compliance_option_string (opt.compliance));
}
/* Check that all certs are compliant with CO_DE_VS. */