mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
gpg: Add new field no 18 to the colon listing.
* g10/misc.c (gnupg_pk_is_compliant): New. * g10/keylist.c (print_compliance_flags): New. (list_keyblock_colon): Call it here. * sm/keylist.c (print_compliance_flags): New. (list_cert_colon): Call it here. -- This patch is to convey information about DE_VS compliant keys to the caller. The double digit value is used so that parsers do the right thing and don't just look for a single digit. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
e2c63a13e2
commit
fe0b37e123
@ -218,6 +218,15 @@ described here.
|
||||
For pub, sub, sec, and ssb records this field is used for the ECC
|
||||
curve name.
|
||||
|
||||
*** Field 18 - Compliance flags
|
||||
|
||||
Space separated list of asserted compliance modes for this key.
|
||||
|
||||
Valid values are:
|
||||
|
||||
- 8 :: The key is compliant with RFC4880bis
|
||||
- 23 :: The key is compliant with compliance mode "de-vs".
|
||||
|
||||
** Special fields
|
||||
|
||||
*** PKD - Public key data
|
||||
|
@ -1170,6 +1170,29 @@ print_revokers (estream_t fp, PKT_public_key * pk)
|
||||
}
|
||||
|
||||
|
||||
/* Print the compliance flags to field 18. PK is the public key.
|
||||
* KEYLENGTH is the length of the key in bits and CURVENAME is either
|
||||
* NULL or the name of the curve. The latter two args are here
|
||||
* merely because the caller has already computed them. */
|
||||
static void
|
||||
print_compliance_flags (PKT_public_key *pk,
|
||||
unsigned int keylength, const char *curvename)
|
||||
{
|
||||
int any = 0;
|
||||
|
||||
if (pk->version == 5)
|
||||
{
|
||||
es_fputs ("8", es_stdout);
|
||||
any++;
|
||||
}
|
||||
if (gnupg_pk_is_compliant (CO_DE_VS, pk, keylength, curvename))
|
||||
{
|
||||
es_fputs (any? " 23":"23", es_stdout);
|
||||
any++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* List a key in colon mode. If SECRET is true this is a secret key
|
||||
record (i.e. requested via --list-secret-key). If HAS_SECRET a
|
||||
secret key is available even if SECRET is not set. */
|
||||
@ -1191,6 +1214,9 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
|
||||
const char *hexgrip = NULL;
|
||||
char *serialno = NULL;
|
||||
int stubkey;
|
||||
unsigned int keylength;
|
||||
char *curve = NULL;
|
||||
const char *curvename = NULL;
|
||||
|
||||
/* Get the keyid from the keyblock. */
|
||||
node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
|
||||
@ -1239,14 +1265,16 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
|
||||
else
|
||||
ownertrust_print = 0;
|
||||
|
||||
keylength = nbits_from_pk (pk);
|
||||
|
||||
es_fputs (secret? "sec:":"pub:", es_stdout);
|
||||
if (trustletter_print)
|
||||
es_putc (trustletter_print, es_stdout);
|
||||
es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
|
||||
nbits_from_pk (pk),
|
||||
pk->pubkey_algo,
|
||||
(ulong) keyid[0], (ulong) keyid[1],
|
||||
colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
|
||||
keylength,
|
||||
pk->pubkey_algo,
|
||||
(ulong) keyid[0], (ulong) keyid[1],
|
||||
colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
|
||||
|
||||
if (ownertrust_print)
|
||||
es_putc (ownertrust_print, es_stdout);
|
||||
@ -1272,14 +1300,14 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|
||||
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH)
|
||||
{
|
||||
char *curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
const char *name = openpgp_oid_to_curve (curve, 0);
|
||||
if (!name)
|
||||
name = curve;
|
||||
es_fputs (name, es_stdout);
|
||||
xfree (curve);
|
||||
curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
curvename = openpgp_oid_to_curve (curve, 0);
|
||||
if (!curvename)
|
||||
curvename = curve;
|
||||
es_fputs (curvename, es_stdout);
|
||||
}
|
||||
es_putc (':', es_stdout); /* End of field 17. */
|
||||
print_compliance_flags (pk, keylength, curvename);
|
||||
es_putc (':', es_stdout); /* End of field 18. */
|
||||
es_putc ('\n', es_stdout);
|
||||
|
||||
@ -1380,13 +1408,13 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
|
||||
if (trustletter)
|
||||
es_fprintf (es_stdout, "%c", trustletter);
|
||||
}
|
||||
keylength = nbits_from_pk (pk2);
|
||||
es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
|
||||
nbits_from_pk (pk2),
|
||||
pk2->pubkey_algo,
|
||||
(ulong) keyid2[0], (ulong) keyid2[1],
|
||||
colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
|
||||
/* fixme: add LID and ownertrust here */
|
||||
);
|
||||
keylength,
|
||||
pk2->pubkey_algo,
|
||||
(ulong) keyid2[0], (ulong) keyid2[1],
|
||||
colon_datestr_from_pk (pk2),
|
||||
colon_strtime (pk2->expiredate));
|
||||
print_capabilities (pk2, NULL);
|
||||
es_putc (':', es_stdout); /* End of field 13. */
|
||||
es_putc (':', es_stdout); /* End of field 14. */
|
||||
@ -1405,14 +1433,16 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
|
||||
|| pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
|
||||
|| pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
|
||||
{
|
||||
char *curve = openpgp_oid_to_str (pk2->pkey[0]);
|
||||
const char *name = openpgp_oid_to_curve (curve, 0);
|
||||
if (!name)
|
||||
name = curve;
|
||||
es_fputs (name, es_stdout);
|
||||
xfree (curve);
|
||||
curve = openpgp_oid_to_str (pk2->pkey[0]);
|
||||
curvename = openpgp_oid_to_curve (curve, 0);
|
||||
if (!curvename)
|
||||
curvename = curve;
|
||||
es_fputs (curvename, es_stdout);
|
||||
}
|
||||
es_putc (':', es_stdout); /* End of field 17. */
|
||||
print_compliance_flags (pk2, keylength, curvename);
|
||||
es_putc (':', es_stdout); /* End of field 18. */
|
||||
es_putc ('\n', es_stdout);
|
||||
print_fingerprint (NULL, pk2, 0);
|
||||
if (hexgrip)
|
||||
@ -1540,6 +1570,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
|
||||
}
|
||||
}
|
||||
|
||||
xfree (curve);
|
||||
xfree (hexgrip_buffer);
|
||||
xfree (serialno);
|
||||
}
|
||||
|
@ -125,6 +125,9 @@ int openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use);
|
||||
int openpgp_pk_algo_usage ( int algo );
|
||||
const char *openpgp_pk_algo_name (pubkey_algo_t algo);
|
||||
|
||||
int gnupg_pk_is_compliant (int compliance, PKT_public_key *pk,
|
||||
unsigned int keylength, const char *curvename);
|
||||
|
||||
enum gcry_md_algos map_md_openpgp_to_gcry (digest_algo_t algo);
|
||||
int openpgp_md_test_algo (digest_algo_t algo);
|
||||
const char *openpgp_md_algo_name (int algo);
|
||||
|
90
g10/misc.c
90
g10/misc.c
@ -640,7 +640,7 @@ openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
|
||||
if (!ga)
|
||||
return gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||
|
||||
/* No check whether Libgcrypt has support for the algorithm. */
|
||||
/* Now check whether Libgcrypt has support for the algorithm. */
|
||||
return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
|
||||
}
|
||||
|
||||
@ -704,6 +704,94 @@ openpgp_pk_algo_name (pubkey_algo_t algo)
|
||||
}
|
||||
|
||||
|
||||
/* Return true if PK is compliant to the give COMPLIANCE mode. If
|
||||
* KEYLENGTH and CURVENAME are not 0/NULL the are assumed to be the
|
||||
* already computed values from PK. */
|
||||
int
|
||||
gnupg_pk_is_compliant (int compliance, PKT_public_key *pk,
|
||||
unsigned int keylength, const char *curvename)
|
||||
{
|
||||
enum { is_rsa, is_pgp5, is_elg_sign, is_ecc } algotype;
|
||||
int result;
|
||||
|
||||
switch (pk->pubkey_algo)
|
||||
{
|
||||
case PUBKEY_ALGO_RSA:
|
||||
case PUBKEY_ALGO_RSA_E:
|
||||
case PUBKEY_ALGO_RSA_S:
|
||||
algotype = is_rsa;
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_ELGAMAL_E:
|
||||
case PUBKEY_ALGO_DSA:
|
||||
algotype = is_pgp5;
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_ECDH:
|
||||
case PUBKEY_ALGO_ECDSA:
|
||||
case PUBKEY_ALGO_EDDSA:
|
||||
algotype = is_ecc;
|
||||
break;
|
||||
|
||||
case PUBKEY_ALGO_ELGAMAL:
|
||||
algotype = is_elg_sign;
|
||||
break;
|
||||
|
||||
default: /* Unknown. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (compliance == CO_DE_VS)
|
||||
{
|
||||
char *curve = NULL;
|
||||
|
||||
switch (algotype)
|
||||
{
|
||||
case is_pgp5:
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
case is_rsa:
|
||||
if (!keylength)
|
||||
keylength = nbits_from_pk (pk);
|
||||
result = (keylength >= 2048);
|
||||
break;
|
||||
|
||||
case is_ecc:
|
||||
if (!curvename)
|
||||
{
|
||||
curve = openpgp_oid_to_str (pk->pkey[0]);
|
||||
curvename = openpgp_oid_to_curve (curve, 0);
|
||||
if (!curvename)
|
||||
curvename = curve;
|
||||
}
|
||||
|
||||
result = (curvename
|
||||
&& pk->pubkey_algo != PUBKEY_ALGO_EDDSA
|
||||
&& (!strcmp (curvename, "brainpoolP256r1")
|
||||
|| !strcmp (curvename, "brainpoolP384r1")
|
||||
|| !strcmp (curvename, "brainpoolP512r1")));
|
||||
break;
|
||||
|
||||
default:
|
||||
result = 0;
|
||||
}
|
||||
xfree (curve);
|
||||
}
|
||||
else if (algotype == is_elg_sign)
|
||||
{
|
||||
/* An Elgamal signing key is only RFC-2440 compliant. */
|
||||
result = (compliance == RFC2440);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 1; /* Assume compliance. */
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Explicit mapping of OpenPGP digest algos to Libgcrypt. */
|
||||
/* FIXME: We do not yes use it everywhere. */
|
||||
enum gcry_md_algos
|
||||
|
18
sm/keylist.c
18
sm/keylist.c
@ -346,6 +346,14 @@ email_kludge (const char *name)
|
||||
}
|
||||
|
||||
|
||||
/* Print the compliance flags to field 18. ALGO is the gcrypt algo
|
||||
* number. NBITS is the length of the key in bits. */
|
||||
static void
|
||||
print_compliance_flags (int algo, unsigned int nbits, estream_t fp)
|
||||
{
|
||||
if (algo == GCRY_PK_RSA && nbits >= 2048)
|
||||
es_fputs ("23", fp);
|
||||
}
|
||||
|
||||
|
||||
/* List one certificate in colon mode */
|
||||
@ -496,6 +504,8 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
|
||||
print_capabilities (cert, fp);
|
||||
/* Field 13, not used: */
|
||||
es_putc (':', fp);
|
||||
/* Field 14, not used: */
|
||||
es_putc (':', fp);
|
||||
if (have_secret || ctrl->with_secret)
|
||||
{
|
||||
char *cardsn;
|
||||
@ -504,18 +514,20 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
|
||||
if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn)
|
||||
&& (cardsn || ctrl->with_secret))
|
||||
{
|
||||
/* Field 14, not used: */
|
||||
es_putc (':', fp);
|
||||
/* Field 15: Token serial number or secret key indicator. */
|
||||
if (cardsn)
|
||||
es_fputs (cardsn, fp);
|
||||
else if (ctrl->with_secret)
|
||||
es_putc ('+', fp);
|
||||
es_putc (':', fp);
|
||||
}
|
||||
xfree (cardsn);
|
||||
xfree (p);
|
||||
}
|
||||
es_putc (':', fp); /* End of field 15. */
|
||||
es_putc (':', fp); /* End of field 16. */
|
||||
es_putc (':', fp); /* End of field 17. */
|
||||
print_compliance_flags (algo, nbits, fp);
|
||||
es_putc (':', fp); /* End of field 18. */
|
||||
es_putc ('\n', fp);
|
||||
|
||||
/* FPR record */
|
||||
|
Loading…
x
Reference in New Issue
Block a user