mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
sm: Exclude rsaPSS from de-vs compliance mode.
* common/compliance.h (PK_ALGO_FLAG_RSAPSS): New. * common/compliance.c (gnupg_pk_is_compliant): Add arg alog_flags and test rsaPSS. Adjust all callers. * common/util.c (pubkey_algo_to_string): New. (gnupg_pk_is_allowed): Ditto. * sm/misc.c (gpgsm_ksba_cms_get_sig_val): New wrapper function. (gpgsm_get_hash_algo_from_sigval): New. * sm/certcheck.c (gpgsm_check_cms_signature): Change type of sigval arg. Add arg pkalgoflags. Use the PK_ALGO_FLAG_RSAPSS. * sm/verify.c (gpgsm_verify): Use the new wrapper and new fucntion to also get the algo flags. Pass algo flags along. Change some of the info output to be more like current master. -- Signed-off-by: Werner Koch <wk@gnupg.org> This backport from master commit 969abcf40cdfc65f3ee859c5e62889e1a8ccde91 also includes some changes taken from commit a759fa963a42e0652134130029217270b6d5d00b (sm: Improve readability of the data verification output.) Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
daca1a011b
commit
4a36adaa64
@ -96,6 +96,7 @@ gnupg_initialize_compliance (int gnupg_module_name)
|
|||||||
* both are compatible from the point of view of this function. */
|
* both are compatible from the point of view of this function. */
|
||||||
int
|
int
|
||||||
gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
|
gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
|
||||||
|
unsigned int algo_flags,
|
||||||
gcry_mpi_t key[], unsigned int keylength,
|
gcry_mpi_t key[], unsigned int keylength,
|
||||||
const char *curvename)
|
const char *curvename)
|
||||||
{
|
{
|
||||||
@ -148,6 +149,10 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
|
|||||||
result = (keylength == 2048
|
result = (keylength == 2048
|
||||||
|| keylength == 3072
|
|| keylength == 3072
|
||||||
|| keylength == 4096);
|
|| keylength == 4096);
|
||||||
|
/* rsaPSS was not part of the evaluation and thus we don't
|
||||||
|
* claim compliance. */
|
||||||
|
if ((algo_flags & PK_ALGO_FLAG_RSAPSS))
|
||||||
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case is_dsa:
|
case is_dsa:
|
||||||
@ -197,7 +202,8 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
|
|||||||
* they produce, and liberal in what they accept. */
|
* they produce, and liberal in what they accept. */
|
||||||
int
|
int
|
||||||
gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
||||||
enum pk_use_case use, int algo, gcry_mpi_t key[],
|
enum pk_use_case use, int algo,
|
||||||
|
unsigned int algo_flags, gcry_mpi_t key[],
|
||||||
unsigned int keylength, const char *curvename)
|
unsigned int keylength, const char *curvename)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -228,6 +234,10 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
|||||||
default:
|
default:
|
||||||
log_assert (!"reached");
|
log_assert (!"reached");
|
||||||
}
|
}
|
||||||
|
/* rsaPSS was not part of the evaluation and thus we don't
|
||||||
|
* claim compliance. */
|
||||||
|
if ((algo_flags & PK_ALGO_FLAG_RSAPSS))
|
||||||
|
result = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUBKEY_ALGO_DSA:
|
case PUBKEY_ALGO_DSA:
|
||||||
|
@ -48,11 +48,17 @@ enum pk_use_case
|
|||||||
PK_USE_SIGNING, PK_USE_VERIFICATION,
|
PK_USE_SIGNING, PK_USE_VERIFICATION,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Flags to distinguish public key algorithm variants. */
|
||||||
|
#define PK_ALGO_FLAG_RSAPSS 1 /* Use rsaPSS padding. */
|
||||||
|
|
||||||
|
|
||||||
int gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
|
int gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo,
|
||||||
|
unsigned int algo_flags,
|
||||||
gcry_mpi_t key[], unsigned int keylength,
|
gcry_mpi_t key[], unsigned int keylength,
|
||||||
const char *curvename);
|
const char *curvename);
|
||||||
int gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
int gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance,
|
||||||
enum pk_use_case use, int algo, gcry_mpi_t key[],
|
enum pk_use_case use, int algo,
|
||||||
|
unsigned int algo_flags, gcry_mpi_t key[],
|
||||||
unsigned int keylength, const char *curvename);
|
unsigned int keylength, const char *curvename);
|
||||||
int gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
|
int gnupg_cipher_is_compliant (enum gnupg_compliance_mode compliance,
|
||||||
cipher_algo_t cipher,
|
cipher_algo_t cipher,
|
||||||
|
@ -642,6 +642,23 @@ pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Map a pubkey algo id from gcrypt to a string. This is the same as
|
||||||
|
* gcry_pk_algo_name but makes sure that the ECC algo identifiers are
|
||||||
|
* not all mapped to "ECC". */
|
||||||
|
const char *
|
||||||
|
pubkey_algo_to_string (int algo)
|
||||||
|
{
|
||||||
|
if (algo == GCRY_PK_ECDSA)
|
||||||
|
return "ECDSA";
|
||||||
|
else if (algo == GCRY_PK_ECDH)
|
||||||
|
return "ECDH";
|
||||||
|
else if (algo == GCRY_PK_EDDSA)
|
||||||
|
return "EdDSA";
|
||||||
|
else
|
||||||
|
return gcry_pk_algo_name (algo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Map a hash algo id from gcrypt to a string. This is the same as
|
/* Map a hash algo id from gcrypt to a string. This is the same as
|
||||||
* gcry_md_algo_name but the returned string is lower case, as
|
* gcry_md_algo_name but the returned string is lower case, as
|
||||||
* expected by libksba and it avoids some overhead. */
|
* expected by libksba and it avoids some overhead. */
|
||||||
|
@ -221,6 +221,7 @@ int get_pk_algo_from_key (gcry_sexp_t key);
|
|||||||
int get_pk_algo_from_canon_sexp (const unsigned char *keydata,
|
int get_pk_algo_from_canon_sexp (const unsigned char *keydata,
|
||||||
size_t keydatalen);
|
size_t keydatalen);
|
||||||
char *pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid);
|
char *pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid);
|
||||||
|
const char *pubkey_algo_to_string (int algo);
|
||||||
const char *hash_algo_to_string (int algo);
|
const char *hash_algo_to_string (int algo);
|
||||||
|
|
||||||
/*-- convert.c --*/
|
/*-- convert.c --*/
|
||||||
|
@ -619,15 +619,15 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
|||||||
PKT_public_key *pk = pkr->pk;
|
PKT_public_key *pk = pkr->pk;
|
||||||
unsigned int nbits = nbits_from_pk (pk);
|
unsigned int nbits = nbits_from_pk (pk);
|
||||||
|
|
||||||
if (!gnupg_pk_is_compliant (opt.compliance,
|
if (!gnupg_pk_is_compliant (opt.compliance, pk->pubkey_algo, 0,
|
||||||
pk->pubkey_algo, pk->pkey, nbits, NULL))
|
pk->pkey, nbits, NULL))
|
||||||
log_info (_("WARNING: key %s is not suitable for encryption"
|
log_info (_("WARNING: key %s is not suitable for encryption"
|
||||||
" in %s mode\n"),
|
" in %s mode\n"),
|
||||||
keystr_from_pk (pk),
|
keystr_from_pk (pk),
|
||||||
gnupg_compliance_option_string (opt.compliance));
|
gnupg_compliance_option_string (opt.compliance));
|
||||||
|
|
||||||
if (compliant
|
if (compliant
|
||||||
&& !gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
|
&& !gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, 0, pk->pkey,
|
||||||
nbits, NULL))
|
nbits, NULL))
|
||||||
compliant = 0;
|
compliant = 0;
|
||||||
}
|
}
|
||||||
|
@ -1340,7 +1340,7 @@ print_compliance_flags (PKT_public_key *pk,
|
|||||||
es_fputs (gnupg_status_compliance_flag (CO_GNUPG), es_stdout);
|
es_fputs (gnupg_status_compliance_flag (CO_GNUPG), es_stdout);
|
||||||
any++;
|
any++;
|
||||||
}
|
}
|
||||||
if (gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
|
if (gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, 0, pk->pkey,
|
||||||
keylength, curvename))
|
keylength, curvename))
|
||||||
{
|
{
|
||||||
es_fprintf (es_stdout, any ? " %s" : "%s",
|
es_fprintf (es_stdout, any ? " %s" : "%s",
|
||||||
|
@ -739,8 +739,8 @@ proc_encrypted (CTX c, PACKET *pkt)
|
|||||||
memset (pk, 0, sizeof *pk);
|
memset (pk, 0, sizeof *pk);
|
||||||
pk->pubkey_algo = i->pubkey_algo;
|
pk->pubkey_algo = i->pubkey_algo;
|
||||||
if (get_pubkey (c->ctrl, pk, i->kid) != 0
|
if (get_pubkey (c->ctrl, pk, i->kid) != 0
|
||||||
|| ! gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
|
|| ! gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, 0,
|
||||||
nbits_from_pk (pk), NULL))
|
pk->pkey, nbits_from_pk (pk), NULL))
|
||||||
compliant = 0;
|
compliant = 0;
|
||||||
release_public_key_parts (pk);
|
release_public_key_parts (pk);
|
||||||
}
|
}
|
||||||
@ -2429,7 +2429,7 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
|
|
||||||
/* Print compliance warning for Good signatures. */
|
/* Print compliance warning for Good signatures. */
|
||||||
if (!rc && pk && !opt.quiet
|
if (!rc && pk && !opt.quiet
|
||||||
&& !gnupg_pk_is_compliant (opt.compliance, pk->pubkey_algo,
|
&& !gnupg_pk_is_compliant (opt.compliance, pk->pubkey_algo, 0,
|
||||||
pk->pkey, nbits_from_pk (pk), NULL))
|
pk->pkey, nbits_from_pk (pk), NULL))
|
||||||
{
|
{
|
||||||
log_info (_("WARNING: This key is not suitable for signing"
|
log_info (_("WARNING: This key is not suitable for signing"
|
||||||
@ -2513,7 +2513,7 @@ check_sig_and_print (CTX c, kbnode_t node)
|
|||||||
|
|
||||||
/* Compute compliance with CO_DE_VS. */
|
/* Compute compliance with CO_DE_VS. */
|
||||||
if (pk && is_status_enabled ()
|
if (pk && is_status_enabled ()
|
||||||
&& gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
|
&& gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, 0, pk->pkey,
|
||||||
nbits_from_pk (pk), NULL)
|
nbits_from_pk (pk), NULL)
|
||||||
&& gnupg_digest_is_compliant (CO_DE_VS, sig->digest_algo))
|
&& gnupg_digest_is_compliant (CO_DE_VS, sig->digest_algo))
|
||||||
write_status_strings (STATUS_VERIFICATION_COMPLIANCE_MODE,
|
write_status_strings (STATUS_VERIFICATION_COMPLIANCE_MODE,
|
||||||
|
@ -92,7 +92,7 @@ get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
|
|||||||
{
|
{
|
||||||
/* Check compliance. */
|
/* Check compliance. */
|
||||||
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
|
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
|
||||||
sk->pubkey_algo,
|
sk->pubkey_algo, 0,
|
||||||
sk->pkey, nbits_from_pk (sk), NULL))
|
sk->pkey, nbits_from_pk (sk), NULL))
|
||||||
{
|
{
|
||||||
log_info (_("key %s is not suitable for decryption"
|
log_info (_("key %s is not suitable for decryption"
|
||||||
@ -133,7 +133,7 @@ get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek)
|
|||||||
|
|
||||||
/* Check compliance. */
|
/* Check compliance. */
|
||||||
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
|
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
|
||||||
sk->pubkey_algo,
|
sk->pubkey_algo, 0,
|
||||||
sk->pkey, nbits_from_pk (sk), NULL))
|
sk->pkey, nbits_from_pk (sk), NULL))
|
||||||
{
|
{
|
||||||
log_info (_("key %s is not suitable for decryption"
|
log_info (_("key %s is not suitable for decryption"
|
||||||
|
@ -164,7 +164,7 @@ check_signature2 (ctrl_t ctrl,
|
|||||||
else if (get_pubkey_for_sig (ctrl, pk, sig, forced_pk))
|
else if (get_pubkey_for_sig (ctrl, pk, sig, forced_pk))
|
||||||
rc = gpg_error (GPG_ERR_NO_PUBKEY);
|
rc = gpg_error (GPG_ERR_NO_PUBKEY);
|
||||||
else if (!gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION,
|
else if (!gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION,
|
||||||
pk->pubkey_algo, pk->pkey,
|
pk->pubkey_algo, 0, pk->pkey,
|
||||||
nbits_from_pk (pk),
|
nbits_from_pk (pk),
|
||||||
NULL))
|
NULL))
|
||||||
{
|
{
|
||||||
|
@ -395,7 +395,8 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pksk->pubkey_algo,
|
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING,
|
||||||
|
pksk->pubkey_algo, 0,
|
||||||
pksk->pkey, nbits_from_pk (pksk), NULL))
|
pksk->pkey, nbits_from_pk (pksk), NULL))
|
||||||
{
|
{
|
||||||
log_error (_("key %s may not be used for signing in %s mode\n"),
|
log_error (_("key %s may not be used for signing in %s mode\n"),
|
||||||
|
@ -492,69 +492,40 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
|
gpgsm_check_cms_signature (ksba_cert_t cert, gcry_sexp_t s_sig,
|
||||||
gcry_md_hd_t md, int mdalgo, int *r_pkalgo)
|
gcry_md_hd_t md, int mdalgo,
|
||||||
|
unsigned int pkalgoflags, int *r_pkalgo)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
ksba_sexp_t p;
|
ksba_sexp_t p;
|
||||||
gcry_sexp_t s_sig, s_hash, s_pkey, l1;
|
gcry_sexp_t s_hash, s_pkey;
|
||||||
size_t n;
|
size_t n;
|
||||||
const char *s;
|
|
||||||
int i;
|
|
||||||
int pkalgo;
|
int pkalgo;
|
||||||
int use_pss;
|
int use_pss;
|
||||||
unsigned int saltlen = 0;
|
unsigned int saltlen = 0;
|
||||||
|
|
||||||
|
|
||||||
if (r_pkalgo)
|
if (r_pkalgo)
|
||||||
*r_pkalgo = 0;
|
*r_pkalgo = 0;
|
||||||
|
|
||||||
n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
|
/* Check whether rsaPSS is needed. This information is indicated in
|
||||||
if (!n)
|
* the SIG-VAL and already provided to us by the caller so that we
|
||||||
|
* do not need to parse this out. */
|
||||||
|
use_pss = !!(pkalgoflags & PK_ALGO_FLAG_RSAPSS);
|
||||||
|
if (use_pss)
|
||||||
{
|
{
|
||||||
log_error ("libksba did not return a proper S-Exp\n");
|
int algo;
|
||||||
return gpg_error (GPG_ERR_BUG);
|
|
||||||
}
|
|
||||||
rc = gcry_sexp_sscan (&s_sig, NULL, (char*)sigval, n);
|
|
||||||
if (rc)
|
|
||||||
{
|
|
||||||
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether rsaPSS is needed. This is indicated in the SIG-VAL
|
rc = extract_pss_params (s_sig, &algo, &saltlen);
|
||||||
* using a flag. Only if we found that flag, we extract the PSS
|
if (rc)
|
||||||
* 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;
|
gcry_sexp_release (s_sig);
|
||||||
|
return rc;
|
||||||
rc = extract_pss_params (s_sig, &algo, &saltlen);
|
}
|
||||||
if (rc)
|
if (algo != mdalgo)
|
||||||
{
|
{
|
||||||
gcry_sexp_release (s_sig);
|
log_error ("PSS hash algo mismatch (%d/%d)\n", mdalgo, algo);
|
||||||
return rc;
|
gcry_sexp_release (s_sig);
|
||||||
}
|
return gpg_error (GPG_ERR_DIGEST_ALGO);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,7 +535,6 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
|
|||||||
{
|
{
|
||||||
log_error ("libksba did not return a proper S-Exp\n");
|
log_error ("libksba did not return a proper S-Exp\n");
|
||||||
ksba_free (p);
|
ksba_free (p);
|
||||||
gcry_sexp_release (s_sig);
|
|
||||||
return gpg_error (GPG_ERR_BUG);
|
return gpg_error (GPG_ERR_BUG);
|
||||||
}
|
}
|
||||||
if (DBG_CRYPTO)
|
if (DBG_CRYPTO)
|
||||||
@ -575,7 +545,6 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
|
|||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
|
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
|
||||||
gcry_sexp_release (s_sig);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,7 +574,6 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
|
|||||||
gcry_pk_get_nbits (s_pkey), s_pkey, &frame);
|
gcry_pk_get_nbits (s_pkey), s_pkey, &frame);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
gcry_sexp_release (s_sig);
|
|
||||||
gcry_sexp_release (s_pkey);
|
gcry_sexp_release (s_pkey);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -618,7 +586,6 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
|
|||||||
rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
|
rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
|
||||||
if (DBG_X509)
|
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_hash);
|
||||||
gcry_sexp_release (s_pkey);
|
gcry_sexp_release (s_pkey);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -483,7 +483,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
|
|||||||
/* Check compliance. */
|
/* Check compliance. */
|
||||||
if (!gnupg_pk_is_allowed (opt.compliance,
|
if (!gnupg_pk_is_allowed (opt.compliance,
|
||||||
PK_USE_DECRYPTION,
|
PK_USE_DECRYPTION,
|
||||||
pk_algo, NULL, nbits, NULL))
|
pk_algo, 0, NULL, nbits, NULL))
|
||||||
{
|
{
|
||||||
char kidstr[10+1];
|
char kidstr[10+1];
|
||||||
|
|
||||||
@ -501,7 +501,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
|
|||||||
/* Check that all certs are compliant with CO_DE_VS. */
|
/* Check that all certs are compliant with CO_DE_VS. */
|
||||||
is_de_vs =
|
is_de_vs =
|
||||||
(is_de_vs
|
(is_de_vs
|
||||||
&& gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL,
|
&& gnupg_pk_is_compliant (CO_DE_VS, pk_algo, 0, NULL,
|
||||||
nbits, NULL));
|
nbits, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +480,8 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
|
|||||||
|
|
||||||
/* Check compliance. */
|
/* Check compliance. */
|
||||||
pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
|
pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
|
||||||
if (!gnupg_pk_is_compliant (opt.compliance, pk_algo, NULL, nbits, NULL))
|
if (!gnupg_pk_is_compliant (opt.compliance, pk_algo, 0,
|
||||||
|
NULL, nbits, NULL))
|
||||||
{
|
{
|
||||||
char kidstr[10+1];
|
char kidstr[10+1];
|
||||||
|
|
||||||
@ -495,7 +496,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
|
|||||||
/* Fixme: When adding ECC we need to provide the curvename and
|
/* Fixme: When adding ECC we need to provide the curvename and
|
||||||
* the key to gnupg_pk_is_compliant. */
|
* the key to gnupg_pk_is_compliant. */
|
||||||
if (compliant
|
if (compliant
|
||||||
&& !gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL, nbits, NULL))
|
&& !gnupg_pk_is_compliant (CO_DE_VS, pk_algo, 0, NULL, nbits, NULL))
|
||||||
compliant = 0;
|
compliant = 0;
|
||||||
|
|
||||||
rc = encrypt_dek (dek, cl->cert, &encval);
|
rc = encrypt_dek (dek, cl->cert, &encval);
|
||||||
|
@ -277,6 +277,41 @@ gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is a wrapper around pubkey_algo_string which takes a KSBA
|
||||||
|
* certificate 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* For certain purposes we need a certificate id which has an upper
|
/* For certain purposes we need a certificate id which has an upper
|
||||||
|
10
sm/gpgsm.h
10
sm/gpgsm.h
@ -264,6 +264,7 @@ unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert,
|
|||||||
unsigned char *gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array);
|
unsigned char *gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array);
|
||||||
char *gpgsm_get_keygrip_hexstring (ksba_cert_t cert);
|
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_info (ksba_cert_t cert, unsigned int *nbits);
|
||||||
|
char *gpgsm_pubkey_algo_string (ksba_cert_t cert, int *r_algoid);
|
||||||
char *gpgsm_get_certid (ksba_cert_t cert);
|
char *gpgsm_get_certid (ksba_cert_t cert);
|
||||||
|
|
||||||
|
|
||||||
@ -295,8 +296,10 @@ char *gpgsm_format_keydesc (ksba_cert_t cert);
|
|||||||
|
|
||||||
/*-- certcheck.c --*/
|
/*-- certcheck.c --*/
|
||||||
int gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert);
|
int gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert);
|
||||||
int gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval,
|
int gpgsm_check_cms_signature (ksba_cert_t cert, gcry_sexp_t sigval,
|
||||||
gcry_md_hd_t md, int hash_algo, int *r_pkalgo);
|
gcry_md_hd_t md,
|
||||||
|
int hash_algo, unsigned int pkalgoflags,
|
||||||
|
int *r_pkalgo);
|
||||||
/* fixme: move create functions to another file */
|
/* fixme: move create functions to another file */
|
||||||
int gpgsm_create_cms_signature (ctrl_t ctrl,
|
int gpgsm_create_cms_signature (ctrl_t ctrl,
|
||||||
ksba_cert_t cert, gcry_md_hd_t md, int mdalgo,
|
ksba_cert_t cert, gcry_md_hd_t md, int mdalgo,
|
||||||
@ -438,6 +441,9 @@ gpg_error_t transform_sigval (const unsigned char *sigval, size_t sigvallen,
|
|||||||
int mdalgo,
|
int mdalgo,
|
||||||
unsigned char **r_newsigval,
|
unsigned char **r_newsigval,
|
||||||
size_t *r_newsigvallen);
|
size_t *r_newsigvallen);
|
||||||
|
gcry_sexp_t gpgsm_ksba_cms_get_sig_val (ksba_cms_t cms, int idx);
|
||||||
|
int gpgsm_get_hash_algo_from_sigval (gcry_sexp_t sigval,
|
||||||
|
unsigned int *r_pkalgo_flags);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -361,7 +361,10 @@ print_compliance_flags (ksba_cert_t cert, int algo, unsigned int nbits,
|
|||||||
{
|
{
|
||||||
int hashalgo;
|
int hashalgo;
|
||||||
|
|
||||||
if (gnupg_pk_is_compliant (CO_DE_VS, algo, NULL, nbits, NULL))
|
/* Note that we do not need to test for PK_ALGO_FLAG_RSAPSS because
|
||||||
|
* that is not a property of the key but one of the created
|
||||||
|
* signature. */
|
||||||
|
if (gnupg_pk_is_compliant (CO_DE_VS, algo, 0, NULL, nbits, NULL))
|
||||||
{
|
{
|
||||||
hashalgo = gcry_md_map_name (ksba_cert_get_digest_algo (cert));
|
hashalgo = gcry_md_map_name (ksba_cert_get_digest_algo (cert));
|
||||||
if (gnupg_digest_is_compliant (CO_DE_VS, hashalgo))
|
if (gnupg_digest_is_compliant (CO_DE_VS, hashalgo))
|
||||||
|
90
sm/misc.c
90
sm/misc.c
@ -216,3 +216,93 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
|
|||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Wrapper around ksba_cms_get_sig_val to return a gcrypt object
|
||||||
|
* instaed of ksba's canonical s-expression. On errror NULL is return
|
||||||
|
* and in some cases an error message is printed. */
|
||||||
|
gcry_sexp_t
|
||||||
|
gpgsm_ksba_cms_get_sig_val (ksba_cms_t cms, int idx)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
ksba_sexp_t sigval;
|
||||||
|
gcry_sexp_t s_sigval;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
sigval = ksba_cms_get_sig_val (cms, idx);
|
||||||
|
if (!sigval)
|
||||||
|
return NULL;
|
||||||
|
n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
|
||||||
|
if (!n)
|
||||||
|
{
|
||||||
|
log_error ("%s: libksba did not return a proper S-Exp\n", __func__);
|
||||||
|
ksba_free (sigval);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
err = gcry_sexp_sscan (&s_sigval, NULL, (char*)sigval, n);
|
||||||
|
ksba_free (sigval);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("%s: gcry_sexp_scan failed: %s\n",
|
||||||
|
__func__, gpg_strerror (err));
|
||||||
|
s_sigval = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_sigval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the hash algorithm from the S-expression SIGVAL. Returns 0
|
||||||
|
* if the hash algorithm is not encoded in SIGVAL or it is not
|
||||||
|
* supported by libgcrypt. It further stores flag values for the
|
||||||
|
* public key algorithm at R_PKALGO_FLAGS; the only flag we currently
|
||||||
|
* support is PK_ALGO_FLAG_RSAPSS. */
|
||||||
|
int
|
||||||
|
gpgsm_get_hash_algo_from_sigval (gcry_sexp_t sigval_arg,
|
||||||
|
unsigned int *r_pkalgo_flags)
|
||||||
|
{
|
||||||
|
gcry_sexp_t sigval, l1;
|
||||||
|
size_t n;
|
||||||
|
const char *s;
|
||||||
|
char *string;
|
||||||
|
int hashalgo;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*r_pkalgo_flags = 0;
|
||||||
|
|
||||||
|
sigval = gcry_sexp_find_token (sigval_arg, "sig-val", 0);
|
||||||
|
if (!sigval)
|
||||||
|
return 0; /* Not a sig-val. */
|
||||||
|
|
||||||
|
/* First check whether this is a rsaPSS signature and return that as
|
||||||
|
* additional info. */
|
||||||
|
l1 = gcry_sexp_find_token (sigval, "flags", 0);
|
||||||
|
if (l1)
|
||||||
|
{
|
||||||
|
/* Note that the flag parser assumes that the list of flags
|
||||||
|
* contains only strings and in particular not a sub-list. This
|
||||||
|
* is always the case for the current libksba. */
|
||||||
|
for (i=1; (s = gcry_sexp_nth_data (l1, i, &n)); i++)
|
||||||
|
if (n == 3 && !memcmp (s, "pss", 3))
|
||||||
|
{
|
||||||
|
*r_pkalgo_flags |= PK_ALGO_FLAG_RSAPSS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gcry_sexp_release (l1);
|
||||||
|
}
|
||||||
|
|
||||||
|
l1 = gcry_sexp_find_token (sigval, "hash", 0);
|
||||||
|
if (!l1)
|
||||||
|
{
|
||||||
|
gcry_sexp_release (sigval);
|
||||||
|
return 0; /* hash algorithm not given in sigval. */
|
||||||
|
}
|
||||||
|
string = gcry_sexp_nth_string (l1, 1);
|
||||||
|
gcry_sexp_release (sigval);
|
||||||
|
if (!string)
|
||||||
|
return 0; /* hash algorithm has no value. */
|
||||||
|
hashalgo = gcry_md_map_name (string);
|
||||||
|
gcry_free (string);
|
||||||
|
|
||||||
|
return hashalgo;
|
||||||
|
}
|
||||||
|
@ -486,7 +486,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
|||||||
unsigned int nbits;
|
unsigned int nbits;
|
||||||
int pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
|
int pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
|
||||||
|
|
||||||
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo,
|
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo, 0,
|
||||||
NULL, nbits, NULL))
|
NULL, nbits, NULL))
|
||||||
{
|
{
|
||||||
char kidstr[10+1];
|
char kidstr[10+1];
|
||||||
|
121
sm/verify.c
121
sm/verify.c
@ -1,6 +1,8 @@
|
|||||||
/* verify.c - Verify a messages signature
|
/* verify.c - Verify a messages signature
|
||||||
* Copyright (C) 2001, 2002, 2003, 2007,
|
* Copyright (C) 2001, 2002, 2003, 2007,
|
||||||
* 2010 Free Software Foundation, Inc.
|
* 2010 Free Software Foundation, Inc.
|
||||||
|
* Copyright (C) 2001-2019 Werner Koch
|
||||||
|
* Copyright (C) 2015-2020 g10 Code GmbH
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -16,6 +18,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@ -286,7 +289,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
|
|||||||
for (signer=0; ; signer++)
|
for (signer=0; ; signer++)
|
||||||
{
|
{
|
||||||
char *issuer = NULL;
|
char *issuer = NULL;
|
||||||
ksba_sexp_t sigval = NULL;
|
gcry_sexp_t sigval = NULL;
|
||||||
ksba_isotime_t sigtime, keyexptime;
|
ksba_isotime_t sigtime, keyexptime;
|
||||||
ksba_sexp_t serial;
|
ksba_sexp_t serial;
|
||||||
char *msgdigest = NULL;
|
char *msgdigest = NULL;
|
||||||
@ -294,7 +297,11 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
|
|||||||
char *ctattr;
|
char *ctattr;
|
||||||
int sigval_hash_algo;
|
int sigval_hash_algo;
|
||||||
int info_pkalgo;
|
int info_pkalgo;
|
||||||
unsigned int verifyflags;
|
unsigned int nbits;
|
||||||
|
int pkalgo;
|
||||||
|
char *pkalgostr = NULL;
|
||||||
|
char *pkfpr = NULL;
|
||||||
|
unsigned int pkalgoflags, verifyflags;
|
||||||
|
|
||||||
rc = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial);
|
rc = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial);
|
||||||
if (!signer && gpg_err_code (rc) == GPG_ERR_NO_DATA
|
if (!signer && gpg_err_code (rc) == GPG_ERR_NO_DATA
|
||||||
@ -400,20 +407,19 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
|
|||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
|
|
||||||
sigval = ksba_cms_get_sig_val (cms, signer);
|
sigval = gpgsm_ksba_cms_get_sig_val (cms, signer);
|
||||||
if (!sigval)
|
if (!sigval)
|
||||||
{
|
{
|
||||||
log_error ("no signature value available\n");
|
log_error ("no signature value available\n");
|
||||||
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
|
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
|
||||||
goto next_signer;
|
goto next_signer;
|
||||||
}
|
}
|
||||||
sigval_hash_algo = hash_algo_from_sigval (sigval);
|
|
||||||
|
sigval_hash_algo = gpgsm_get_hash_algo_from_sigval (sigval, &pkalgoflags);
|
||||||
if (DBG_X509)
|
if (DBG_X509)
|
||||||
{
|
{
|
||||||
log_debug ("signer %d - signature available (sigval hash=%d)",
|
log_debug ("signer %d - signature available (sigval hash=%d pkaf=%u)",
|
||||||
signer, sigval_hash_algo);
|
signer, sigval_hash_algo, pkalgoflags);
|
||||||
/*log_printhex(sigval, gcry_sexp_canon_len (sigval, 0, NULL, NULL),*/
|
|
||||||
/* "sigval "); */
|
|
||||||
}
|
}
|
||||||
if (!sigval_hash_algo)
|
if (!sigval_hash_algo)
|
||||||
sigval_hash_algo = algo; /* Fallback used e.g. with old libksba. */
|
sigval_hash_algo = algo; /* Fallback used e.g. with old libksba. */
|
||||||
@ -450,49 +456,68 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
|
|||||||
goto next_signer;
|
goto next_signer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check compliance. */
|
pkfpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
|
||||||
{
|
pkalgostr = gpgsm_pubkey_algo_string (cert, NULL);
|
||||||
unsigned int nbits;
|
pkalgo = gpgsm_get_key_algo_info (cert, &nbits);
|
||||||
int pk_algo = gpgsm_get_key_algo_info (cert, &nbits);
|
|
||||||
|
|
||||||
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION,
|
|
||||||
pk_algo, NULL, nbits, NULL))
|
|
||||||
{
|
|
||||||
char kidstr[10+1];
|
|
||||||
|
|
||||||
snprintf (kidstr, sizeof kidstr, "0x%08lX",
|
|
||||||
gpgsm_get_short_fingerprint (cert, NULL));
|
|
||||||
log_error (_("key %s may not be used for signing in %s mode\n"),
|
|
||||||
kidstr,
|
|
||||||
gnupg_compliance_option_string (opt.compliance));
|
|
||||||
goto next_signer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! gnupg_digest_is_allowed (opt.compliance, 0, sigval_hash_algo))
|
|
||||||
{
|
|
||||||
log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
|
|
||||||
gcry_md_algo_name (sigval_hash_algo),
|
|
||||||
gnupg_compliance_option_string (opt.compliance));
|
|
||||||
goto next_signer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check compliance with CO_DE_VS. */
|
|
||||||
if (gnupg_pk_is_compliant (CO_DE_VS, pk_algo, NULL, nbits, NULL)
|
|
||||||
&& gnupg_digest_is_compliant (CO_DE_VS, sigval_hash_algo))
|
|
||||||
gpgsm_status (ctrl, STATUS_VERIFICATION_COMPLIANCE_MODE,
|
|
||||||
gnupg_status_compliance_flag (CO_DE_VS));
|
|
||||||
}
|
|
||||||
|
|
||||||
log_info (_("Signature made "));
|
log_info (_("Signature made "));
|
||||||
if (*sigtime)
|
if (*sigtime)
|
||||||
dump_isotime (sigtime);
|
{
|
||||||
|
/* We take the freedom as noted in RFC3339 to use a space
|
||||||
|
* instead of the "T" delimiter between date and time. We
|
||||||
|
* also append a separate UTC instead of a "Z" or "+00:00"
|
||||||
|
* suffix because that makes it clear to everyone what kind
|
||||||
|
* of time this is. */
|
||||||
|
dump_isotime (sigtime);
|
||||||
|
log_printf (" UTC");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
log_printf (_("[date not given]"));
|
log_printf (_("[date not given]"));
|
||||||
log_printf (_(" using certificate ID 0x%08lX\n"),
|
log_info (_(" using %s key %s\n"), pkalgostr, pkfpr);
|
||||||
gpgsm_get_short_fingerprint (cert, NULL));
|
if (opt.verbose)
|
||||||
|
{
|
||||||
|
log_info (_("algorithm:"));
|
||||||
|
log_printf (" %s + %s",
|
||||||
|
pubkey_algo_to_string (pkalgo),
|
||||||
|
gcry_md_algo_name (sigval_hash_algo));
|
||||||
|
if (algo != sigval_hash_algo)
|
||||||
|
log_printf (" (%s)", gcry_md_algo_name (algo));
|
||||||
|
log_printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
|
audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
|
||||||
|
|
||||||
|
/* Check compliance. */
|
||||||
|
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION,
|
||||||
|
pkalgo, pkalgoflags, NULL, nbits, NULL))
|
||||||
|
{
|
||||||
|
char kidstr[10+1];
|
||||||
|
|
||||||
|
snprintf (kidstr, sizeof kidstr, "0x%08lX",
|
||||||
|
gpgsm_get_short_fingerprint (cert, NULL));
|
||||||
|
log_error (_("key %s may not be used for signing in %s mode\n"),
|
||||||
|
kidstr,
|
||||||
|
gnupg_compliance_option_string (opt.compliance));
|
||||||
|
goto next_signer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gnupg_digest_is_allowed (opt.compliance, 0, sigval_hash_algo))
|
||||||
|
{
|
||||||
|
log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
|
||||||
|
gcry_md_algo_name (sigval_hash_algo),
|
||||||
|
gnupg_compliance_option_string (opt.compliance));
|
||||||
|
goto next_signer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check compliance with CO_DE_VS. */
|
||||||
|
if (gnupg_pk_is_compliant (CO_DE_VS, pkalgo, pkalgoflags,
|
||||||
|
NULL, nbits, NULL)
|
||||||
|
&& gnupg_digest_is_compliant (CO_DE_VS, sigval_hash_algo))
|
||||||
|
gpgsm_status (ctrl, STATUS_VERIFICATION_COMPLIANCE_MODE,
|
||||||
|
gnupg_status_compliance_flag (CO_DE_VS));
|
||||||
|
|
||||||
|
|
||||||
|
/* Now we can check the signature. */
|
||||||
if (msgdigest)
|
if (msgdigest)
|
||||||
{ /* Signed attributes are available. */
|
{ /* Signed attributes are available. */
|
||||||
gcry_md_hd_t md;
|
gcry_md_hd_t md;
|
||||||
@ -545,14 +570,14 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
|
|||||||
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
|
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
|
||||||
goto next_signer;
|
goto next_signer;
|
||||||
}
|
}
|
||||||
rc = gpgsm_check_cms_signature (cert, sigval, md,
|
rc = gpgsm_check_cms_signature (cert, sigval, md, sigval_hash_algo,
|
||||||
sigval_hash_algo, &info_pkalgo);
|
pkalgoflags, &info_pkalgo);
|
||||||
gcry_md_close (md);
|
gcry_md_close (md);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc = gpgsm_check_cms_signature (cert, sigval, data_md,
|
rc = gpgsm_check_cms_signature (cert, sigval, data_md,
|
||||||
algo, &info_pkalgo);
|
algo, pkalgoflags, &info_pkalgo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -669,8 +694,10 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp)
|
|||||||
rc = 0;
|
rc = 0;
|
||||||
xfree (issuer);
|
xfree (issuer);
|
||||||
xfree (serial);
|
xfree (serial);
|
||||||
xfree (sigval);
|
gcry_sexp_release (sigval);
|
||||||
xfree (msgdigest);
|
xfree (msgdigest);
|
||||||
|
xfree (pkalgostr);
|
||||||
|
xfree (pkfpr);
|
||||||
ksba_cert_release (cert);
|
ksba_cert_release (cert);
|
||||||
cert = NULL;
|
cert = NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user