aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/openpgp-oid.c6
-rw-r--r--doc/DETAILS4
-rw-r--r--sm/fingerprint.c70
-rw-r--r--sm/gpgsm.h3
-rw-r--r--sm/keylist.c25
5 files changed, 89 insertions, 19 deletions
diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c
index 8fda23028..55f8f432d 100644
--- a/common/openpgp-oid.c
+++ b/common/openpgp-oid.c
@@ -540,9 +540,9 @@ map_openpgp_pk_to_gcry (pubkey_algo_t algo)
/* Return a string describing the public key algorithm and the
* keysize. For elliptic curves the function prints the name of the
* curve because the keysize is a property of the curve. ALGO is the
- * Gcrypt algorithmj number, curve is either NULL or give the PID of
- * the curve, NBITS is either 0 or the size of the algorithms for RSA
- * etc. The returned string is taken from permanent table. Examples
+ * Gcrypt algorithm number, CURVE is either NULL or gives the OID of
+ * the curve, NBITS is either 0 or the size for algorithms like RSA.
+ * The returned string is taken from permanent table. Examples
* for the output are:
*
* "rsa3072" - RSA with 3072 bit
diff --git a/doc/DETAILS b/doc/DETAILS
index 7655489a5..a1c53b88e 100644
--- a/doc/DETAILS
+++ b/doc/DETAILS
@@ -238,8 +238,8 @@ described here.
*** Field 17 - Curve name
- For pub, sub, sec, and ssb records this field is used for the ECC
- curve name.
+ For pub, sub, sec, ssb, crt, and crs records this field is used
+ for the ECC curve name.
*** Field 18 - Compliance flags
diff --git a/sm/fingerprint.c b/sm/fingerprint.c
index ca44e1bc4..c3c37c2d6 100644
--- a/sm/fingerprint.c
+++ b/sm/fingerprint.c
@@ -219,20 +219,25 @@ gpgsm_get_keygrip_hexstring (ksba_cert_t cert)
/* Return the PK algorithm used by CERT as well as the length in bits
- of the public key at NBITS. */
+ * of the public key at NBITS. If R_CURVE is not NULL and an ECC
+ * algorithm is used the name or OID of the curve is stored there; the
+ * caller needs to free this value. */
int
-gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
+gpgsm_get_key_algo_info2 (ksba_cert_t cert, unsigned int *nbits, char **r_curve)
{
gcry_sexp_t s_pkey;
int rc;
ksba_sexp_t p;
size_t n;
gcry_sexp_t l1, l2;
+ const char *curve;
const char *name;
char namebuf[128];
if (nbits)
*nbits = 0;
+ if (r_curve)
+ *r_curve = NULL;
p = ksba_cert_get_public_key (cert);
if (!p)
@@ -258,6 +263,24 @@ gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
gcry_sexp_release (s_pkey);
return 0;
}
+
+ if (r_curve)
+ {
+ curve = gcry_pk_get_curve (l1, 0, NULL);
+ if (curve)
+ {
+ name = openpgp_oid_to_curve (openpgp_curve_to_oid (curve,
+ NULL, NULL), 0);
+ *r_curve = xtrystrdup (name? name : curve);
+ if (!*r_curve)
+ {
+ gcry_sexp_release (l1);
+ gcry_sexp_release (s_pkey);
+ return 0; /* Out of core. */
+ }
+ }
+ }
+
l2 = gcry_sexp_cadr (l1);
gcry_sexp_release (l1);
l1 = l2;
@@ -277,6 +300,49 @@ gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
}
+int
+gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
+{
+ return gpgsm_get_key_algo_info2 (cert, nbits, NULL);
+}
+
+
+/* This is a wrapper around pubkey_algo_string which takesa KSA
+ * certitificate instead of a Gcrypt public key. Note that this
+ * function may return NULL on error. */
+char *
+gpgsm_pubkey_algo_string (ksba_cert_t cert, int *r_algoid)
+{
+ gpg_error_t err;
+ gcry_sexp_t s_pkey;
+ ksba_sexp_t p;
+ size_t n;
+ enum gcry_pk_algos algoid;
+ char *algostr;
+
+ p = ksba_cert_get_public_key (cert);
+ if (!p)
+ return NULL;
+ n = gcry_sexp_canon_len (p, 0, NULL, NULL);
+ if (!n)
+ {
+ xfree (p);
+ return NULL;
+ }
+ err = gcry_sexp_sscan (&s_pkey, NULL, (char *)p, n);
+ xfree (p);
+ if (err)
+ return NULL;
+
+ algostr = pubkey_algo_string (s_pkey, r_algoid? &algoid : NULL);
+ if (algostr && r_algoid)
+ *r_algoid = algoid;
+
+ gcry_sexp_release (s_pkey);
+ return algostr;
+}
+
+
/* If KEY is an RSA key, return its modulus. For non-RSA keys or on
* error return NULL. */
gcry_mpi_t
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 580f2d6f6..c4df8496e 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -286,6 +286,9 @@ unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert,
unsigned char *gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array);
char *gpgsm_get_keygrip_hexstring (ksba_cert_t cert);
int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits);
+int gpgsm_get_key_algo_info2 (ksba_cert_t cert, unsigned int *nbits,
+ char **r_curve);
+char *gpgsm_pubkey_algo_string (ksba_cert_t cert, int *r_algoid);
gcry_mpi_t gpgsm_get_rsa_modulus (ksba_cert_t cert);
char *gpgsm_get_certid (ksba_cert_t cert);
diff --git a/sm/keylist.c b/sm/keylist.c
index 1fd2892ce..c1e5bf5c4 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -425,6 +425,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
gpg_error_t valerr;
int algo;
unsigned int nbits;
+ char *curve = NULL;
const char *chain_id;
char *chain_id_buffer = NULL;
int is_root = 0;
@@ -516,7 +517,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
if (*truststring)
es_fputs (truststring, fp);
- algo = gpgsm_get_key_algo_info (cert, &nbits);
+ algo = gpgsm_get_key_algo_info2 (cert, &nbits, &curve);
es_fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
ksba_cert_get_validity (cert, 0, t);
@@ -580,6 +581,8 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
}
es_putc (':', fp); /* End of field 15. */
es_putc (':', fp); /* End of field 16. */
+ if (curve)
+ es_fputs (curve, fp);
es_putc (':', fp); /* End of field 17. */
print_compliance_flags (cert, algo, nbits, fp);
es_putc (':', fp); /* End of field 18. */
@@ -639,6 +642,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
xfree (p);
}
xfree (kludge_uid);
+ xfree (curve);
}
@@ -835,12 +839,11 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
es_fprintf (fp, " hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
{
- const char *algoname;
- unsigned int nbits;
+ char *algostr;
- algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
- es_fprintf (fp, " keyType: %u bit %s\n",
- nbits, algoname? algoname:"?");
+ algostr = gpgsm_pubkey_algo_string (cert, NULL);
+ es_fprintf (fp, " keyType: %s\n", algostr? algostr : "[error]");
+ xfree (algostr);
}
/* subjectKeyIdentifier */
@@ -1195,15 +1198,13 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
{
- const char *algoname;
- unsigned int nbits;
+ char *algostr;
- algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
- es_fprintf (fp, " key type: %u bit %s\n",
- nbits, algoname? algoname:"?");
+ algostr = gpgsm_pubkey_algo_string (cert, NULL);
+ es_fprintf (fp, " key type: %s\n", algostr? algostr : "[error]");
+ xfree (algostr);
}
-
err = ksba_cert_get_key_usage (cert, &kusage);
if (gpg_err_code (err) != GPG_ERR_NO_DATA)
{