diff --git a/sm/ChangeLog b/sm/ChangeLog index af7ddb1c6..a1997e27e 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,5 +1,15 @@ 2004-05-11 Werner Koch + * sign.c (gpgsm_sign): Include the error source in the final error + message. + * decrypt.c (gpgsm_decrypt): Ditto. + + * fingerprint.c (gpgsm_get_key_algo_info): New. + * sign.c (gpgsm_sign): Don't assume RSA in the status line. + * keylist.c (list_cert_colon): Really print the algorithm and key + length. + (list_cert_raw, list_cert_std): Ditto. + * gpgsm.c: New option --debug-allow-core-dump. * gpgsm.h (opt): Add member CONFIG_FILENAME. diff --git a/sm/decrypt.c b/sm/decrypt.c index 9a21cfb46..de53af9e7 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -495,7 +495,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp) if (rc) { gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL); - log_error ("message decryption failed: %s\n", gpg_strerror (rc)); + log_error ("message decryption failed: %s <%s>\n", + gpg_strerror (rc), gpg_strsource (rc)); } ksba_cms_release (cms); gpgsm_destroy_reader (b64reader); diff --git a/sm/fingerprint.c b/sm/fingerprint.c index 6755f8eb7..7fe619c18 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -198,6 +198,66 @@ 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. */ +int +gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits) +{ + gcry_sexp_t s_pkey; + int rc; + ksba_sexp_t p; + size_t n; + gcry_sexp_t l1, l2; + const char *name; + char namebuf[128]; + + if (nbits) + *nbits = 0; + + p = ksba_cert_get_public_key (cert); + if (!p) + return 0; + n = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!n) + { + xfree (p); + return 0; + } + rc = gcry_sexp_sscan (&s_pkey, NULL, p, n); + xfree (p); + if (rc) + return 0; + + if (nbits) + *nbits = gcry_pk_get_nbits (s_pkey); + + /* Breaking the algorithm out of the S-exp is a bit of a challenge ... */ + l1 = gcry_sexp_find_token (s_pkey, "public-key", 0); + if (!l1) + { + gcry_sexp_release (s_pkey); + return 0; + } + l2 = gcry_sexp_cadr (l1); + gcry_sexp_release (l1); + l1 = l2; + name = gcry_sexp_nth_data (l1, 0, &n); + if (name) + { + if (n > sizeof namebuf -1) + n = sizeof namebuf -1; + memcpy (namebuf, name, n); + namebuf[n] = 0; + } + else + *namebuf = 0; + gcry_sexp_release (l1); + gcry_sexp_release (s_pkey); + return gcry_pk_map_name (namebuf); +} + + + /* For certain purposes we need a certificate id which has an upper limit of the size. We use the hash of the issuer name and the diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 3c3a1ba76..786a97353 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -179,6 +179,7 @@ char *gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo); unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert); char *gpgsm_get_keygrip (ksba_cert_t cert, char *array); char *gpgsm_get_keygrip_hexstring (ksba_cert_t cert); +int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits); char *gpgsm_get_certid (ksba_cert_t cert); diff --git a/sm/keylist.c b/sm/keylist.c index 07cddb3dc..e9056b6da 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -296,6 +296,8 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, char *fpr; ksba_isotime_t t; gpg_error_t valerr; + int algo; + unsigned int nbits; if (ctrl->with_validation) valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0); @@ -330,10 +332,8 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, fputs (truststring, fp); fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); - fprintf (fp, ":%u:%d:%s:", - /*keylen_of_cert (cert)*/1024, - /* pubkey_algo_of_cert (cert)*/1, - fpr+24); + algo = gpgsm_get_key_algo_info (cert, &nbits); + fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24); /* We assume --fixed-list-mode for gpgsm */ ksba_cert_get_validity (cert, 0, t); @@ -547,6 +547,14 @@ list_cert_raw (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret, s = get_oid_desc (oid, NULL); fprintf (fp, " hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":""); + { + const char *algoname; + unsigned int nbits; + + algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits)); + fprintf (fp, " keyType: %u bit %s\n", nbits, algoname? algoname:"?"); + } + /* authorityKeyIdentifier */ fputs (" authKeyId: ", fp); err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp); @@ -829,6 +837,16 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret, gpgsm_print_time (fp, t); putc ('\n', fp); + + { + const char *algoname; + unsigned int nbits; + + algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits)); + fprintf (fp, " key type: %u bit %s\n", nbits, algoname? algoname:"?"); + } + + err = ksba_cert_get_key_usage (cert, &kusage); if (gpg_err_code (err) != GPG_ERR_NO_DATA) { diff --git a/sm/sign.c b/sm/sign.c index 9d34ab221..3340f1066 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -616,12 +616,15 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist, gcry_md_close (md); goto leave; } - rc = asprintf (&buf, "%c %d %d 00 %s %s", - detached? 'D':'S', - GCRY_PK_RSA, /* FIXME: get pk algo from cert */ - algo, - signed_at, - fpr); + { + int pkalgo = gpgsm_get_key_algo_info (cl->cert, NULL); + rc = asprintf (&buf, "%c %d %d 00 %s %s", + detached? 'D':'S', + pkalgo, + algo, + signed_at, + fpr); + } xfree (fpr); if (rc < 0) { @@ -651,7 +654,8 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist, leave: if (rc) - log_error ("error creating signature: %s\n", gpg_strerror (rc)); + log_error ("error creating signature: %s <%s>\n", + gpg_strerror (rc), gpg_strsource (rc) ); if (release_signerlist) gpgsm_release_certlist (signerlist); ksba_cms_release (cms);