aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dirmngr/ocsp.c2
-rw-r--r--sm/certcheck.c148
-rw-r--r--sm/verify.c4
3 files changed, 113 insertions, 41 deletions
diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
index 0b846651c..6ed180955 100644
--- a/dirmngr/ocsp.c
+++ b/dirmngr/ocsp.c
@@ -305,7 +305,7 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp,
if (opt.verbose)
log_info (_("OCSP responder at '%s' status: %s\n"), url, t);
- /* Get the signature value now because we can all this function
+ /* Get the signature value now because we can call this function
* only once. */
*r_sigval = ksba_ocsp_get_sig_val (ocsp, r_produced_at);
diff --git a/sm/certcheck.c b/sm/certcheck.c
index effab9ab9..68185332e 100644
--- a/sm/certcheck.c
+++ b/sm/certcheck.c
@@ -270,6 +270,41 @@ uint_from_buffer (const void *buffer, size_t buflen)
}
+/* Extract the hash algorithm and the salt length from the sigval. */
+static gpg_error_t
+extract_pss_params (gcry_sexp_t s_sig, int *r_algo, unsigned int *r_saltlen)
+{
+ gpg_error_t err;
+ gcry_buffer_t ioarray[2] = { {0}, {0} };
+
+ err = gcry_sexp_extract_param (s_sig, "sig-val",
+ "&'hash-algo''salt-length'",
+ ioarray+0, ioarray+1, NULL);
+ if (err)
+ {
+ log_error ("extracting params from PSS failed: %s\n", gpg_strerror (err));
+ return err;
+ }
+
+ *r_algo = hash_algo_from_buffer (ioarray[0].data, ioarray[0].len);
+ *r_saltlen = uint_from_buffer (ioarray[1].data, ioarray[1].len);
+ xfree (ioarray[0].data);
+ xfree (ioarray[1].data);
+ if (*r_saltlen < 20)
+ {
+ log_error ("length of PSS salt too short\n");
+ gcry_sexp_release (s_sig);
+ return gpg_error (GPG_ERR_DIGEST_ALGO);
+ }
+ if (!*r_algo)
+ {
+ return gpg_error (GPG_ERR_DIGEST_ALGO);
+ }
+ /* log_debug ("PSS hash=%d saltlen=%u\n", *r_algo, *r_saltlen); */
+ return 0;
+}
+
+
/* Check the signature on CERT using the ISSUER-CERT. This function
does only test the cryptographic signature and nothing else. It is
assumed that the ISSUER_CERT is valid. */
@@ -320,35 +355,12 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
if (use_pss)
{
- /* Extract the hash algorithm and the salt length from the sigval. */
- gcry_buffer_t ioarray[2] = { {0}, {0} };
-
- rc = gcry_sexp_extract_param (s_sig, "sig-val",
- "&'hash-algo''salt-length'",
- ioarray+0, ioarray+1, NULL);
+ rc = extract_pss_params (s_sig, &algo, &saltlen);
if (rc)
{
gcry_sexp_release (s_sig);
- log_error ("extracting params from PSS failed: %s\n",
- gpg_strerror (rc));
return rc;
}
- algo = hash_algo_from_buffer (ioarray[0].data, ioarray[0].len);
- saltlen = uint_from_buffer (ioarray[1].data, ioarray[1].len);
- xfree (ioarray[0].data);
- xfree (ioarray[1].data);
- if (saltlen < 20)
- {
- log_error ("length of PSS salt too short\n");
- gcry_sexp_release (s_sig);
- return gpg_error (GPG_ERR_DIGEST_ALGO);
- }
- if (!algo)
- {
- gcry_sexp_release (s_sig);
- return gpg_error (GPG_ERR_DIGEST_ALGO);
- }
- /* log_debug ("PSS hash=%d saltlen=%u\n", algo, saltlen); */
}
@@ -409,7 +421,7 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
}
else
{
- /* RSA or DAS: Prepare the hash for verification. */
+ /* RSA or DSA: Prepare the hash for verification. */
gcry_mpi_t frame;
rc = do_encode_md (md, algo, pk_algo_from_sexp (s_pkey),
@@ -447,10 +459,14 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
{
int rc;
ksba_sexp_t p;
- gcry_mpi_t frame;
- gcry_sexp_t s_sig, s_hash, s_pkey;
+ gcry_sexp_t s_sig, s_hash, s_pkey, l1;
size_t n;
+ const char *s;
+ int i;
int pkalgo;
+ int use_pss;
+ unsigned int saltlen = 0;
+
if (r_pkalgo)
*r_pkalgo = 0;
@@ -468,6 +484,42 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
return rc;
}
+ /* Check whether rsaPSS is needed. This is indicated in the SIG-VAL
+ * using a flag. Only if we found that flag, we extract the PSS
+ * parameters for SIG-VAL. */
+ use_pss = 0;
+ l1 = gcry_sexp_find_token (s_sig, "flags", 0);
+ if (l1)
+ {
+ /* Note that the flag parser assumes that the list of flags
+ * contains only strings and in particular not sublist. This is
+ * always the case or current libksba. */
+ for (i=1; (s = gcry_sexp_nth_data (l1, i, &n)); i++)
+ if (n == 3 && !memcmp (s, "pss", 3))
+ {
+ use_pss = 1;
+ break;
+ }
+ gcry_sexp_release (l1);
+ if (use_pss)
+ {
+ int algo;
+
+ rc = extract_pss_params (s_sig, &algo, &saltlen);
+ if (rc)
+ {
+ gcry_sexp_release (s_sig);
+ return rc;
+ }
+ if (algo != mdalgo)
+ {
+ log_error ("PSS hash algo mismatch (%d/%d)\n", mdalgo, algo);
+ gcry_sexp_release (s_sig);
+ return gpg_error (GPG_ERR_DIGEST_ALGO);
+ }
+ }
+ }
+
p = ksba_cert_get_public_key (cert);
n = gcry_sexp_canon_len (p, 0, NULL, NULL);
if (!n)
@@ -492,22 +544,42 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
pkalgo = pk_algo_from_sexp (s_pkey);
if (r_pkalgo)
*r_pkalgo = pkalgo;
- rc = do_encode_md (md, mdalgo, pkalgo,
- gcry_pk_get_nbits (s_pkey), s_pkey, &frame);
- if (rc)
+
+ if (use_pss)
{
- gcry_sexp_release (s_sig);
- gcry_sexp_release (s_pkey);
- return rc;
+ rc = gcry_sexp_build (&s_hash, NULL,
+ "(data (flags pss)"
+ "(hash %s %b)"
+ "(salt-length %u))",
+ hash_algo_to_string (mdalgo),
+ (int)gcry_md_get_algo_dlen (mdalgo),
+ gcry_md_read (md, mdalgo),
+ saltlen);
+ if (rc)
+ BUG ();
+ }
+ else
+ {
+ /* RSA or DSA: Prepare the hash for verification. */
+ gcry_mpi_t frame;
+
+ rc = do_encode_md (md, mdalgo, pkalgo,
+ gcry_pk_get_nbits (s_pkey), s_pkey, &frame);
+ if (rc)
+ {
+ gcry_sexp_release (s_sig);
+ gcry_sexp_release (s_pkey);
+ return rc;
+ }
+ /* put hash into the S-Exp s_hash */
+ if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) )
+ BUG ();
+ gcry_mpi_release (frame);
}
- /* put hash into the S-Exp s_hash */
- if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) )
- BUG ();
- gcry_mpi_release (frame);
rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
if (DBG_X509)
- log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
+ log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc));
gcry_sexp_release (s_sig);
gcry_sexp_release (s_hash);
gcry_sexp_release (s_pkey);
diff --git a/sm/verify.c b/sm/verify.c
index b7b9fa8be..6d2f11055 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -412,8 +412,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
{
log_debug ("signer %d - signature available (sigval hash=%d)",
signer, sigval_hash_algo);
-/* log_printhex ("sigval ", sigval, */
-/* gcry_sexp_canon_len (sigval, 0, NULL, NULL)); */
+ /*log_printhex(sigval, gcry_sexp_canon_len (sigval, 0, NULL, NULL),*/
+ /* "sigval "); */
}
if (!sigval_hash_algo)
sigval_hash_algo = algo; /* Fallback used e.g. with old libksba. */