summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2002-04-12 20:54:34 +0200
committerWerner Koch <wk@gnupg.org>2002-04-12 20:54:34 +0200
commit7e07a397a009da4da1e21f8ce66fd7721b7a30c9 (patch)
tree12aeae79bc93b943aa9352c6c7933d303e6f9dfe
parent* card.c (card_open): Return immediately when no reader is available. (diff)
downloadgnupg2-7e07a397a009da4da1e21f8ce66fd7721b7a30c9.tar.xz
gnupg2-7e07a397a009da4da1e21f8ce66fd7721b7a30c9.zip
* certlist.c (cert_usable_p): New.
(gpgsm_cert_use_sign_p,gpgsm_cert_use_encrypt_p): New. (gpgsm_cert_use_verify_p,gpgsm_cert_use_decrypt_p): New. (gpgsm_add_to_certlist): Check the key usage. * sign.c (gpgsm_sign): Ditto. * verify.c (gpgsm_verify): Print a message wehn an unsuitable certificate was used. * decrypt.c (gpgsm_decrypt): Ditto * keylist.c (print_capabilities): Determine values from the cert.
-rw-r--r--common/errors.h1
-rw-r--r--sm/ChangeLog12
-rw-r--r--sm/certlist.c90
-rw-r--r--sm/decrypt.c4
-rw-r--r--sm/gpgsm.h4
-rw-r--r--sm/keylist.c41
-rw-r--r--sm/sign.c4
-rw-r--r--sm/verify.c1
8 files changed, 149 insertions, 8 deletions
diff --git a/common/errors.h b/common/errors.h
index 58508c93f..22c827299 100644
--- a/common/errors.h
+++ b/common/errors.h
@@ -102,6 +102,7 @@ enum {
GNUPG_Bad_PIN_Method = 73,
GNUPG_Card_Not_Initialized = 74,
GNUPG_Unsupported_Operation = 75,
+ GNUPG_Wrong_Key_Usage = 76,
};
/* Status codes - fixme: should go into another file */
diff --git a/sm/ChangeLog b/sm/ChangeLog
index 7793006dd..e28853fdb 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,3 +1,15 @@
+2002-04-11 Werner Koch <wk@gnupg.org>
+
+ * certlist.c (cert_usable_p): New.
+ (gpgsm_cert_use_sign_p,gpgsm_cert_use_encrypt_p): New.
+ (gpgsm_cert_use_verify_p,gpgsm_cert_use_decrypt_p): New.
+ (gpgsm_add_to_certlist): Check the key usage.
+ * sign.c (gpgsm_sign): Ditto.
+ * verify.c (gpgsm_verify): Print a message wehn an unsuitable
+ certificate was used.
+ * decrypt.c (gpgsm_decrypt): Ditto
+ * keylist.c (print_capabilities): Determine values from the cert.
+
2002-03-28 Werner Koch <wk@gnupg.org>
* keylist.c (list_cert_colon): Fixed listing of crt record; the
diff --git a/sm/certlist.c b/sm/certlist.c
index fe45f1d22..2d52ada30 100644
--- a/sm/certlist.c
+++ b/sm/certlist.c
@@ -32,6 +32,71 @@
#include "gpgsm.h"
#include "keydb.h"
+#include "i18n.h"
+
+/* Return 0 if the cert is usable for encryption. A MODE of 0 checks
+ for signing a MODE of 1 checks for encryption, a MODE of 2 checks
+ for verification and a MODE of 3 for decryption (just for
+ debugging) */
+static int
+cert_usage_p (KsbaCert cert, int mode)
+{
+ KsbaError err;
+ unsigned int use;
+
+ err = ksba_cert_get_key_usage (cert, &use);
+ if (err == KSBA_No_Data)
+ {
+ if (opt.verbose && mode < 2)
+ log_info (mode?
+ _("no key usage specified - accepted for encryption\n"):
+ _("no key usage specified - accepted for signing\n"));
+ return 0;
+ }
+ if (err)
+ {
+ log_error (_("error getting key usage information: %s\n"),
+ ksba_strerror (err));
+ return map_ksba_err (err);
+ }
+
+ if ((use & ((mode&1)? KSBA_KEYUSAGE_DIGITAL_SIGNATURE
+ : KSBA_KEYUSAGE_KEY_ENCIPHERMENT)))
+ return 0;
+ log_info (mode==3? _("certificate should have not been used for encryption\n"):
+ mode==2? _("certificate should have not been used for signing\n"):
+ mode==1? _("certificate is not usable for encryption\n"):
+ _("certificate is not usable for signing\n"));
+ return GNUPG_Wrong_Key_Usage;
+}
+
+
+/* Return 0 if the cert is usable for signing */
+int
+gpgsm_cert_use_sign_p (KsbaCert cert)
+{
+ return cert_usage_p (cert, 0);
+}
+
+
+/* Return 0 if the cert is usable for encryption */
+int
+gpgsm_cert_use_encrypt_p (KsbaCert cert)
+{
+ return cert_usage_p (cert, 1);
+}
+
+int
+gpgsm_cert_use_verify_p (KsbaCert cert)
+{
+ return cert_usage_p (cert, 2);
+}
+
+int
+gpgsm_cert_use_decrypt_p (KsbaCert cert)
+{
+ return cert_usage_p (cert, 3);
+}
/* add a certificate to a list of certificate and make sure that it is
a valid certificate */
@@ -51,17 +116,40 @@ gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr)
rc = GNUPG_Out_Of_Core;
else
{
+ int wrong_usage = 0;
+ get_next:
rc = keydb_search (kh, &desc, 1);
if (!rc)
rc = keydb_get_cert (kh, &cert);
if (!rc)
{
+ rc = gpgsm_cert_use_encrypt_p (cert);
+ if (rc == GNUPG_Wrong_Key_Usage)
+ {
+ /* There might be another certificate with the
+ correct usage, so we better try again */
+ wrong_usage = rc;
+ ksba_cert_release (cert);
+ cert = NULL;
+ goto get_next;
+ }
+ }
+ /* we want the error code from the first match in this case */
+ if (wrong_usage)
+ rc = wrong_usage;
+
+ if (!rc)
+ {
+ /* Fixme: If we ever have two certifciates differing
+ only in the key usage, we should only bail out here
+ if the certificate differes just in the key usage.
+ However we need to find some criteria to match the
+ identities */
rc = keydb_search (kh, &desc, 1);
if (rc == -1)
rc = 0;
else if (!rc)
rc = GNUPG_Ambiguous_Name;
-
}
if (!rc)
rc = gpgsm_validate_path (cert);
diff --git a/sm/decrypt.c b/sm/decrypt.c
index 4e513a28b..e3566fd13 100644
--- a/sm/decrypt.c
+++ b/sm/decrypt.c
@@ -378,6 +378,10 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
log_error ("failed to get cert: %s\n", gnupg_strerror (rc));
goto oops;
}
+ /* Just in case there is a problem with the own
+ certificate we print this message - should never
+ happen of course */
+ gpgsm_cert_use_decrypt_p (cert);
hexkeygrip = gpgsm_get_keygrip_hexstring (cert);
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index a46627da3..9cba457dd 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -178,6 +178,10 @@ int gpgsm_validate_path (KsbaCert cert);
int gpgsm_basic_cert_check (KsbaCert cert);
/*-- certlist.c --*/
+int gpgsm_cert_use_sign_p (KsbaCert cert);
+int gpgsm_cert_use_encrypt_p (KsbaCert cert);
+int gpgsm_cert_use_verify_p (KsbaCert cert);
+int gpgsm_cert_use_decrypt_p (KsbaCert cert);
int gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr);
void gpgsm_release_certlist (CERTLIST list);
int gpgsm_find_cert (const char *name, KsbaCert *r_cert);
diff --git a/sm/keylist.c b/sm/keylist.c
index bccb26b6e..18d570ec8 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -32,7 +32,7 @@
#include "gpgsm.h"
#include "keydb.h"
-
+#include "i18n.h"
@@ -56,12 +56,39 @@ print_key_data (KsbaCert cert, FILE *fp)
static void
print_capabilities (KsbaCert cert, FILE *fp)
{
- putc ('e', fp);
- putc ('s', fp);
- putc ('c', fp);
- putc ('E', fp);
- putc ('S', fp);
- putc ('C', fp);
+ KsbaError err;
+ unsigned int use;
+
+ err = ksba_cert_get_key_usage (cert, &use);
+ if (err == KSBA_No_Data)
+ {
+ putc ('e', fp);
+ putc ('s', fp);
+ putc ('c', fp);
+ putc ('E', fp);
+ putc ('S', fp);
+ putc ('C', fp);
+ return;
+ }
+ if (err)
+ {
+ log_error (_("error getting key usage information: %s\n"),
+ ksba_strerror (err));
+ return;
+ }
+
+ if ((use & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
+ putc ('e', fp);
+ if ((use & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
+ putc ('s', fp);
+ if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
+ putc ('c', fp);
+ if ((use & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
+ putc ('E', fp);
+ if ((use & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
+ putc ('S', fp);
+ if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
+ putc ('C', fp);
}
diff --git a/sm/sign.c b/sm/sign.c
index b16e840bc..2781baa84 100644
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -310,6 +310,10 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
rc = seterr (General_Error);
goto leave;
}
+ rc = gpgsm_cert_use_sign_p (cert);
+ if (rc)
+ goto leave;
+
err = ksba_cms_add_signer (cms, cert);
if (err)
{
diff --git a/sm/verify.c b/sm/verify.c
index 69e18ac25..f4d80393a 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -370,6 +370,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp)
gpgsm_status (ctrl, STATUS_BADSIG, NULL);
goto next_signer;
}
+ gpgsm_cert_use_verify_p (cert); /* this displays an info message */
log_debug ("signature okay - checking certs\n");
gpgsm_status (ctrl, STATUS_GOODSIG, NULL);
{