mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg,sm: New option --with-key-screening.
* common/pkscreening.c: New. * common/pkscreening.h: New. * common/Makefile.am (common_sources): Add them. * g10/gpg.c (opts): New option --with-key-screening. * g10/options.h (struct opt): New field with_key_screening. * g10/keylist.c: Include pkscreening.h. (print_pk_screening): New. (list_keyblock_print): Call it. (print_compliance_flags): Call it. * sm/gpgsm.c (opts): New option --with-key-screening. * sm/gpgsm.h (scruct opt): New field with_key_screening. * sm/keylist.c: Include pkscreening.h. (print_pk_screening): New. (print_compliance_flags): Call it. Add new arg cert. (list_cert_colon): Pass arg cert (list_cert_std): Call print_pk_screening. * sm/fingerprint.c (gpgsm_get_rsa_modulus): New. -- This new option can be used to detect ROCA affected keys. To scan an entire keyring and print the affected fingerprints use this: gpg -k --with-key-screening --with-colons | gawk -F: \ '$1~/pub|sub|sec|ssb|crt/ && $18~/\<6001\>/ {found=1;next}; $1=="fpr" && found {print $10}; {found=0}' The same works for gpgsm. Note that we need gawk due to the "\<" in the r.e. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
69e579d785
commit
825abec0e7
@ -94,7 +94,8 @@ common_sources = \
|
|||||||
name-value.c name-value.h \
|
name-value.c name-value.h \
|
||||||
recsel.c recsel.h \
|
recsel.c recsel.h \
|
||||||
ksba-io-support.c ksba-io-support.h \
|
ksba-io-support.c ksba-io-support.h \
|
||||||
compliance.c compliance.h
|
compliance.c compliance.h \
|
||||||
|
pkscreening.c pkscreening.h
|
||||||
|
|
||||||
|
|
||||||
if HAVE_W32_SYSTEM
|
if HAVE_W32_SYSTEM
|
||||||
|
159
common/pkscreening.c
Normal file
159
common/pkscreening.c
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/* pkscreening.c - Screen public keys for vulnerabilities
|
||||||
|
* Copyright (C) 2017 Werner Koch
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "pkscreening.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper */
|
||||||
|
static inline gpg_error_t
|
||||||
|
my_error (gpg_err_code_t ec)
|
||||||
|
{
|
||||||
|
return gpg_err_make (default_errsource, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Emulation of the new gcry_mpi_get_ui function. */
|
||||||
|
static gpg_error_t
|
||||||
|
my_mpi_get_ui (unsigned int *v, gcry_mpi_t a)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
unsigned char buf[8];
|
||||||
|
size_t n;
|
||||||
|
int i, mul;
|
||||||
|
|
||||||
|
if (gcry_mpi_cmp_ui (a, 16384) > 0)
|
||||||
|
return my_error (GPG_ERR_ERANGE); /* Clearly too large for our purpose. */
|
||||||
|
|
||||||
|
err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, sizeof buf, &n, a);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
*v = 0;
|
||||||
|
for (i = n - 1, mul = 1; i >= 0; i--, mul *= 256)
|
||||||
|
*v += mul * buf[i];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Detect whether the MODULUS of a public RSA key is affected by the
|
||||||
|
* ROCA vulnerability as found in the Infinion RSA library
|
||||||
|
* (CVE-2017-15361). Returns 0 if not affected, GPG_ERR_TRUE if
|
||||||
|
* affected, GPG_ERR_BAD_MPI if an opaque RSA was passed, or other
|
||||||
|
* error codes if something weird happened */
|
||||||
|
gpg_error_t
|
||||||
|
screen_key_for_roca (gcry_mpi_t modulus)
|
||||||
|
{
|
||||||
|
static struct {
|
||||||
|
unsigned int prime_ui;
|
||||||
|
const char *print_hex;
|
||||||
|
gcry_mpi_t prime;
|
||||||
|
gcry_mpi_t print;
|
||||||
|
} table[] = {
|
||||||
|
{ 3, "0x6" },
|
||||||
|
{ 5, "0x1E" },
|
||||||
|
{ 7, "0x7E" },
|
||||||
|
{ 11, "0x402" },
|
||||||
|
{ 13, "0x161A" },
|
||||||
|
{ 17, "0x1A316" },
|
||||||
|
{ 19, "0x30AF2" },
|
||||||
|
{ 23, "0x7FFFFE" },
|
||||||
|
{ 29, "0x1FFFFFFE" },
|
||||||
|
{ 31, "0x7FFFFFFE" },
|
||||||
|
{ 37, "0x4000402" },
|
||||||
|
{ 41, "0x1FFFFFFFFFE" },
|
||||||
|
{ 43, "0x7FFFFFFFFFE" },
|
||||||
|
{ 47, "0x7FFFFFFFFFFE" },
|
||||||
|
{ 53, "0x12DD703303AED2" },
|
||||||
|
{ 59, "0x7FFFFFFFFFFFFFE" },
|
||||||
|
{ 61, "0x1434026619900B0A" },
|
||||||
|
{ 67, "0x7FFFFFFFFFFFFFFFE" },
|
||||||
|
{ 71, "0x1164729716B1D977E" },
|
||||||
|
{ 73, "0x147811A48004962078A" },
|
||||||
|
{ 79, "0xB4010404000640502" },
|
||||||
|
{ 83, "0x7FFFFFFFFFFFFFFFFFFFE" },
|
||||||
|
{ 89, "0x1FFFFFFFFFFFFFFFFFFFFFE" },
|
||||||
|
{ 97, "0x1000000006000001800000002" },
|
||||||
|
{ 101, "0x1FFFFFFFFFFFFFFFFFFFFFFFFE" },
|
||||||
|
{ 103, "0x16380E9115BD964257768FE396" },
|
||||||
|
{ 107, "0x27816EA9821633397BE6A897E1A" },
|
||||||
|
{ 109, "0x1752639F4E85B003685CBE7192BA" },
|
||||||
|
{ 113, "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
|
||||||
|
{ 127, "0x6CA09850C2813205A04C81430A190536" },
|
||||||
|
{ 131, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
|
||||||
|
{ 137, "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
|
||||||
|
{ 139, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
|
||||||
|
{ 149, "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
|
||||||
|
{ 151, "0x50C018BC00482458DAC35B1A2412003D18030A" },
|
||||||
|
{ 157, "0x161FB414D76AF63826461899071BD5BACA0B7E1A" },
|
||||||
|
{ 163, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" },
|
||||||
|
{ 167, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" }
|
||||||
|
};
|
||||||
|
gpg_error_t err;
|
||||||
|
int i;
|
||||||
|
gcry_mpi_t rem;
|
||||||
|
unsigned int bitno;
|
||||||
|
|
||||||
|
/* Initialize on the first call. */
|
||||||
|
if (!table[0].prime)
|
||||||
|
{
|
||||||
|
/* We pass primes[i] to the call so that in case of a concurrent
|
||||||
|
* second thread the already allocated space is reused. */
|
||||||
|
for (i = 0; i < DIM (table); i++)
|
||||||
|
{
|
||||||
|
table[i].prime = gcry_mpi_set_ui (table[i].prime, table[i].prime_ui);
|
||||||
|
if (gcry_mpi_scan (&table[i].print, GCRYMPI_FMT_HEX,
|
||||||
|
table[i].print_hex, 0, NULL))
|
||||||
|
BUG ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that it is not NULL or an opaque MPI. */
|
||||||
|
if (!modulus || gcry_mpi_get_flag (modulus, GCRYMPI_FLAG_OPAQUE))
|
||||||
|
return my_error (GPG_ERR_BAD_MPI);
|
||||||
|
|
||||||
|
/* We divide the modulus of an RSA public key by a set of small
|
||||||
|
* PRIMEs and examine all the remainders. If all the bits at the
|
||||||
|
* index given by the remainder are set in the corresponding PRINT
|
||||||
|
* masks the key is very likely vulnerable. If any of the tested
|
||||||
|
* bits is zero, the key is not vulnerable. */
|
||||||
|
rem = gcry_mpi_new (0);
|
||||||
|
for (i = 0; i < DIM (table); i++)
|
||||||
|
{
|
||||||
|
gcry_mpi_mod (rem, modulus, table[i].prime);
|
||||||
|
err = my_mpi_get_ui (&bitno, rem);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_ERANGE)
|
||||||
|
continue;
|
||||||
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
if (!gcry_mpi_test_bit (table[i].print, bitno))
|
||||||
|
goto leave; /* Not vulnerable. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Very likely vulnerable */
|
||||||
|
err = my_error (GPG_ERR_TRUE);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
gcry_mpi_release (rem);
|
||||||
|
return err;
|
||||||
|
}
|
26
common/pkscreening.h
Normal file
26
common/pkscreening.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/* pkscreening.c - Screen public keys for vulnerabilities
|
||||||
|
* Copyright (C) 2017 Werner Koch
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GNUPG_COMMON_PKSCREENING_H
|
||||||
|
#define GNUPG_COMMON_PKSCREENING_H
|
||||||
|
|
||||||
|
gpg_error_t screen_key_for_roca (gcry_mpi_t modulus);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*GNUPG_COMMON_PKSCREENING_H*/
|
@ -222,12 +222,14 @@ described here.
|
|||||||
|
|
||||||
*** Field 18 - Compliance flags
|
*** Field 18 - Compliance flags
|
||||||
|
|
||||||
Space separated list of asserted compliance modes for this key.
|
Space separated list of asserted compliance modes and
|
||||||
|
screening result for this key.
|
||||||
|
|
||||||
Valid values are:
|
Valid values are:
|
||||||
|
|
||||||
- 8 :: The key is compliant with RFC4880bis
|
- 8 :: The key is compliant with RFC4880bis
|
||||||
- 23 :: The key is compliant with compliance mode "de-vs".
|
- 23 :: The key is compliant with compliance mode "de-vs".
|
||||||
|
- 6001 :: Screening hit on the ROCA vulnerability.
|
||||||
|
|
||||||
*** Field 19 - Last update
|
*** Field 19 - Last update
|
||||||
|
|
||||||
|
@ -197,6 +197,7 @@ enum cmd_and_opt_values
|
|||||||
oWithSubkeyFingerprint,
|
oWithSubkeyFingerprint,
|
||||||
oWithICAOSpelling,
|
oWithICAOSpelling,
|
||||||
oWithKeygrip,
|
oWithKeygrip,
|
||||||
|
oWithKeyScreening,
|
||||||
oWithSecret,
|
oWithSecret,
|
||||||
oWithWKDHash,
|
oWithWKDHash,
|
||||||
oWithColons,
|
oWithColons,
|
||||||
@ -785,6 +786,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"),
|
ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"),
|
||||||
ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"),
|
ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"),
|
||||||
ARGPARSE_s_n (oWithKeygrip, "with-keygrip", "@"),
|
ARGPARSE_s_n (oWithKeygrip, "with-keygrip", "@"),
|
||||||
|
ARGPARSE_s_n (oWithKeyScreening,"with-key-screening", "@"),
|
||||||
ARGPARSE_s_n (oWithSecret, "with-secret", "@"),
|
ARGPARSE_s_n (oWithSecret, "with-secret", "@"),
|
||||||
ARGPARSE_s_n (oWithWKDHash, "with-wkd-hash", "@"),
|
ARGPARSE_s_n (oWithWKDHash, "with-wkd-hash", "@"),
|
||||||
ARGPARSE_s_n (oWithKeyOrigin, "with-key-origin", "@"),
|
ARGPARSE_s_n (oWithKeyOrigin, "with-key-origin", "@"),
|
||||||
@ -2737,6 +2739,10 @@ main (int argc, char **argv)
|
|||||||
opt.with_keygrip = 1;
|
opt.with_keygrip = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case oWithKeyScreening:
|
||||||
|
opt.with_key_screening = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case oWithSecret:
|
case oWithSecret:
|
||||||
opt.with_secret = 1;
|
opt.with_secret = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include "../common/zb32.h"
|
#include "../common/zb32.h"
|
||||||
#include "tofu.h"
|
#include "tofu.h"
|
||||||
#include "../common/compliance.h"
|
#include "../common/compliance.h"
|
||||||
|
#include "../common/pkscreening.h"
|
||||||
|
|
||||||
|
|
||||||
static void list_all (ctrl_t, int, int);
|
static void list_all (ctrl_t, int, int);
|
||||||
@ -696,6 +697,37 @@ print_key_data (PKT_public_key * pk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Various public key screenings. (Right now just ROCA). With
|
||||||
|
* COLON_MODE set the output is formatted for use in the compliance
|
||||||
|
* field of a colon listing.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
print_pk_screening (PKT_public_key *pk, int colon_mode)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
if (is_RSA (pk->pubkey_algo) && pubkey_get_npkey (pk->pubkey_algo))
|
||||||
|
{
|
||||||
|
err = screen_key_for_roca (pk->pkey[0]);
|
||||||
|
if (!err)
|
||||||
|
;
|
||||||
|
else if (gpg_err_code (err) == GPG_ERR_TRUE)
|
||||||
|
{
|
||||||
|
if (colon_mode)
|
||||||
|
es_fprintf (es_stdout, colon_mode > 1? " %d":"%d", 6001);
|
||||||
|
else
|
||||||
|
es_fprintf (es_stdout,
|
||||||
|
" Screening: ROCA vulnerability detected\n");
|
||||||
|
}
|
||||||
|
else if (!colon_mode)
|
||||||
|
es_fprintf (es_stdout, " Screening: [ROCA check failed: %s]\n",
|
||||||
|
gpg_strerror (err));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_capabilities (ctrl_t ctrl, PKT_public_key *pk, KBNODE keyblock)
|
print_capabilities (ctrl_t ctrl, PKT_public_key *pk, KBNODE keyblock)
|
||||||
{
|
{
|
||||||
@ -922,6 +954,9 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
|
|||||||
if (opt.with_key_data)
|
if (opt.with_key_data)
|
||||||
print_key_data (pk);
|
print_key_data (pk);
|
||||||
|
|
||||||
|
if (opt.with_key_screening)
|
||||||
|
print_pk_screening (pk, 0);
|
||||||
|
|
||||||
if (opt.with_key_origin
|
if (opt.with_key_origin
|
||||||
&& (pk->keyorg || pk->keyupdate || pk->updateurl))
|
&& (pk->keyorg || pk->keyupdate || pk->updateurl))
|
||||||
{
|
{
|
||||||
@ -1063,6 +1098,8 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
|
|||||||
es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
|
es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
|
||||||
if (opt.with_key_data)
|
if (opt.with_key_data)
|
||||||
print_key_data (pk2);
|
print_key_data (pk2);
|
||||||
|
if (opt.with_key_screening)
|
||||||
|
print_pk_screening (pk2, 0);
|
||||||
}
|
}
|
||||||
else if (opt.list_sigs
|
else if (opt.list_sigs
|
||||||
&& node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
|
&& node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
|
||||||
@ -1227,6 +1264,9 @@ print_compliance_flags (PKT_public_key *pk,
|
|||||||
gnupg_status_compliance_flag (CO_DE_VS));
|
gnupg_status_compliance_flag (CO_DE_VS));
|
||||||
any++;
|
any++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt.with_key_screening)
|
||||||
|
print_pk_screening (pk, 1+any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ struct
|
|||||||
int with_fingerprint; /* Option --with-fingerprint active. */
|
int with_fingerprint; /* Option --with-fingerprint active. */
|
||||||
int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active. */
|
int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active. */
|
||||||
int with_keygrip; /* Option --with-keygrip active. */
|
int with_keygrip; /* Option --with-keygrip active. */
|
||||||
|
int with_key_screening;/* Option --with-key-screening active. */
|
||||||
int with_tofu_info; /* Option --with-tofu_info active. */
|
int with_tofu_info; /* Option --with-tofu_info active. */
|
||||||
int with_secret; /* Option --with-secret active. */
|
int with_secret; /* Option --with-secret active. */
|
||||||
int with_wkd_hash; /* Option --with-wkd-hash. */
|
int with_wkd_hash; /* Option --with-wkd-hash. */
|
||||||
|
@ -277,6 +277,70 @@ gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If KEY is an RSA key, return its modulus. For non-RSA keys or on
|
||||||
|
* error return NULL. */
|
||||||
|
gcry_mpi_t
|
||||||
|
gpgsm_get_rsa_modulus (ksba_cert_t cert)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
gcry_sexp_t key;
|
||||||
|
gcry_sexp_t list = NULL;
|
||||||
|
gcry_sexp_t l2 = NULL;
|
||||||
|
char *name = NULL;
|
||||||
|
gcry_mpi_t modulus = NULL;
|
||||||
|
|
||||||
|
{
|
||||||
|
ksba_sexp_t ckey;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
ckey = ksba_cert_get_public_key (cert);
|
||||||
|
if (!ckey)
|
||||||
|
return NULL;
|
||||||
|
n = gcry_sexp_canon_len (ckey, 0, NULL, NULL);
|
||||||
|
if (!n)
|
||||||
|
{
|
||||||
|
xfree (ckey);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
err = gcry_sexp_sscan (&key, NULL, (char *)ckey, n);
|
||||||
|
xfree (ckey);
|
||||||
|
if (err)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list = gcry_sexp_find_token (key, "public-key", 0);
|
||||||
|
if (!list)
|
||||||
|
list = gcry_sexp_find_token (key, "private-key", 0);
|
||||||
|
if (!list)
|
||||||
|
list = gcry_sexp_find_token (key, "protected-private-key", 0);
|
||||||
|
if (!list)
|
||||||
|
list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
|
||||||
|
|
||||||
|
gcry_sexp_release (key);
|
||||||
|
if (!list)
|
||||||
|
return NULL; /* No suitable key. */
|
||||||
|
|
||||||
|
l2 = gcry_sexp_cadr (list);
|
||||||
|
gcry_sexp_release (list);
|
||||||
|
list = l2;
|
||||||
|
l2 = NULL;
|
||||||
|
|
||||||
|
name = gcry_sexp_nth_string (list, 0);
|
||||||
|
if (!name)
|
||||||
|
;
|
||||||
|
else if (gcry_pk_map_name (name) == GCRY_PK_RSA)
|
||||||
|
{
|
||||||
|
l2 = gcry_sexp_find_token (list, "n", 1);
|
||||||
|
if (l2)
|
||||||
|
modulus = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
|
||||||
|
}
|
||||||
|
|
||||||
|
gcry_free (name);
|
||||||
|
gcry_sexp_release (l2);
|
||||||
|
gcry_sexp_release (list);
|
||||||
|
return modulus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* For certain purposes we need a certificate id which has an upper
|
/* For certain purposes we need a certificate id which has an upper
|
||||||
|
@ -155,6 +155,7 @@ enum cmd_and_opt_values {
|
|||||||
oWithMD5Fingerprint,
|
oWithMD5Fingerprint,
|
||||||
oWithKeygrip,
|
oWithKeygrip,
|
||||||
oWithSecret,
|
oWithSecret,
|
||||||
|
oWithKeyScreening,
|
||||||
oAnswerYes,
|
oAnswerYes,
|
||||||
oAnswerNo,
|
oAnswerNo,
|
||||||
oKeyring,
|
oKeyring,
|
||||||
@ -391,6 +392,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
|
ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
|
||||||
ARGPARSE_s_n (oWithKeygrip, "with-keygrip", "@"),
|
ARGPARSE_s_n (oWithKeygrip, "with-keygrip", "@"),
|
||||||
ARGPARSE_s_n (oWithSecret, "with-secret", "@"),
|
ARGPARSE_s_n (oWithSecret, "with-secret", "@"),
|
||||||
|
ARGPARSE_s_n (oWithKeyScreening,"with-key-screening", "@"),
|
||||||
ARGPARSE_s_s (oDisableCipherAlgo, "disable-cipher-algo", "@"),
|
ARGPARSE_s_s (oDisableCipherAlgo, "disable-cipher-algo", "@"),
|
||||||
ARGPARSE_s_s (oDisablePubkeyAlgo, "disable-pubkey-algo", "@"),
|
ARGPARSE_s_s (oDisablePubkeyAlgo, "disable-pubkey-algo", "@"),
|
||||||
ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"),
|
ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"),
|
||||||
@ -1289,6 +1291,10 @@ main ( int argc, char **argv)
|
|||||||
opt.with_keygrip = 1;
|
opt.with_keygrip = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case oWithKeyScreening:
|
||||||
|
opt.with_key_screening = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case oOptions:
|
case oOptions:
|
||||||
/* config files may not be nested (silently ignore them) */
|
/* config files may not be nested (silently ignore them) */
|
||||||
if (!configfp)
|
if (!configfp)
|
||||||
|
@ -85,6 +85,8 @@ struct
|
|||||||
|
|
||||||
int with_keygrip; /* Option --with-keygrip active. */
|
int with_keygrip; /* Option --with-keygrip active. */
|
||||||
|
|
||||||
|
int with_key_screening; /* Option --with-key-screening active. */
|
||||||
|
|
||||||
int pinentry_mode;
|
int pinentry_mode;
|
||||||
|
|
||||||
int armor; /* force base64 armoring (see also ctrl.with_base64) */
|
int armor; /* force base64 armoring (see also ctrl.with_base64) */
|
||||||
@ -258,6 +260,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);
|
||||||
|
gcry_mpi_t gpgsm_get_rsa_modulus (ksba_cert_t cert);
|
||||||
char *gpgsm_get_certid (ksba_cert_t cert);
|
char *gpgsm_get_certid (ksba_cert_t cert);
|
||||||
|
|
||||||
|
|
||||||
|
51
sm/keylist.c
51
sm/keylist.c
@ -37,6 +37,7 @@
|
|||||||
#include "../common/i18n.h"
|
#include "../common/i18n.h"
|
||||||
#include "../common/tlv.h"
|
#include "../common/tlv.h"
|
||||||
#include "../common/compliance.h"
|
#include "../common/compliance.h"
|
||||||
|
#include "../common/pkscreening.h"
|
||||||
|
|
||||||
struct list_external_parm_s
|
struct list_external_parm_s
|
||||||
{
|
{
|
||||||
@ -238,6 +239,38 @@ print_key_data (ksba_cert_t cert, estream_t fp)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Various public key screenings. (Right now just ROCA). With
|
||||||
|
* COLON_MODE set the output is formatted for use in the compliance
|
||||||
|
* field of a colon listing. */
|
||||||
|
static void
|
||||||
|
print_pk_screening (ksba_cert_t cert, int colon_mode, estream_t fp)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
gcry_mpi_t modulus;
|
||||||
|
|
||||||
|
modulus = gpgsm_get_rsa_modulus (cert);
|
||||||
|
if (modulus)
|
||||||
|
{
|
||||||
|
err = screen_key_for_roca (modulus);
|
||||||
|
if (!err)
|
||||||
|
;
|
||||||
|
else if (gpg_err_code (err) == GPG_ERR_TRUE)
|
||||||
|
{
|
||||||
|
if (colon_mode)
|
||||||
|
es_fprintf (fp, colon_mode > 1? " %d":"%d", 6001);
|
||||||
|
else
|
||||||
|
es_fprintf (fp, " screening: ROCA vulnerability detected\n");
|
||||||
|
}
|
||||||
|
else if (!colon_mode)
|
||||||
|
es_fprintf (fp, " screening: [ROCA check failed: %s]\n",
|
||||||
|
gpg_strerror (err));
|
||||||
|
gcry_mpi_release (modulus);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_capabilities (ksba_cert_t cert, estream_t fp)
|
print_capabilities (ksba_cert_t cert, estream_t fp)
|
||||||
{
|
{
|
||||||
@ -348,10 +381,19 @@ email_kludge (const char *name)
|
|||||||
/* Print the compliance flags to field 18. ALGO is the gcrypt algo
|
/* Print the compliance flags to field 18. ALGO is the gcrypt algo
|
||||||
* number. NBITS is the length of the key in bits. */
|
* number. NBITS is the length of the key in bits. */
|
||||||
static void
|
static void
|
||||||
print_compliance_flags (int algo, unsigned int nbits, estream_t fp)
|
print_compliance_flags (ksba_cert_t cert, int algo, unsigned int nbits,
|
||||||
|
estream_t fp)
|
||||||
{
|
{
|
||||||
|
int any = 0;
|
||||||
|
|
||||||
if (gnupg_pk_is_compliant (CO_DE_VS, algo, NULL, nbits, NULL))
|
if (gnupg_pk_is_compliant (CO_DE_VS, algo, NULL, nbits, NULL))
|
||||||
es_fputs (gnupg_status_compliance_flag (CO_DE_VS), fp);
|
{
|
||||||
|
es_fputs (gnupg_status_compliance_flag (CO_DE_VS), fp);
|
||||||
|
any++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt.with_key_screening)
|
||||||
|
print_pk_screening (cert, 1+any, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -526,7 +568,7 @@ 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 15. */
|
||||||
es_putc (':', fp); /* End of field 16. */
|
es_putc (':', fp); /* End of field 16. */
|
||||||
es_putc (':', fp); /* End of field 17. */
|
es_putc (':', fp); /* End of field 17. */
|
||||||
print_compliance_flags (algo, nbits, fp);
|
print_compliance_flags (cert, algo, nbits, fp);
|
||||||
es_putc (':', fp); /* End of field 18. */
|
es_putc (':', fp); /* End of field 18. */
|
||||||
es_putc ('\n', fp);
|
es_putc ('\n', fp);
|
||||||
|
|
||||||
@ -1253,6 +1295,9 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt.with_key_screening)
|
||||||
|
print_pk_screening (cert, 0, fp);
|
||||||
|
|
||||||
if (have_secret)
|
if (have_secret)
|
||||||
{
|
{
|
||||||
char *cardsn;
|
char *cardsn;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user