mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Add option --assert-pubkey_algo.
* g10/keyid.c (parse_one_algo_string): New. (compare_pubkey_string_part): New. (compare_pubkey_string): New. * g10/verify.c (check_assert_signer_list): New. * g10/mainproc.c (check_sig_and_print): Call check_assert_pubkey_algo. * g10/options.h (opt): Add field assert_pubkey_algos. * g10/gpg.c (oAssertPubkeyAlgo): New. (opts): Add "--assert-pubkey_algo". (assert_pubkey_algo_false): New. (main): Parse option. (g10_exit): Reorder RC modifications. Check assert_pubkey_algo_false. * common/status.h (ASSERT_PUBKEY_ALGOS): new. * common/t-support.h (LEAN_T_SUPPORT): Use a simplified version if this macro is set. * g10/gpgv.c (oAssertPubkeyAlgo): New. (opts): Add "--assert-pubkey_algo". (assert_pubkey_algo_false): New. (main): Parse option. (g10_exit): Check assert_pubkey_algo_false. * g10/t-keyid.c: New. * g10/Makefile.am: Add t-keyid. * g10/test-stubs.c: Add assert_pubkey_algos and assert_signer_list and remove from other tests. (check_assert_signer_list): Ditto. (check_assert_pubkey_algo): Ditto. -- GnuPG-bug-id: 6946
This commit is contained in:
parent
5842eee805
commit
302afcb6f6
@ -54,6 +54,7 @@ enum
|
||||
STATUS_NEED_PASSPHRASE,
|
||||
STATUS_VALIDSIG,
|
||||
STATUS_ASSERT_SIGNER,
|
||||
STATUS_ASSERT_PUBKEY_ALGO,
|
||||
STATUS_SIG_ID,
|
||||
STATUS_ENC_TO,
|
||||
STATUS_NODATA,
|
||||
|
@ -31,6 +31,8 @@
|
||||
#ifndef GNUPG_COMMON_T_SUPPORT_H
|
||||
#define GNUPG_COMMON_T_SUPPORT_H 1
|
||||
|
||||
#ifndef LEAN_T_SUPPORT
|
||||
|
||||
#ifdef GCRYPT_VERSION
|
||||
#error The regression tests should not include with gcrypt.h
|
||||
#endif
|
||||
@ -45,11 +47,6 @@
|
||||
# define getenv(a) (NULL)
|
||||
#endif
|
||||
|
||||
#ifndef DIM
|
||||
# define DIM(v) (sizeof(v)/sizeof((v)[0]))
|
||||
# define DIMof(type,member) DIM(((type *)0)->member)
|
||||
#endif
|
||||
|
||||
|
||||
/* Replacement prototypes. */
|
||||
void *gcry_xmalloc (size_t n);
|
||||
@ -65,6 +62,12 @@ void gcry_free (void *a);
|
||||
#define xstrdup(a) gcry_xstrdup ( (a) )
|
||||
#define xfree(a) gcry_free ( (a) )
|
||||
|
||||
#endif /* LEAN_T_SUPPORT */
|
||||
|
||||
#ifndef DIM
|
||||
# define DIM(v) (sizeof(v)/sizeof((v)[0]))
|
||||
# define DIMof(type,member) DIM(((type *)0)->member)
|
||||
#endif
|
||||
|
||||
/* Macros to print the result of a test. */
|
||||
#define pass() do { ; } while(0)
|
||||
|
@ -527,6 +527,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
|
||||
--assert-signer is used. The fingerprint is printed with
|
||||
uppercase hex digits.
|
||||
|
||||
*** ASSERT_PUBKEY_ALGO <fingerprint> <state> <algostr>
|
||||
This is emitted when option --assert-pubkey-algo is used and the
|
||||
signing algorithms is accepted according to that list if state is
|
||||
1 or denied if state is 0. The fingerprint is printed with
|
||||
uppercase hex digits.
|
||||
|
||||
*** SIG_ID <radix64_string> <sig_creation_date> <sig-timestamp>
|
||||
This is emitted only for signatures of class 0 or 1 which have
|
||||
been verified okay. The string is a signature id and may be used
|
||||
|
23
doc/gpg.texi
23
doc/gpg.texi
@ -1917,6 +1917,29 @@ is guaranteed to return with an exit code of 0 if and only if a
|
||||
signature has been encountered, is valid, and the key matches one of
|
||||
the fingerprints given by this option.
|
||||
|
||||
@item --assert-pubkey-algo @var{algolist}
|
||||
@opindex assert-pubkey-algo
|
||||
During data signature verification this options checks whether the
|
||||
used public key algorithm matches the algorithms given by
|
||||
@var{algolist}. This option can be given multiple times to
|
||||
concatenate more algorithms to the list; the delimiter of the list are
|
||||
either commas or spaces.
|
||||
|
||||
The algorithm names given in the list may either be verbatim names
|
||||
like "ed25519" with an optional leading single equal sign, or being
|
||||
prefixed with ">", ">=", "<=", or "<". That prefix operator is
|
||||
applied to the number part of the algorithm name; for example 2048 in
|
||||
"rsa2048" or 384 in "brainpoolP384r1". If the the leading non-digits
|
||||
in the name matches, the prefix operator is used to compare the number
|
||||
part, a trailing suffix is ignored in this case. For example an
|
||||
algorithm list ">rsa3000, >=brainpool384r1, =ed25519" allows RSA
|
||||
signatures with more that 3000 bits, Brainpool curves 384 and 512,
|
||||
and the ed25519 algorithm.
|
||||
|
||||
With this option gpg (and also gpgv) is guaranteed to return with an
|
||||
exit code of 0 if and only if all valid signatures on data are made
|
||||
using a matching algorithm from the given list.
|
||||
|
||||
|
||||
@item --auto-key-locate @var{mechanisms}
|
||||
@itemx --no-auto-key-locate
|
||||
|
@ -140,6 +140,10 @@ This option enables a mode in which filenames of the form
|
||||
@file{-&n}, where n is a non-negative decimal number,
|
||||
refer to the file descriptor n and not to a file with that name.
|
||||
|
||||
@item --assert-pubkey-algo @var{algolist}
|
||||
@opindex assert-pubkey-algo
|
||||
This option works in the same way as described for @command{gpg}.
|
||||
|
||||
@end table
|
||||
|
||||
@mansect return value
|
||||
@ -190,4 +194,3 @@ The default keyring with the allowed keys.
|
||||
@mansect see also
|
||||
@command{gpg}(1)
|
||||
@include see-also-note.texi
|
||||
|
||||
|
@ -183,7 +183,7 @@ gpgv_LDFLAGS =
|
||||
|
||||
|
||||
t_common_ldadd =
|
||||
module_tests = t-rmd160 t-keydb t-keydb-get-keyblock t-stutter
|
||||
module_tests = t-rmd160 t-keydb t-keydb-get-keyblock t-stutter t-keyid
|
||||
t_rmd160_SOURCES = t-rmd160.c rmd160.c
|
||||
t_rmd160_LDADD = $(t_common_ldadd)
|
||||
t_keydb_SOURCES = t-keydb.c test-stubs.c $(common_source)
|
||||
@ -200,6 +200,10 @@ t_stutter_SOURCES = t-stutter.c test-stubs.c \
|
||||
t_stutter_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \
|
||||
$(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) $(NETLIBS) \
|
||||
$(LIBICONV) $(t_common_ldadd)
|
||||
t_keyid_SOURCES = t-keyid.c test-stubs.c $(common_source)
|
||||
t_keyid_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \
|
||||
$(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) $(NETLIBS) \
|
||||
$(LIBICONV) $(t_common_ldadd)
|
||||
|
||||
|
||||
$(PROGRAMS): $(needed_libs) ../common/libgpgrl.a
|
||||
|
39
g10/gpg.c
39
g10/gpg.c
@ -451,6 +451,7 @@ enum cmd_and_opt_values
|
||||
oCompatibilityFlags,
|
||||
oAddDesigRevoker,
|
||||
oAssertSigner,
|
||||
oAssertPubkeyAlgo,
|
||||
oKbxBufferSize,
|
||||
|
||||
oNoop
|
||||
@ -715,6 +716,7 @@ static gpgrt_opt_t opts[] = {
|
||||
#endif
|
||||
ARGPARSE_s_s (oAddDesigRevoker, "add-desig-revoker", "@"),
|
||||
ARGPARSE_s_s (oAssertSigner, "assert-signer", "@"),
|
||||
ARGPARSE_s_s (oAssertPubkeyAlgo,"assert-pubkey-algo", "@"),
|
||||
|
||||
ARGPARSE_header ("Input", N_("Options controlling the input")),
|
||||
|
||||
@ -1044,9 +1046,12 @@ static struct compatibility_flags_s compatibility_flags [] =
|
||||
|
||||
/* Can be set to true to force gpg to return with EXIT_FAILURE. */
|
||||
int g10_errors_seen = 0;
|
||||
/* If opt.assert_signer_list is used and this variabale is not true
|
||||
/* If opt.assert_signer_list is used and this variable is not true
|
||||
* gpg will be forced to return EXIT_FAILURE. */
|
||||
int assert_signer_true = 0;
|
||||
/* If opt.assert_pubkey_algo is used and this variable is not true
|
||||
* gpg will be forced to return EXIT_FAILURE. */
|
||||
int assert_pubkey_algo_false = 0;
|
||||
|
||||
|
||||
static int utf8_strings =
|
||||
@ -3770,6 +3775,18 @@ main (int argc, char **argv)
|
||||
add_to_strlist (&opt.assert_signer_list, pargs.r.ret_str);
|
||||
break;
|
||||
|
||||
case oAssertPubkeyAlgo:
|
||||
if (!opt.assert_pubkey_algos)
|
||||
opt.assert_pubkey_algos = xstrdup (pargs.r.ret_str);
|
||||
else
|
||||
{
|
||||
char *tmp = opt.assert_pubkey_algos;
|
||||
opt.assert_pubkey_algos = xstrconcat (tmp, ",",
|
||||
pargs.r.ret_str, NULL);
|
||||
xfree (tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
case oKbxBufferSize:
|
||||
keybox_set_buffersize (pargs.r.ret_ulong, 0);
|
||||
break;
|
||||
@ -5472,6 +5489,17 @@ emergency_cleanup (void)
|
||||
void
|
||||
g10_exit( int rc )
|
||||
{
|
||||
if (rc)
|
||||
;
|
||||
else if (log_get_errorcount(0))
|
||||
rc = 2;
|
||||
else if (g10_errors_seen)
|
||||
rc = 1;
|
||||
else if (opt.assert_signer_list && !assert_signer_true)
|
||||
rc = 1;
|
||||
else if (opt.assert_pubkey_algos && assert_pubkey_algo_false)
|
||||
rc = 1;
|
||||
|
||||
/* If we had an error but not printed an error message, do it now.
|
||||
* Note that write_status_failure will never print a second failure
|
||||
* status line. */
|
||||
@ -5496,15 +5524,6 @@ g10_exit( int rc )
|
||||
gnupg_block_all_signals ();
|
||||
emergency_cleanup ();
|
||||
|
||||
if (rc)
|
||||
;
|
||||
else if (log_get_errorcount(0))
|
||||
rc = 2;
|
||||
else if (g10_errors_seen)
|
||||
rc = 1;
|
||||
else if (opt.assert_signer_list && !assert_signer_true)
|
||||
rc = 1;
|
||||
|
||||
exit (rc);
|
||||
}
|
||||
|
||||
|
30
g10/gpgv.c
30
g10/gpgv.c
@ -68,6 +68,7 @@ enum cmd_and_opt_values {
|
||||
oWeakDigest,
|
||||
oEnableSpecialFilenames,
|
||||
oDebug,
|
||||
oAssertPubkeyAlgo,
|
||||
aTest
|
||||
};
|
||||
|
||||
@ -91,6 +92,7 @@ static gpgrt_opt_t opts[] = {
|
||||
N_("|ALGO|reject signatures made with ALGO")),
|
||||
ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"),
|
||||
ARGPARSE_s_s (oDebug, "debug", "@"),
|
||||
ARGPARSE_s_s (oAssertPubkeyAlgo,"assert-pubkey-algo", "@"),
|
||||
|
||||
ARGPARSE_end ()
|
||||
};
|
||||
@ -119,6 +121,7 @@ static struct debug_flags_s debug_flags [] =
|
||||
|
||||
int g10_errors_seen = 0;
|
||||
int assert_signer_true = 0;
|
||||
int assert_pubkey_algo_false = 0;
|
||||
|
||||
static char *
|
||||
make_libversion (const char *libname, const char *(*getfnc)(const char*))
|
||||
@ -251,6 +254,19 @@ main( int argc, char **argv )
|
||||
case oEnableSpecialFilenames:
|
||||
enable_special_filenames ();
|
||||
break;
|
||||
|
||||
case oAssertPubkeyAlgo:
|
||||
if (!opt.assert_pubkey_algos)
|
||||
opt.assert_pubkey_algos = xstrdup (pargs.r.ret_str);
|
||||
else
|
||||
{
|
||||
char *tmp = opt.assert_pubkey_algos;
|
||||
opt.assert_pubkey_algos = xstrconcat (tmp, ",",
|
||||
pargs.r.ret_str, NULL);
|
||||
xfree (tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
default : pargs.err = ARGPARSE_PRINT_ERROR; break;
|
||||
}
|
||||
}
|
||||
@ -288,10 +304,18 @@ main( int argc, char **argv )
|
||||
|
||||
|
||||
void
|
||||
g10_exit( int rc )
|
||||
g10_exit (int rc)
|
||||
{
|
||||
rc = rc? rc : log_get_errorcount(0)? 2 : g10_errors_seen? 1 : 0;
|
||||
exit(rc );
|
||||
if (rc)
|
||||
;
|
||||
else if (log_get_errorcount(0))
|
||||
rc = 2;
|
||||
else if (g10_errors_seen)
|
||||
rc = 1;
|
||||
else if (opt.assert_pubkey_algos && assert_pubkey_algo_false)
|
||||
rc = 1;
|
||||
|
||||
exit (rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -487,6 +487,7 @@ const char *key_origin_string (int origin);
|
||||
/*-- keyid.c --*/
|
||||
int pubkey_letter( int algo );
|
||||
char *pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize);
|
||||
int compare_pubkey_string (const char *astr, const char *bstr);
|
||||
#define PUBKEY_STRING_SIZE 32
|
||||
u32 v3_keyid (gcry_mpi_t a, u32 *ki);
|
||||
void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk );
|
||||
|
124
g10/keyid.c
124
g10/keyid.c
@ -140,6 +140,130 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
|
||||
}
|
||||
|
||||
|
||||
/* Helper for compare_pubkey_string. This skips leading spaces,
|
||||
* commas and optional condition operators and returns a pointer to
|
||||
* the first non-space character or NULL in case of an error. The
|
||||
* length of a prefix consisting of letters is then returned ar PFXLEN
|
||||
* and the value of the number (e.g. 384 for "brainpoolP384r1") at
|
||||
* NUMBER. R_LENGTH receives the entire length of the algorithm name
|
||||
* which is terminated by a space, nul, or a comma. If R_CONDITION is
|
||||
* not NULL, 0 is stored for a leading "=", 1 for a ">", 2 for a ">=",
|
||||
* -1 for a "<", and -2 for a "<=". If R_CONDITION is NULL no
|
||||
* condition prefix is allowed. */
|
||||
static const char *
|
||||
parse_one_algo_string (const char *str, size_t *pfxlen, unsigned int *number,
|
||||
size_t *r_length, int *r_condition)
|
||||
{
|
||||
int condition = 0;
|
||||
const char *result;
|
||||
|
||||
while (spacep (str) || *str ==',')
|
||||
str++;
|
||||
if (!r_condition)
|
||||
;
|
||||
else if (*str == '>' && str[1] == '=')
|
||||
condition = 2, str += 2;
|
||||
else if (*str == '>' )
|
||||
condition = 1, str += 1;
|
||||
else if (*str == '<' && str[1] == '=')
|
||||
condition = -2, str += 2;
|
||||
else if (*str == '<')
|
||||
condition = -1, str += 1;
|
||||
else if (*str == '=') /* Default. */
|
||||
str += 1;
|
||||
|
||||
if (!alphap (str))
|
||||
return NULL; /* Error. */
|
||||
|
||||
*pfxlen = 1;
|
||||
for (result = str++; alphap (str); str++)
|
||||
++*pfxlen;
|
||||
while (*str == '-' || *str == '+')
|
||||
str++;
|
||||
*number = atoi (str);
|
||||
while (*str && !spacep (str) && *str != ',')
|
||||
str++;
|
||||
|
||||
*r_length = str - result;
|
||||
if (r_condition)
|
||||
*r_condition = condition;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Helper for compare_pubkey_string. If BPARSED is set to 0 on
|
||||
* return, an error in ASTR or BSTR was found and further checks are
|
||||
* not possible. */
|
||||
static int
|
||||
compare_pubkey_string_part (const char *astr, const char *bstr_arg,
|
||||
size_t *bparsed)
|
||||
{
|
||||
const char *bstr = bstr_arg;
|
||||
size_t alen, apfxlen, blen, bpfxlen;
|
||||
unsigned int anumber, bnumber;
|
||||
int condition;
|
||||
|
||||
*bparsed = 0;
|
||||
astr = parse_one_algo_string (astr, &apfxlen, &anumber, &alen, &condition);
|
||||
if (!astr)
|
||||
return 0; /* Invalid algorithm name. */
|
||||
bstr = parse_one_algo_string (bstr, &bpfxlen, &bnumber, &blen, &condition);
|
||||
if (!bstr)
|
||||
return 0; /* Invalid algorithm name. */
|
||||
*bparsed = blen + (bstr - bstr_arg);
|
||||
if (apfxlen != bpfxlen || ascii_strncasecmp (astr, bstr, apfxlen))
|
||||
return 0; /* false. */
|
||||
switch (condition)
|
||||
{
|
||||
case 2: return anumber >= bnumber;
|
||||
case 1: return anumber > bnumber;
|
||||
case -1: return anumber < bnumber;
|
||||
case -2: return anumber <= bnumber;
|
||||
}
|
||||
|
||||
return alen == blen && !ascii_strncasecmp (astr, bstr, alen);
|
||||
}
|
||||
|
||||
|
||||
/* Check whether ASTR matches the constraints given by BSTR. ASTR may
|
||||
* be any algo string like "rsa2048", "ed25519" and BSTR may be a
|
||||
* constraint which is in the simplest case just another algo string.
|
||||
* BSTR may have more that one string in which case they are comma
|
||||
* separated and any match will return true. It is possible to prefix
|
||||
* BSTR with ">", ">=", "<=", or "<". That prefix operator is applied
|
||||
* to the number part of the algorithm, i.e. the first sequence of
|
||||
* digits found before end-of-string or a comma. Examples:
|
||||
*
|
||||
* | ASTR | BSTR | result |
|
||||
* |----------+----------------------+--------|
|
||||
* | rsa2048 | rsa2048 | true |
|
||||
* | rsa2048 | >=rsa2048 | true |
|
||||
* | rsa2048 | >rsa2048 | false |
|
||||
* | ed25519 | >rsa1024 | false |
|
||||
* | ed25519 | ed25519 | true |
|
||||
* | nistp384 | >nistp256 | true |
|
||||
* | nistp521 | >=rsa3072, >nistp384 | true |
|
||||
*/
|
||||
int
|
||||
compare_pubkey_string (const char *astr, const char *bstr)
|
||||
{
|
||||
size_t bparsed;
|
||||
int result;
|
||||
|
||||
while (*bstr)
|
||||
{
|
||||
result = compare_pubkey_string_part (astr, bstr, &bparsed);
|
||||
if (result)
|
||||
return 1;
|
||||
if (!bparsed)
|
||||
return 0; /* Syntax error in ASTR or BSTR. */
|
||||
bstr += bparsed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Hash a public key and allow to specify the to be used format.
|
||||
* Note that if the v5 format is requested for a v4 key, a 0x04 as
|
||||
* version is hashed instead of the 0x05. */
|
||||
|
@ -84,6 +84,7 @@ struct weakhash
|
||||
/*-- gpg.c --*/
|
||||
extern int g10_errors_seen;
|
||||
extern int assert_signer_true;
|
||||
extern int assert_pubkey_algo_false;
|
||||
|
||||
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
|
||||
void g10_exit(int rc) __attribute__ ((__noreturn__));
|
||||
@ -494,6 +495,7 @@ int verify_signatures (ctrl_t ctrl, int nfiles, char **files );
|
||||
int verify_files (ctrl_t ctrl, int nfiles, char **files );
|
||||
int gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp);
|
||||
void check_assert_signer_list (const char *mainpkhex, const char *pkhex);
|
||||
void check_assert_pubkey_algo (const char *algostr, const char *pkhex);
|
||||
|
||||
/*-- decrypt.c --*/
|
||||
int decrypt_message (ctrl_t ctrl, const char *filename );
|
||||
|
@ -1876,6 +1876,8 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
const void *extrahash = NULL;
|
||||
size_t extrahashlen = 0;
|
||||
kbnode_t included_keyblock = NULL;
|
||||
char pkstrbuf[PUBKEY_STRING_SIZE] = { 0 };
|
||||
|
||||
|
||||
if (opt.skip_verify)
|
||||
{
|
||||
@ -2409,8 +2411,14 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
show_notation (sig, 0, 2, 0);
|
||||
}
|
||||
|
||||
/* Fill PKSTRBUF with the algostring in case we later need it. */
|
||||
if (pk)
|
||||
pubkey_string (pk, pkstrbuf, sizeof pkstrbuf);
|
||||
|
||||
/* For good signatures print the VALIDSIG status line. */
|
||||
if (!rc && (is_status_enabled () || opt.assert_signer_list) && pk)
|
||||
if (!rc && (is_status_enabled ()
|
||||
|| opt.assert_signer_list
|
||||
|| opt.assert_pubkey_algos) && pk)
|
||||
{
|
||||
char pkhex[MAX_FINGERPRINT_LEN*2+1];
|
||||
char mainpkhex[MAX_FINGERPRINT_LEN*2+1];
|
||||
@ -2432,6 +2440,8 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
mainpkhex);
|
||||
/* Handle the --assert-signer option. */
|
||||
check_assert_signer_list (mainpkhex, pkhex);
|
||||
/* Handle the --assert-pubkey-algo option. */
|
||||
check_assert_pubkey_algo (pkstrbuf, pkhex);
|
||||
}
|
||||
|
||||
/* Print compliance warning for Good signatures. */
|
||||
@ -2464,13 +2474,6 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
|
||||
if (opt.verbose)
|
||||
{
|
||||
char pkstrbuf[PUBKEY_STRING_SIZE];
|
||||
|
||||
if (pk)
|
||||
pubkey_string (pk, pkstrbuf, sizeof pkstrbuf);
|
||||
else
|
||||
*pkstrbuf = 0;
|
||||
|
||||
log_info (_("%s signature, digest algorithm %s%s%s\n"),
|
||||
sig->sig_class==0x00?_("binary"):
|
||||
sig->sig_class==0x01?_("textmode"):_("unknown"),
|
||||
|
@ -241,6 +241,10 @@ struct
|
||||
* modify to be uppercase if they represent a fingerrint */
|
||||
strlist_t assert_signer_list;
|
||||
|
||||
/* A single string with the comma delimited args from
|
||||
* --assert-pubkey_algo. */
|
||||
char *assert_pubkey_algos;
|
||||
|
||||
struct
|
||||
{
|
||||
/* If set, require an 0x19 backsig to be present on signatures
|
||||
|
@ -67,12 +67,3 @@ do_test (int argc, char *argv[])
|
||||
release_kbnode (kb1);
|
||||
xfree (ctrl);
|
||||
}
|
||||
|
||||
int assert_signer_true = 0;
|
||||
|
||||
void
|
||||
check_assert_signer_list (const char *mainpkhex, const char *pkhex)
|
||||
{
|
||||
(void)mainpkhex;
|
||||
(void)pkhex;
|
||||
}
|
||||
|
@ -105,13 +105,3 @@ do_test (int argc, char *argv[])
|
||||
keydb_release (hd2);
|
||||
xfree (ctrl);
|
||||
}
|
||||
|
||||
|
||||
int assert_signer_true = 0;
|
||||
|
||||
void
|
||||
check_assert_signer_list (const char *mainpkhex, const char *pkhex)
|
||||
{
|
||||
(void)mainpkhex;
|
||||
(void)pkhex;
|
||||
}
|
||||
|
129
g10/t-keyid.c
Normal file
129
g10/t-keyid.c
Normal file
@ -0,0 +1,129 @@
|
||||
/* t-keyid.c - Tests for keyid.c.
|
||||
* Copyright (C) 2024 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG 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 General Public License
|
||||
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define LEAN_T_SUPPORT 1
|
||||
|
||||
#define PGM "t-keyid"
|
||||
|
||||
#include "gpg.h"
|
||||
#include "keydb.h"
|
||||
#include "../common/t-support.h"
|
||||
|
||||
|
||||
|
||||
static int verbose;
|
||||
|
||||
|
||||
static void
|
||||
test_compare_pubkey_string (void)
|
||||
{
|
||||
static struct { const char *astr; const char *bstr; int expected; } t[] =
|
||||
{
|
||||
{ "rsa2048" , "rsa2048" , 1 },
|
||||
{ "rsa2048" , ">=rsa2048" , 1 },
|
||||
{ "rsa2048" , ">rsa2048" , 0 },
|
||||
{ "ed25519" , ">rsa1024" , 0 },
|
||||
{ "ed25519" , "ed25519" , 1 },
|
||||
{ "ed25519" , ",,,=ed25519" , 1 },
|
||||
{ "nistp384" , ">nistp256" , 1 },
|
||||
{ "nistp521" , ">=rsa3072, >nistp384", 1 },
|
||||
{ " nistp521" , ">=rsa3072, >nistp384 ", 1 },
|
||||
{ " nistp521 " , " >=rsa3072, >nistp384 ", 1 },
|
||||
{ " =nistp521 " , " >=rsa3072, >nistp384,,", 1 },
|
||||
{ "nistp384" , ">nistp384" , 0 },
|
||||
{ "nistp384" , ">=nistp384" , 1 },
|
||||
{ "brainpoolP384" , ">=brainpoolp256", 1 },
|
||||
{ "brainpoolP384" , ">brainpoolp384" , 0 },
|
||||
{ "brainpoolP384" , ">=brainpoolp384", 1 },
|
||||
{ "brainpoolP256r1", ">brainpoolp256r1", 0 },
|
||||
{ "brainpoolP384r1", ">brainpoolp384r1" , 0 },
|
||||
{ "brainpoolP384r1", ">=brainpoolp384r1", 1 },
|
||||
{ "brainpoolP384r1", ">=brainpoolp384" , 1 },
|
||||
{ "", "", 0}
|
||||
};
|
||||
int idx;
|
||||
int result;
|
||||
|
||||
for (idx=0; idx < DIM(t); idx++)
|
||||
{
|
||||
result = compare_pubkey_string (t[idx].astr, t[idx].bstr);
|
||||
if (result != t[idx].expected)
|
||||
{
|
||||
fail (idx);
|
||||
if (verbose)
|
||||
log_debug ("\"%s\", \"%s\" want %d got %d\n",
|
||||
t[idx].astr, t[idx].bstr, t[idx].expected, result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int last_argc = -1;
|
||||
|
||||
no_exit_on_fail = 1;
|
||||
|
||||
if (argc)
|
||||
{ argc--; argv++; }
|
||||
while (argc && last_argc != argc )
|
||||
{
|
||||
last_argc = argc;
|
||||
if (!strcmp (*argv, "--"))
|
||||
{
|
||||
argc--; argv++;
|
||||
break;
|
||||
}
|
||||
else if (!strcmp (*argv, "--help"))
|
||||
{
|
||||
fputs ("usage: " PGM " [FILE]\n"
|
||||
"Options:\n"
|
||||
" --verbose Print timings etc.\n"
|
||||
" --debug Flyswatter\n"
|
||||
, stdout);
|
||||
exit (0);
|
||||
}
|
||||
else if (!strcmp (*argv, "--verbose"))
|
||||
{
|
||||
verbose++;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--debug"))
|
||||
{
|
||||
verbose += 2;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strncmp (*argv, "--", 2))
|
||||
{
|
||||
fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
test_compare_pubkey_string ();
|
||||
|
||||
return !!errcount;
|
||||
}
|
@ -611,12 +611,3 @@ do_test (int argc, char *argv[])
|
||||
|
||||
xfree (filename);
|
||||
}
|
||||
|
||||
int assert_signer_true = 0;
|
||||
|
||||
void
|
||||
check_assert_signer_list (const char *mainpkhex, const char *pkhex)
|
||||
{
|
||||
(void)mainpkhex;
|
||||
(void)pkhex;
|
||||
}
|
||||
|
@ -43,6 +43,9 @@
|
||||
#include "call-agent.h"
|
||||
|
||||
int g10_errors_seen;
|
||||
int assert_signer_true = 0;
|
||||
int assert_pubkey_algo_false = 0;
|
||||
|
||||
|
||||
|
||||
void
|
||||
@ -580,3 +583,18 @@ impex_filter_getval (void *cookie, const char *propname)
|
||||
(void)propname;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
check_assert_signer_list (const char *mainpkhex, const char *pkhex)
|
||||
{
|
||||
(void)mainpkhex;
|
||||
(void)pkhex;
|
||||
}
|
||||
|
||||
void
|
||||
check_assert_pubkey_algo (const char *algostr, const char *pkhex)
|
||||
{
|
||||
(void)algostr;
|
||||
(void)pkhex;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
33
g10/verify.c
33
g10/verify.c
@ -333,7 +333,7 @@ check_assert_signer_list (const char *mainpkhex, const char *pkhex)
|
||||
assert_signer_true = 1;
|
||||
write_status_text (STATUS_ASSERT_SIGNER, item->d);
|
||||
if (!opt.quiet)
|
||||
log_info ("signer '%s' matched\n", item->d);
|
||||
log_info ("asserted signer '%s'\n", item->d);
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
@ -388,7 +388,7 @@ check_assert_signer_list (const char *mainpkhex, const char *pkhex)
|
||||
assert_signer_true = 1;
|
||||
write_status_text (STATUS_ASSERT_SIGNER, p);
|
||||
if (!opt.quiet)
|
||||
log_info ("signer '%s' matched '%s', line %d\n",
|
||||
log_info ("asserted signer '%s' (%s:%d)\n",
|
||||
p, fname, lnr);
|
||||
goto leave;
|
||||
}
|
||||
@ -405,3 +405,32 @@ check_assert_signer_list (const char *mainpkhex, const char *pkhex)
|
||||
leave:
|
||||
es_fclose (fp);
|
||||
}
|
||||
|
||||
|
||||
/* This function shall be called with the signer's public key
|
||||
* algorithm ALGOSTR iff a signature is fully valid. If the option
|
||||
* --assert-pubkey-algo is active the functions checks whether the
|
||||
* signing key's algo is valid according to that list; in this case a
|
||||
* global flag is set. */
|
||||
void
|
||||
check_assert_pubkey_algo (const char *algostr, const char *pkhex)
|
||||
{
|
||||
if (!opt.assert_pubkey_algos)
|
||||
return; /* Nothing to do. */
|
||||
|
||||
if (compare_pubkey_string (algostr, opt.assert_pubkey_algos))
|
||||
{
|
||||
write_status_strings (STATUS_ASSERT_PUBKEY_ALGO,
|
||||
pkhex, " 1 ", algostr, NULL);
|
||||
if (!opt.quiet)
|
||||
log_info ("asserted signer '%s' with algo %s\n", pkhex, algostr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!opt.quiet)
|
||||
log_info ("denied signer '%s' with algo %s\n", pkhex, algostr);
|
||||
assert_pubkey_algo_false = 1;
|
||||
write_status_strings (STATUS_ASSERT_PUBKEY_ALGO,
|
||||
pkhex, " 0 ", algostr, NULL);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user