diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-02-09 16:00:10 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-02-09 16:00:10 +0900 |
commit | 38e6451f41db54227426835fea3069d721d1a0a5 (patch) | |
tree | aaf6506d5bf0178d9a2561f4f76af6eedf7d1881 /tests | |
parent | 8bffc2850be3e430e7f6faec136d31c6c815f93f (diff) | |
download | gpg2-38e6451f41db54227426835fea3069d721d1a0a5.tar.gz gpg2-38e6451f41db54227426835fea3069d721d1a0a5.tar.bz2 gpg2-38e6451f41db54227426835fea3069d721d1a0a5.zip |
Imported Upstream version 2.1.13upstream/2.1.13
Diffstat (limited to 'tests')
-rw-r--r-- | tests/openpgp/Makefile.am | 4 | ||||
-rwxr-xr-x | tests/openpgp/export.test | 110 | ||||
-rw-r--r-- | tests/openpgp/fake-pinentry.c | 216 |
3 files changed, 314 insertions, 16 deletions
diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index bab0b7d..bb1047d 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -57,6 +57,7 @@ TESTS = version.test mds.test \ import.test ecc.test 4gb-packet.test \ $(sqlite3_dependent_tests) \ gpgtar.test use-exact-key.test default-key.test \ + export.test \ finish.test @@ -123,7 +124,8 @@ CLEANFILES = prepared.stamp x y yy z out err $(data_files) \ *.test.log gpg_dearmor gpg.conf gpg-agent.conf S.gpg-agent \ pubring.gpg pubring.gpg~ pubring.kbx pubring.kbx~ \ secring.gpg pubring.pkr secring.skr \ - gnupg-test.stop random_seed gpg-agent.log tofu.db + gnupg-test.stop random_seed gpg-agent.log tofu.db \ + passphrases clean-local: -rm -rf private-keys-v1.d openpgp-revocs.d tofu.d gpgtar.d diff --git a/tests/openpgp/export.test b/tests/openpgp/export.test new file mode 100755 index 0000000..9776760 --- /dev/null +++ b/tests/openpgp/export.test @@ -0,0 +1,110 @@ +#!/bin/sh + +. $srcdir/defs.inc || exit 3 + +check_exported_public_key() +{ + $GPG --list-packets $1 >$1.packets + grep '^:public key packet:' $1.packets >/dev/null + grep "^ keyid: .*$KEY$" $1.packets >/dev/null + grep '^:user ID packet:' $1.packets >/dev/null + grep "^:signature packet:.*keyid.*$KEY" $1.packets >/dev/null + rm $1.packets +} + +check_armored_public_key() +{ + grep '^-----BEGIN PGP PUBLIC KEY BLOCK-----$' $1 >/dev/null + grep '^-----END PGP PUBLIC KEY BLOCK-----$' $1 >/dev/null + check_exported_public_key $1 +} + +check_exported_private_key() +{ + $GPG --list-packets $1 >$1.packets + grep '^:secret key packet:' $1.packets >/dev/null + grep "^ keyid: .*$KEY$" $1.packets >/dev/null + grep '^:user ID packet:' $1.packets >/dev/null + grep "^:signature packet:.*keyid.*$KEY" $1.packets >/dev/null + rm $1.packets +} + +check_armored_private_key() +{ + grep '^-----BEGIN PGP PRIVATE KEY BLOCK-----$' $1 >/dev/null + grep '^-----END PGP PRIVATE KEY BLOCK-----$' $1 >/dev/null + check_exported_private_key $1 +} + +logfile="`pwd`/pinentry.log" +ppfile="`pwd`/passphrases" +rm -f -- $logfile $ppfile +touch $ppfile + +prepare_passphrase() +{ + echo $* >>$ppfile +} + +prepare_passphrase_confirm() +{ + echo "fake-entry being started to CONFIRM the weak phrase" >>$ppfile +} + +assert_passphrases_consumed() +{ + if test -s $ppfile; then + echo "Expected $ppfile to be empty, but these are enqueued:" >&2 + cat "$ppfile" >&2 + exit 1 + fi + rm -f -- $logfile +} + +export PINENTRY_USER_DATA="--logfile=$logfile --passphrasefile=$ppfile" + +info "Checking key export." +for KEY in D74C5F22 C40FDECF ECABF51D +do + progress $KEY + + $GPG --export $KEY >$KEY.public + check_exported_public_key $KEY.public + rm $KEY.public + + $GPG --armor --export $KEY >$KEY.public + check_armored_public_key $KEY.public + rm $KEY.public + + # test without --armor: + + if [ $KEY = D74C5F22 ]; then + # Key D74C5F22 is protected by a passphrase. Prepare this + # one. Currently, GnuPG does not ask for an export passphrase + # in this case. + prepare_passphrase "$usrpass1" + fi + + $GPG --export-secret-keys $KEY >$KEY.private + check_exported_private_key $KEY.private + rm $KEY.private + + assert_passphrases_consumed + + # test with --armor: + + if [ $KEY = D74C5F22 ]; then + # Key D74C5F22 is protected by a passphrase. Prepare this + # one. Currently, GnuPG does not ask for an export passphrase + # in this case. + prepare_passphrase "$usrpass1" + fi + + $GPG --armor --export-secret-keys $KEY >$KEY.private + check_armored_private_key $KEY.private + rm $KEY.private + + assert_passphrases_consumed +done + +progress_end diff --git a/tests/openpgp/fake-pinentry.c b/tests/openpgp/fake-pinentry.c index b8aa848..a651726 100644 --- a/tests/openpgp/fake-pinentry.c +++ b/tests/openpgp/fake-pinentry.c @@ -21,30 +21,208 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <stdarg.h> + +FILE *log_stream; + +int +reply (const char *fmt, ...) +{ + int result; + va_list ap; + + if (log_stream) + { + fprintf (log_stream, "> "); + va_start (ap, fmt); + vfprintf (log_stream, fmt, ap); + va_end (ap); + } + va_start (ap, fmt); + result = vprintf (fmt, ap); + va_end (ap); + + return result; +} + +/* Return the first line from FNAME, removing it from the file. */ +char * +get_passphrase (const char *fname) +{ + char *passphrase = NULL; + size_t fname_len; + char *fname_new; + FILE *source, *sink; + char linebuf[80]; + + fname_len = strlen (fname); + fname_new = malloc (fname_len + 5); + if (fname_new == NULL) + { + perror ("malloc"); + exit (1); + } + snprintf (fname_new, fname_len + 5, "%s.new", fname); + + source = fopen (fname, "r"); + if (! source) + { + perror (fname); + exit (1); + } + + sink = fopen (fname_new, "w"); + if (! sink) + { + perror (fname_new); + exit (1); + } + + while (fgets (linebuf, sizeof linebuf, source)) + { + linebuf[sizeof linebuf - 1] = 0; + if (passphrase == NULL) + { + passphrase = strdup (linebuf); + if (passphrase == NULL) + { + perror ("strdup"); + exit (1); + } + } + else + fputs (linebuf, sink); + } + + if (ferror (source)) + { + perror (fname); + exit (1); + } + + if (ferror (sink)) + { + perror (fname_new); + exit (1); + } + + fclose (source); + fclose (sink); + rename (fname_new, fname); + return passphrase; +} + + +#define spacep(p) (*(p) == ' ' || *(p) == '\t') + +/* Skip over options in LINE. + + Blanks after the options are also removed. Options are indicated + by two leading dashes followed by a string consisting of non-space + characters. The special option "--" indicates an explicit end of + options; all what follows will not be considered an option. The + first no-option string also indicates the end of option parsing. */ +char * +skip_options (const char *line) +{ + while (spacep (line)) + line++; + while (*line == '-' && line[1] == '-') + { + while (*line && !spacep (line)) + line++; + while (spacep (line)) + line++; + } + return (char*) line; +} + + +/* Return a pointer to the argument of the option with NAME. If such + an option is not given, NULL is returned. */ +char * +option_value (const char *line, const char *name) +{ + char *s; + int n = strlen (name); + + s = strstr (line, name); + if (s && s >= skip_options (line)) + return NULL; + if (s && (s == line || spacep (s-1)) + && s[n] && (spacep (s+n) || s[n] == '=')) + { + s += n + 1; + s += strspn (s, " "); + if (*s && !spacep(s)) + return s; + } + return NULL; +} int main (int argc, char **argv) { - static char *passphrase; - char *p; + char *args; + char *logfile; + char *passphrasefile; + char *passphrase; + /* We get our options via PINENTRY_USER_DATA. */ (void) argc, (void) argv; setvbuf (stdin, NULL, _IOLBF, BUFSIZ); setvbuf (stdout, NULL, _IOLBF, BUFSIZ); - if (!passphrase) + args = getenv ("PINENTRY_USER_DATA"); + if (! args) + args = ""; + + logfile = option_value (args, "--logfile"); + if (logfile) + { + char *p = logfile, more; + while (*p && ! spacep (p)) + p++; + more = !! *p; + *p = 0; + args = more ? p+1 : p; + + log_stream = fopen (logfile, "a"); + if (! log_stream) + { + perror (logfile); + return 1; + } + } + + passphrasefile = option_value (args, "--passphrasefile"); + if (passphrasefile) { - passphrase = getenv ("PINENTRY_USER_DATA"); - if (!passphrase) - passphrase = ""; - for (p=passphrase; *p; p++) - if (*p == '\r' || *p == '\n') - *p = '.'; - printf ("# Passphrase='%s'\n", passphrase); + char *p = passphrasefile, more; + while (*p && ! spacep (p)) + p++; + more = !! *p; + *p = 0; + args = more ? p+1 : p; + + passphrase = get_passphrase (passphrasefile); + if (! passphrase) + { + reply ("# Passphrasefile '%s' is empty. Terminating.\n", + passphrasefile); + return 1; + } + + p = passphrase + strlen (passphrase) - 1; + if (*p == '\n') + *p = 0; } + else + passphrase = skip_options (args); - printf ("OK - what's up?\n"); + reply ("# fake-pinentry started. Passphrase='%s'.\n", passphrase); + reply ("OK - what's up?\n"); while (! feof (stdin)) { @@ -53,15 +231,23 @@ main (int argc, char **argv) if (fgets (buffer, sizeof buffer, stdin) == NULL) break; + if (log_stream) + fprintf (log_stream, "< %s", buffer); + if (strncmp (buffer, "GETPIN", 6) == 0) - printf ("D %s\nOK\n", passphrase); + reply ("D %s\n", passphrase); else if (strncmp (buffer, "BYE", 3) == 0) { - printf ("OK\n"); + reply ("OK\n"); break; } - else - printf ("OK\n"); + + reply ("OK\n"); } + + reply ("# Connection terminated.\n"); + if (log_stream) + fclose (log_stream); + return 0; } |