From a035938216c39230e1476925119d3cff76932e7e Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 11 May 2023 19:18:21 +0900 Subject: [PATCH 001/869] common,agent,gpg,dirmngr,g13,scd,tests,tools: New spawn function. * common/exechelp-posix.c (do_exec, gnupg_spawn_process): Remove. (check_syscall_func, pre_syscall, post_syscall) : New. (do_create_socketpair, posix_open_null, call_spawn_cb): New. (my_exec, spawn_detached, gnupg_spawn_helper): New. (gnupg_process_spawn, process_kill, gnupg_process_terminate): New. (gnupg_process_get_fds, gnupg_process_get_streams): New. (process_vctl, gnupg_process_ctl): New. (gnupg_process_wait, gnupg_process_release): New. (gnupg_process_wait_list): New. * common/exechelp-w32.c: Add definition of _WIN32_WINNT as 0x600. (check_syscall_func, pre_syscall, post_syscall): New. (gnupg_spawn_process): Remove. (check_windows_version): New. (spawn_detached, gnupg_spawn_helper, gnupg_process_spawn): New. (gnupg_process_get_fds, gnupg_process_get_streams): New. (process_kill, process_vctl, gnupg_process_ctl): New. (gnupg_process_wait, gnupg_process_terminate): New. (gnupg_process_release, gnupg_process_wait_list): New. * common/exechelp.h: Re-write for new API. * common/exectool.c (gnupg_exec_tool_stream): Follow the change. * common/asshelp.c (start_new_service): Likewise. * agent/genkey.c (do_check_passphrase_pattern): Likewise. * dirmngr/ldap-wrapper.c (struct wrapper_context_s): Use PROC. (destroy_wrapper): Follow the change of API. (read_log_data): Follow the change of API, use printable_pid. (ldap_reaper_thread, ldap_wrapper_release_context): Likewise. (ldap_wrapper_connection_cleanup, ldap_wrapper): Likewise. * g10/photoid.c (run_with_pipe): Follow the change of API. (show_photo): Likewise. * g13/be-encfs.c (run_umount_helper): Likewise. (run_encfs_tool): Likewise. * g13/g13.c: Add including ./common/exechelp.h. * g13/mount.c: Likewise. * g13/runner.c: Follow the change of API. * g13/runner.h: Follow the change of API. * scd/app.c (setup_env): New. (report_change): Follow the change of API. * tests/gpgscm/ffi.c (proc_object_finalize): New. (proc_object_to_string): New. (proc_wrap, proc_unwrap): New. (do_spawn_process): Remove. (do_process_spawn): New. (setup_std_fds): New. (do_spawn_process_fd): Remove. (do_process_spawn_fd): New. (do_wait_process): Remove. (do_process_wait): New. (do_wait_processes): Remove. * tests/gpgscm/t-child.scm: Follow the change of API. * tests/gpgscm/tests.scm: Likewise. * tests/openpgp/defs.scm: Likewise. * tests/tpm2dtests/defs.scm: Likewise. * tools/gpg-card.c: Likewise. * tools/gpgconf-comp.c: Likewise. * tools/gpgconf.c: Likewise. * tools/gpgtar-create.c: Likewise. * tools/gpgtar-extract.c: Likewise. * tools/gpgtar-list.c: Likewise. -- GnuPG-bug-id: 6275 Signed-off-by: NIIBE Yutaka --- agent/genkey.c | 18 +- common/asshelp.c | 14 +- common/exechelp-posix.c | 1109 ++++++++++++++++-------------- common/exechelp-w32.c | 1342 +++++++++++++++++++++---------------- common/exechelp.h | 201 +++--- common/exectool.c | 40 +- dirmngr/ldap-wrapper.c | 79 ++- g10/photoid.c | 42 +- g13/be-encfs.c | 63 +- g13/g13.c | 1 + g13/mount.c | 3 +- g13/runner.c | 36 +- g13/runner.h | 2 +- scd/app.c | 21 +- tests/gpgscm/ffi.c | 222 +++--- tests/gpgscm/t-child.scm | 39 +- tests/gpgscm/tests.scm | 66 +- tests/openpgp/defs.scm | 7 +- tests/tpm2dtests/defs.scm | 7 +- tools/gpg-card.c | 16 +- tools/gpgconf-comp.c | 115 ++-- tools/gpgconf.c | 18 +- tools/gpgtar-create.c | 33 +- tools/gpgtar-extract.c | 30 +- tools/gpgtar-list.c | 33 +- 25 files changed, 1936 insertions(+), 1621 deletions(-) diff --git a/agent/genkey.c b/agent/genkey.c index 7660443ca..563407253 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -99,7 +99,7 @@ do_check_passphrase_pattern (ctrl_t ctrl, const char *pw, unsigned int flags) const char *pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CHECK_PATTERN); estream_t stream_to_check_pattern = NULL; const char *argv[10]; - pid_t pid; + gnupg_process_t proc; int result, i; const char *pattern; char *patternfname; @@ -142,11 +142,17 @@ do_check_passphrase_pattern (ctrl_t ctrl, const char *pw, unsigned int flags) argv[i] = NULL; log_assert (i < sizeof argv); - if (gnupg_spawn_process (pgmname, argv, NULL, 0, - &stream_to_check_pattern, NULL, NULL, &pid)) + if (gnupg_process_spawn (pgmname, argv, + GNUPG_PROCESS_STDIN_PIPE, + NULL, NULL, &proc)) result = 1; /* Execute error - assume password should no be used. */ else { + int status; + + gnupg_process_get_streams (proc, 0, &stream_to_check_pattern, + NULL, NULL); + es_set_binary (stream_to_check_pattern); if (es_fwrite (pw, strlen (pw), 1, stream_to_check_pattern) != 1) { @@ -157,11 +163,13 @@ do_check_passphrase_pattern (ctrl_t ctrl, const char *pw, unsigned int flags) else es_fflush (stream_to_check_pattern); es_fclose (stream_to_check_pattern); - if (gnupg_wait_process (pgmname, pid, 1, NULL)) + gnupg_process_wait (proc, 1); + gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &status); + if (status) result = 1; /* Helper returned an error - probably a match. */ else result = 0; /* Success; i.e. no match. */ - gnupg_release_process (pid); + gnupg_process_release (proc); } xfree (patternfname); diff --git a/common/asshelp.c b/common/asshelp.c index eb3e41bf5..8b3df2a4b 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -523,16 +523,12 @@ start_new_service (assuan_context_t *r_ctx, && assuan_socket_connect (ctx, sockname, 0, connect_flags)) { #ifdef HAVE_W32_SYSTEM - err = gnupg_spawn_process_detached (program? program : program_name, - argv, NULL); + err = gnupg_process_spawn (program? program : program_name, argv, + GNUPG_PROCESS_DETACHED, + NULL, NULL, NULL); #else /*!W32*/ - pid_t pid; - - err = gnupg_spawn_process_fd (program? program : program_name, - argv, -1, -1, -1, &pid); - if (!err) - err = gnupg_wait_process (program? program : program_name, - pid, 1, NULL); + err = gnupg_process_spawn (program? program : program_name, argv, + 0, NULL, NULL, NULL); #endif /*!W32*/ if (err) log_error ("failed to start %s '%s': %s\n", diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index fa613449d..7b20a3796 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -273,73 +273,6 @@ get_all_open_fds (void) } -/* The exec core used right after the fork. This will never return. */ -static void -do_exec (const char *pgmname, const char *argv[], - int fd_in, int fd_out, int fd_err, - int *except, unsigned int flags) -{ - char **arg_list; - int i, j; - int fds[3]; - int nodevnull[3]; - - fds[0] = fd_in; - fds[1] = fd_out; - fds[2] = fd_err; - - nodevnull[0] = !!(flags & GNUPG_SPAWN_KEEP_STDIN); - nodevnull[1] = !!(flags & GNUPG_SPAWN_KEEP_STDOUT); - nodevnull[2] = !!(flags & GNUPG_SPAWN_KEEP_STDERR); - - /* Create the command line argument array. */ - i = 0; - if (argv) - while (argv[i]) - i++; - arg_list = xcalloc (i+2, sizeof *arg_list); - arg_list[0] = strrchr (pgmname, '/'); - if (arg_list[0]) - arg_list[0]++; - else - arg_list[0] = xstrdup (pgmname); - if (argv) - for (i=0,j=1; argv[i]; i++, j++) - arg_list[j] = (char*)argv[i]; - - /* Assign /dev/null to unused FDs. */ - for (i=0; i <= 2; i++) - { - if (nodevnull[i]) - continue; - if (fds[i] == -1) - { - fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY); - if (fds[i] == -1) - log_fatal ("failed to open '%s': %s\n", - "/dev/null", strerror (errno)); - } - } - - /* Connect the standard files. */ - for (i=0; i <= 2; i++) - { - if (nodevnull[i]) - continue; - if (fds[i] != i && dup2 (fds[i], i) == -1) - log_fatal ("dup2 std%s failed: %s\n", - i==0?"in":i==1?"out":"err", strerror (errno)); - } - - /* Close all other files. */ - close_all_fds (3, except); - - execv (pgmname, arg_list); - /* No way to print anything, as we have closed all streams. */ - _exit (127); -} - - static gpg_error_t do_create_pipe (int filedes[2]) { @@ -431,453 +364,160 @@ gnupg_close_pipe (int fd) close (fd); } +#include -/* Fork and exec the PGMNAME, see exechelp.h for details. */ -gpg_error_t -gnupg_spawn_process (const char *pgmname, const char *argv[], - int *except, unsigned int flags, - estream_t *r_infp, - estream_t *r_outfp, - estream_t *r_errfp, - pid_t *pid) -{ - gpg_error_t err; - int inpipe[2] = {-1, -1}; - int outpipe[2] = {-1, -1}; - int errpipe[2] = {-1, -1}; - estream_t infp = NULL; - estream_t outfp = NULL; - estream_t errfp = NULL; - int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK); - - if (r_infp) - *r_infp = NULL; - if (r_outfp) - *r_outfp = NULL; - if (r_errfp) - *r_errfp = NULL; - *pid = (pid_t)(-1); /* Always required. */ - - if (r_infp) - { - err = create_pipe_and_estream (inpipe, &infp, 1, nonblock); - if (err) - return err; - } - - if (r_outfp) - { - err = create_pipe_and_estream (outpipe, &outfp, 0, nonblock); - if (err) - { - if (infp) - es_fclose (infp); - else if (inpipe[1] != -1) - close (inpipe[1]); - if (inpipe[0] != -1) - close (inpipe[0]); - - return err; - } - } - - if (r_errfp) - { - err = create_pipe_and_estream (errpipe, &errfp, 0, nonblock); - if (err) - { - if (infp) - es_fclose (infp); - else if (inpipe[1] != -1) - close (inpipe[1]); - if (inpipe[0] != -1) - close (inpipe[0]); - - if (outfp) - es_fclose (outfp); - else if (outpipe[0] != -1) - close (outpipe[0]); - if (outpipe[1] != -1) - close (outpipe[1]); - - return err; - } - } - - - *pid = fork (); - if (*pid == (pid_t)(-1)) - { - err = my_error_from_syserror (); - log_error (_("error forking process: %s\n"), gpg_strerror (err)); - - if (infp) - es_fclose (infp); - else if (inpipe[1] != -1) - close (inpipe[1]); - if (inpipe[0] != -1) - close (inpipe[0]); - - if (outfp) - es_fclose (outfp); - else if (outpipe[0] != -1) - close (outpipe[0]); - if (outpipe[1] != -1) - close (outpipe[1]); - - if (errfp) - es_fclose (errfp); - else if (errpipe[0] != -1) - close (errpipe[0]); - if (errpipe[1] != -1) - close (errpipe[1]); - return err; - } - - if (!*pid) - { - /* This is the child. */ - gcry_control (GCRYCTL_TERM_SECMEM); - es_fclose (infp); - es_fclose (outfp); - es_fclose (errfp); - do_exec (pgmname, argv, inpipe[0], outpipe[1], errpipe[1], - except, flags); - /*NOTREACHED*/ - } - - /* This is the parent. */ - if (inpipe[0] != -1) - close (inpipe[0]); - if (outpipe[1] != -1) - close (outpipe[1]); - if (errpipe[1] != -1) - close (errpipe[1]); - - if (r_infp) - *r_infp = infp; - if (r_outfp) - *r_outfp = outfp; - if (r_errfp) - *r_errfp = errfp; - - return 0; -} - - - -/* Simplified version of gnupg_spawn_process. This function forks and - then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout - and ERRFD to stderr (any of them may be -1 to connect them to - /dev/null). The arguments for the process are expected in the NULL - terminated array ARGV. The program name itself should not be - included there. Calling gnupg_wait_process is required. - - Returns 0 on success or an error code. */ -gpg_error_t -gnupg_spawn_process_fd (const char *pgmname, const char *argv[], - int infd, int outfd, int errfd, pid_t *pid) -{ - gpg_error_t err; - - *pid = fork (); - if (*pid == (pid_t)(-1)) - { - err = my_error_from_syserror (); - log_error (_("error forking process: %s\n"), strerror (errno)); - return err; - } - - if (!*pid) - { - gcry_control (GCRYCTL_TERM_SECMEM); - /* Run child. */ - do_exec (pgmname, argv, infd, outfd, errfd, NULL, 0); - /*NOTREACHED*/ - } - - return 0; -} - - - - -/* Waiting for child processes. - - waitpid(2) may return information about terminated children that we - did not yet request, and there is no portable way to wait for a - specific set of children. - - As a workaround, we store the results of children for later use. - - XXX: This assumes that PIDs are not reused too quickly. */ - -struct terminated_child -{ +struct gnupg_process { + const char *pgmname; + unsigned int terminated :1; /* or detached */ + unsigned int flags; pid_t pid; - int exitcode; - struct terminated_child *next; + int fd_in; + int fd_out; + int fd_err; + int wstatus; }; -struct terminated_child *terminated_children; +static int gnupg_process_syscall_func_initialized; +/* Functions called before and after blocking syscalls. */ +static void (*pre_syscall_func) (void); +static void (*post_syscall_func) (void); -static gpg_error_t -store_result (pid_t pid, int exitcode) +static void +check_syscall_func (void) { - struct terminated_child *c; - - c = xtrymalloc (sizeof *c); - if (c == NULL) - return gpg_err_code_from_syserror (); - - c->pid = pid; - c->exitcode = exitcode; - c->next = terminated_children; - terminated_children = c; - - return 0; + if (!gnupg_process_syscall_func_initialized) + { + gpgrt_get_syscall_clamp (&pre_syscall_func, &post_syscall_func); + gnupg_process_syscall_func_initialized = 1; + } } +static void +pre_syscall (void) +{ + if (pre_syscall_func) + pre_syscall_func (); +} + +static void +post_syscall (void) +{ + if (post_syscall_func) + post_syscall_func (); +} + + +static gpg_err_code_t +do_create_socketpair (int filedes[2]) +{ + gpg_error_t err = 0; + + pre_syscall (); + if (socketpair (AF_LOCAL, SOCK_STREAM, 0, filedes) == -1) + { + err = gpg_err_code_from_syserror (); + filedes[0] = filedes[1] = -1; + } + post_syscall (); + + return err; +} static int -get_result (pid_t pid, int *r_exitcode) +posix_open_null (int for_write) { - struct terminated_child *c, **prevp; + int fd; - for (prevp = &terminated_children, c = terminated_children; - c; - prevp = &c->next, c = c->next) - if (c->pid == pid) + fd = open ("/dev/null", for_write? O_WRONLY : O_RDONLY); + if (fd == -1) + log_fatal ("failed to open '/dev/null': %s\n", strerror (errno)); + return fd; +} + +static void +call_spawn_cb (struct spawn_cb_arg *sca, + int fd_in, int fd_out, int fd_err, + void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) +{ + sca->fds[0] = fd_in; + sca->fds[1] = fd_out; + sca->fds[2] = fd_err; + sca->except_fds = NULL; + sca->arg = spawn_cb_arg; + if (spawn_cb) + (*spawn_cb) (sca); +} + +static void +my_exec (const char *pgmname, const char *argv[], struct spawn_cb_arg *sca) +{ + int i; + + /* Assign /dev/null to unused FDs. */ + for (i = 0; i <= 2; i++) + if (sca->fds[i] == -1) + sca->fds[i] = posix_open_null (i); + + /* Connect the standard files. */ + for (i = 0; i <= 2; i++) + if (sca->fds[i] != i) { - *prevp = c->next; - *r_exitcode = c->exitcode; - xfree (c); - return 1; + if (dup2 (sca->fds[i], i) == -1) + log_fatal ("dup2 std%s failed: %s\n", + i==0?"in":i==1?"out":"err", strerror (errno)); + /* + * We don't close sca.fds[i] here, but close them by + * close_all_fds. Note that there may be same one in three of + * sca->fds[i]. + */ } - return 0; + /* Close all other files. */ + close_all_fds (3, sca->except_fds); + + execv (pgmname, (char *const *)argv); + /* No way to print anything, as we have may have closed all streams. */ + _exit (127); } - -/* See exechelp.h for a description. */ -gpg_error_t -gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) -{ - gpg_err_code_t ec; - int i, status; - - if (r_exitcode) - *r_exitcode = -1; - - if (pid == (pid_t)(-1)) - return gpg_error (GPG_ERR_INV_VALUE); - -#ifdef USE_NPTH - i = npth_waitpid (pid, &status, hang? 0:WNOHANG); -#else - while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1) - && errno == EINTR); -#endif - - if (i == (pid_t)(-1)) - { - ec = gpg_err_code_from_errno (errno); - log_error (_("waiting for process %d to terminate failed: %s\n"), - (int)pid, strerror (errno)); - } - else if (!i) - { - ec = GPG_ERR_TIMEOUT; /* Still running. */ - } - else if (WIFEXITED (status) && WEXITSTATUS (status) == 127) - { - log_error (_("error running '%s': probably not installed\n"), pgmname); - ec = GPG_ERR_CONFIGURATION; - } - else if (WIFEXITED (status) && WEXITSTATUS (status)) - { - if (!r_exitcode) - log_error (_("error running '%s': exit status %d\n"), pgmname, - WEXITSTATUS (status)); - else - *r_exitcode = WEXITSTATUS (status); - ec = GPG_ERR_GENERAL; - } - else if (!WIFEXITED (status)) - { - log_error (_("error running '%s': terminated\n"), pgmname); - ec = GPG_ERR_GENERAL; - } - else - { - if (r_exitcode) - *r_exitcode = 0; - ec = 0; - } - - return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec); -} - -/* See exechelp.h for a description. */ -gpg_error_t -gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, - int hang, int *r_exitcodes) -{ - gpg_err_code_t ec = 0; - size_t i, left; - int *dummy = NULL; - - if (r_exitcodes == NULL) - { - dummy = r_exitcodes = xtrymalloc (sizeof *r_exitcodes * count); - if (dummy == NULL) - return gpg_err_code_from_syserror (); - } - - for (i = 0, left = count; i < count; i++) - { - int status = -1; - - /* Skip invalid PID. */ - if (pids[i] == (pid_t)(-1)) - { - r_exitcodes[i] = -1; - left -= 1; - continue; - } - - /* See if there was a previously stored result for this pid. */ - if (get_result (pids[i], &status)) - left -= 1; - - r_exitcodes[i] = status; - } - - while (left > 0) - { - pid_t pid; - int status; - -#ifdef USE_NPTH - pid = npth_waitpid (-1, &status, hang ? 0 : WNOHANG); -#else - while ((pid = waitpid (-1, &status, hang ? 0 : WNOHANG)) == (pid_t)(-1) - && errno == EINTR); -#endif - - if (pid == (pid_t)(-1)) - { - ec = gpg_err_code_from_errno (errno); - log_error (_("waiting for processes to terminate failed: %s\n"), - strerror (errno)); - break; - } - else if (!pid) - { - ec = GPG_ERR_TIMEOUT; /* Still running. */ - break; - } - else - { - for (i = 0; i < count; i++) - if (pid == pids[i]) - break; - - if (i == count) - { - /* No match, store this result. */ - ec = store_result (pid, status); - if (ec) - break; - continue; - } - - /* Process PIDS[i] died. */ - if (r_exitcodes[i] != (pid_t) -1) - { - log_error ("PID %d was reused", pid); - ec = GPG_ERR_GENERAL; - break; - } - - left -= 1; - r_exitcodes[i] = status; - } - } - - for (i = 0; i < count; i++) - { - if (r_exitcodes[i] == -1) - continue; - - if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i]) == 127) - { - log_error (_("error running '%s': probably not installed\n"), - pgmnames[i]); - ec = GPG_ERR_CONFIGURATION; - } - else if (WIFEXITED (r_exitcodes[i]) && WEXITSTATUS (r_exitcodes[i])) - { - if (dummy) - log_error (_("error running '%s': exit status %d\n"), - pgmnames[i], WEXITSTATUS (r_exitcodes[i])); - else - r_exitcodes[i] = WEXITSTATUS (r_exitcodes[i]); - ec = GPG_ERR_GENERAL; - } - else if (!WIFEXITED (r_exitcodes[i])) - { - log_error (_("error running '%s': terminated\n"), pgmnames[i]); - ec = GPG_ERR_GENERAL; - } - } - - xfree (dummy); - return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec); -} - - - -void -gnupg_release_process (pid_t pid) -{ - (void)pid; -} - - -/* Spawn a new process and immediately detach from it. The name of - the program to exec is PGMNAME and its arguments are in ARGV (the - programname is automatically passed as first argument). - Environment strings in ENVP are set. An error is returned if - pgmname is not executable; to make this work it is necessary to - provide an absolute file name. All standard file descriptors are - connected to /dev/null. */ -gpg_error_t -gnupg_spawn_process_detached (const char *pgmname, const char *argv[], - const char *envp[] ) +static gpg_err_code_t +spawn_detached (const char *pgmname, const char *argv[], + void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) { gpg_err_code_t ec; pid_t pid; - int i; + /* FIXME: Is this GnuPG specific or should we keep it. */ if (getuid() != geteuid()) - return my_error (GPG_ERR_BUG); + { + xfree (argv); + return GPG_ERR_BUG; + } - if ((ec = gnupg_access (pgmname, X_OK))) - return gpg_err_make (default_errsource, ec); + if (access (pgmname, X_OK)) + { + ec = gpg_err_code_from_syserror (); + xfree (argv); + return ec; + } + pre_syscall (); pid = fork (); + post_syscall (); if (pid == (pid_t)(-1)) { - log_error (_("error forking process: %s\n"), strerror (errno)); - return my_error_from_syserror (); + ec = gpg_err_code_from_syserror (); + log_error (_("error forking process: %s\n"), gpg_strerror (ec)); + xfree (argv); + return ec; } + if (!pid) { pid_t pid2; + struct spawn_cb_arg sca; - gcry_control (GCRYCTL_TERM_SECMEM); if (setsid() == -1 || chdir ("/")) _exit (1); @@ -887,31 +527,506 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], if (pid2) _exit (0); /* Let the parent exit immediately. */ - if (envp) - for (i=0; envp[i]; i++) - putenv (xstrdup (envp[i])); - - do_exec (pgmname, argv, -1, -1, -1, NULL, 0); + call_spawn_cb (&sca, -1, -1, -1, spawn_cb, spawn_cb_arg); + my_exec (pgmname, argv, &sca); /*NOTREACHED*/ } + pre_syscall (); if (waitpid (pid, NULL, 0) == -1) - log_error ("waitpid failed in gnupg_spawn_process_detached: %s", - strerror (errno)); + { + post_syscall (); + ec = gpg_err_code_from_syserror (); + log_error ("waitpid failed in gpgrt_spawn_process_detached: %s", + gpg_strerror (ec)); + return ec; + } + else + post_syscall (); return 0; } - -/* Kill a process; that is send an appropriate signal to the process. - gnupg_wait_process must be called to actually remove the process - from the system. An invalid PID is ignored. */ void -gnupg_kill_process (pid_t pid) +gnupg_spawn_helper (struct spawn_cb_arg *sca) { - if (pid != (pid_t)(-1)) - { - kill (pid, SIGTERM); - } + int *user_except = sca->arg; + sca->except_fds = user_except; +} + +gpg_err_code_t +gnupg_process_spawn (const char *pgmname, const char *argv1[], + unsigned int flags, + void (*spawn_cb) (struct spawn_cb_arg *), + void *spawn_cb_arg, + gnupg_process_t *r_process) +{ + gpg_err_code_t ec; + gnupg_process_t process; + int fd_in[2]; + int fd_out[2]; + int fd_err[2]; + pid_t pid; + const char **argv; + int i, j; + + check_syscall_func (); + + if (r_process) + *r_process = NULL; + + /* Create the command line argument array. */ + i = 0; + if (argv1) + while (argv1[i]) + i++; + argv = xtrycalloc (i+2, sizeof *argv); + if (!argv) + return gpg_err_code_from_syserror (); + argv[0] = strrchr (pgmname, '/'); + if (argv[0]) + argv[0]++; + else + argv[0] = pgmname; + + if (argv1) + for (i=0, j=1; argv1[i]; i++, j++) + argv[j] = argv1[i]; + + if ((flags & GNUPG_PROCESS_DETACHED)) + { + if ((flags & GNUPG_PROCESS_STDFDS_SETTING)) + { + xfree (argv); + return GPG_ERR_INV_FLAG; + } + + /* In detached case, it must be no R_PROCESS. */ + if (r_process) + { + xfree (argv); + return GPG_ERR_INV_ARG; + } + + return spawn_detached (pgmname, argv, spawn_cb, spawn_cb_arg); + } + + process = xtrycalloc (1, sizeof (struct gnupg_process)); + if (process == NULL) + { + xfree (argv); + return gpg_err_code_from_syserror (); + } + + process->pgmname = pgmname; + process->flags = flags; + + if ((flags & GNUPG_PROCESS_STDINOUT_SOCKETPAIR)) + { + ec = do_create_socketpair (fd_in); + if (ec) + { + xfree (process); + xfree (argv); + return ec; + } + fd_out[0] = dup (fd_in[0]); + fd_out[1] = dup (fd_in[1]); + } + else + { + if ((flags & GNUPG_PROCESS_STDIN_PIPE)) + { + ec = do_create_pipe (fd_in); + if (ec) + { + xfree (process); + xfree (argv); + return ec; + } + } + else if ((flags & GNUPG_PROCESS_STDIN_KEEP)) + { + fd_in[0] = 0; + fd_in[1] = -1; + } + else + { + fd_in[0] = -1; + fd_in[1] = -1; + } + + if ((flags & GNUPG_PROCESS_STDOUT_PIPE)) + { + ec = do_create_pipe (fd_out); + if (ec) + { + if (fd_in[0] >= 0 && fd_in[0] != 0) + close (fd_in[0]); + if (fd_in[1] >= 0) + close (fd_in[1]); + xfree (process); + xfree (argv); + return ec; + } + } + else if ((flags & GNUPG_PROCESS_STDOUT_KEEP)) + { + fd_out[0] = -1; + fd_out[1] = 1; + } + else + { + fd_out[0] = -1; + fd_out[1] = -1; + } + } + + if ((flags & GNUPG_PROCESS_STDERR_PIPE)) + { + ec = do_create_pipe (fd_err); + if (ec) + { + if (fd_in[0] >= 0 && fd_in[0] != 0) + close (fd_in[0]); + if (fd_in[1] >= 0) + close (fd_in[1]); + if (fd_out[0] >= 0) + close (fd_out[0]); + if (fd_out[1] >= 0 && fd_out[1] != 1) + close (fd_out[1]); + xfree (process); + xfree (argv); + return ec; + } + } + else if ((flags & GNUPG_PROCESS_STDERR_KEEP)) + { + fd_err[0] = -1; + fd_err[1] = 2; + } + else + { + fd_err[0] = -1; + fd_err[1] = -1; + } + + pre_syscall (); + pid = fork (); + post_syscall (); + if (pid == (pid_t)(-1)) + { + ec = gpg_err_code_from_syserror (); + log_error (_("error forking process: %s\n"), gpg_strerror (ec)); + if (fd_in[0] >= 0 && fd_in[0] != 0) + close (fd_in[0]); + if (fd_in[1] >= 0) + close (fd_in[1]); + if (fd_out[0] >= 0) + close (fd_out[0]); + if (fd_out[1] >= 0 && fd_out[1] != 1) + close (fd_out[1]); + if (fd_err[0] >= 0) + close (fd_err[0]); + if (fd_err[1] >= 0 && fd_err[1] != 2) + close (fd_err[1]); + xfree (process); + xfree (argv); + return ec; + } + + if (!pid) + { + struct spawn_cb_arg sca; + + if (fd_in[1] >= 0) + close (fd_in[1]); + if (fd_out[0] >= 0) + close (fd_out[0]); + if (fd_err[0] >= 0) + close (fd_err[0]); + + call_spawn_cb (&sca, fd_in[0], fd_out[1], fd_err[1], + spawn_cb, spawn_cb_arg); + + /* Run child. */ + my_exec (pgmname, argv, &sca); + /*NOTREACHED*/ + } + + xfree (argv); + process->pid = pid; + + if (fd_in[0] >= 0 && fd_in[0] != 0) + close (fd_in[0]); + if (fd_out[1] >= 0 && fd_out[1] != 1) + close (fd_out[1]); + if (fd_err[1] >= 0 && fd_err[1] != 2) + close (fd_err[1]); + process->fd_in = fd_in[1]; + process->fd_out = fd_out[0]; + process->fd_err = fd_err[0]; + process->wstatus = -1; + process->terminated = 0; + + if (r_process == NULL) + { + ec = gnupg_process_wait (process, 1); + gnupg_process_release (process); + return ec; + } + + *r_process = process; + return 0; +} + +static gpg_err_code_t +process_kill (gnupg_process_t process, int sig) +{ + gpg_err_code_t ec = 0; + pid_t pid = process->pid; + + pre_syscall (); + if (kill (pid, sig) < 0) + ec = gpg_err_code_from_syserror (); + post_syscall (); + return ec; +} + +gpg_err_code_t +gnupg_process_terminate (gnupg_process_t process) +{ + return process_kill (process, SIGTERM); +} + +gpg_err_code_t +gnupg_process_get_fds (gnupg_process_t process, unsigned int flags, + int *r_fd_in, int *r_fd_out, int *r_fd_err) +{ + (void)flags; + if (r_fd_in) + { + *r_fd_in = process->fd_in; + process->fd_in = -1; + } + if (r_fd_out) + { + *r_fd_out = process->fd_out; + process->fd_out = -1; + } + if (r_fd_err) + { + *r_fd_err = process->fd_err; + process->fd_err = -1; + } + + return 0; +} + +gpg_err_code_t +gnupg_process_get_streams (gnupg_process_t process, unsigned int flags, + gpgrt_stream_t *r_fp_in, gpgrt_stream_t *r_fp_out, + gpgrt_stream_t *r_fp_err) +{ + int nonblock = (flags & GNUPG_PROCESS_STREAM_NONBLOCK)? 1: 0; + + if (r_fp_in) + { + *r_fp_in = es_fdopen (process->fd_in, nonblock? "w,nonblock" : "w"); + process->fd_in = -1; + } + if (r_fp_out) + { + *r_fp_out = es_fdopen (process->fd_out, nonblock? "r,nonblock" : "r"); + process->fd_out = -1; + } + if (r_fp_err) + { + *r_fp_err = es_fdopen (process->fd_err, nonblock? "r,nonblock" : "r"); + process->fd_err = -1; + } + return 0; +} + +static gpg_err_code_t +process_vctl (gnupg_process_t process, unsigned int request, va_list arg_ptr) +{ + switch (request) + { + case GNUPG_PROCESS_NOP: + return 0; + + case GNUPG_PROCESS_GET_PROC_ID: + { + int *r_id = va_arg (arg_ptr, int *); + + if (r_id == NULL) + return GPG_ERR_INV_VALUE; + + *r_id = (int)process->pid; + return 0; + } + + case GNUPG_PROCESS_GET_EXIT_ID: + { + int status = process->wstatus; + int *r_exit_status = va_arg (arg_ptr, int *); + + if (!process->terminated) + return GPG_ERR_UNFINISHED; + + if (WIFEXITED (status)) + { + if (r_exit_status) + *r_exit_status = WEXITSTATUS (status); + } + else + *r_exit_status = -1; + + return 0; + } + + case GNUPG_PROCESS_GET_PID: + { + pid_t *r_pid = va_arg (arg_ptr, pid_t *); + + if (r_pid == NULL) + return GPG_ERR_INV_VALUE; + + *r_pid = process->pid; + return 0; + } + + case GNUPG_PROCESS_GET_WSTATUS: + { + int status = process->wstatus; + int *r_if_exited = va_arg (arg_ptr, int *); + int *r_if_signaled = va_arg (arg_ptr, int *); + int *r_exit_status = va_arg (arg_ptr, int *); + int *r_termsig = va_arg (arg_ptr, int *); + + if (!process->terminated) + return GPG_ERR_UNFINISHED; + + if (WIFEXITED (status)) + { + if (r_if_exited) + *r_if_exited = 1; + if (r_if_signaled) + *r_if_signaled = 0; + if (r_exit_status) + *r_exit_status = WEXITSTATUS (status); + if (r_termsig) + *r_termsig = 0; + } + else if (WIFSIGNALED (status)) + { + if (r_if_exited) + *r_if_exited = 0; + if (r_if_signaled) + *r_if_signaled = 1; + if (r_exit_status) + *r_exit_status = 0; + if (r_termsig) + *r_termsig = WTERMSIG (status); + } + + return 0; + } + + case GNUPG_PROCESS_KILL: + { + int sig = va_arg (arg_ptr, int); + + return process_kill (process, sig); + } + + default: + break; + } + + return GPG_ERR_UNKNOWN_COMMAND; +} + +gpg_err_code_t +gnupg_process_ctl (gnupg_process_t process, unsigned int request, ...) +{ + va_list arg_ptr; + gpg_err_code_t ec; + + va_start (arg_ptr, request); + ec = process_vctl (process, request, arg_ptr); + va_end (arg_ptr); + return ec; +} + +gpg_err_code_t +gnupg_process_wait (gnupg_process_t process, int hang) +{ + gpg_err_code_t ec; + int status; + pid_t pid; + + if (process->terminated) + /* Already terminated. */ + return 0; + + pre_syscall (); + while ((pid = waitpid (process->pid, &status, hang? 0: WNOHANG)) + == (pid_t)(-1) && errno == EINTR); + post_syscall (); + + if (pid == (pid_t)(-1)) + { + ec = gpg_err_code_from_syserror (); + log_error (_("waiting for process %d to terminate failed: %s\n"), + (int)pid, gpg_strerror (ec)); + } + else if (!pid) + { + ec = GPG_ERR_TIMEOUT; /* Still running. */ + } + else + { + process->terminated = 1; + process->wstatus = status; + ec = 0; + } + + return ec; +} + +void +gnupg_process_release (gnupg_process_t process) +{ + if (!process) + return; + + if (process->terminated) + { + gnupg_process_terminate (process); + gnupg_process_wait (process, 1); + } + + xfree (process); +} + +gpg_err_code_t +gnupg_process_wait_list (gnupg_process_t *process_list, int count, int hang) +{ + gpg_err_code_t ec = 0; + int i; + + for (i = 0; i < count; i++) + { + if (process_list[i]->terminated) + continue; + + ec = gnupg_process_wait (process_list[i], hang); + if (ec) + break; + } + + return ec; } diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 0034e03f2..8057cc3b4 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -33,6 +33,8 @@ #if !defined(HAVE_W32_SYSTEM) #error This code is only used on W32. +#else +#define _WIN32_WINNT 0x600 #endif #include @@ -63,9 +65,11 @@ #include "util.h" #include "i18n.h" #include "sysutils.h" +#define NEED_STRUCT_SPAWN_CB_ARG #include "exechelp.h" #include +#include /* Define to 1 do enable debugging. */ #define DEBUG_W32_SPAWN 0 @@ -405,646 +409,828 @@ gnupg_close_pipe (int fd) if (fd != -1) close (fd); } + +struct gnupg_process { + const char *pgmname; + unsigned int terminated :1; /* or detached */ + unsigned int flags; + HANDLE hProcess; + HANDLE hd_in; + HANDLE hd_out; + HANDLE hd_err; + int exitcode; +}; +static int gnupg_process_syscall_func_initialized; -/* Fork and exec the PGMNAME, see exechelp.h for details. */ -gpg_error_t -gnupg_spawn_process (const char *pgmname, const char *argv[], - int *except, unsigned int flags, - estream_t *r_infp, - estream_t *r_outfp, - estream_t *r_errfp, - pid_t *pid) +/* Functions called before and after blocking syscalls. */ +static void (*pre_syscall_func) (void); +static void (*post_syscall_func) (void); + +static void +check_syscall_func (void) { - gpg_error_t err; - SECURITY_ATTRIBUTES sec_attr; - PROCESS_INFORMATION pi = + if (!gnupg_process_syscall_func_initialized) { - NULL, /* Returns process handle. */ - 0, /* Returns primary thread handle. */ - 0, /* Returns pid. */ - 0 /* Returns tid. */ - }; - STARTUPINFOW si; - int cr_flags; - char *cmdline; - wchar_t *wcmdline = NULL; - wchar_t *wpgmname = NULL; - HANDLE inpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; - HANDLE outpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; - HANDLE errpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; - estream_t infp = NULL; - estream_t outfp = NULL; - estream_t errfp = NULL; - HANDLE nullhd[3] = {INVALID_HANDLE_VALUE, - INVALID_HANDLE_VALUE, - INVALID_HANDLE_VALUE}; - int i, rc; - es_syshd_t syshd; - gpg_err_source_t errsource = default_errsource; - int nonblock = !!(flags & GNUPG_SPAWN_NONBLOCK); - - (void)except; /* Not yet used. */ - - if (r_infp) - *r_infp = NULL; - if (r_outfp) - *r_outfp = NULL; - if (r_errfp) - *r_errfp = NULL; - *pid = (pid_t)(-1); /* Always required. */ - - if (r_infp) - { - if (create_inheritable_pipe (inpipe, INHERIT_READ)) - { - err = gpg_err_make (errsource, GPG_ERR_GENERAL); - log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); - return err; - } - - syshd.type = ES_SYSHD_HANDLE; - syshd.u.handle = inpipe[1]; - infp = es_sysopen (&syshd, nonblock? "w,nonblock" : "w"); - if (!infp) - { - err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); - log_error (_("error creating a stream for a pipe: %s\n"), - gpg_strerror (err)); - CloseHandle (inpipe[0]); - CloseHandle (inpipe[1]); - inpipe[0] = inpipe[1] = INVALID_HANDLE_VALUE; - return err; - } + gpgrt_get_syscall_clamp (&pre_syscall_func, &post_syscall_func); + gnupg_process_syscall_func_initialized = 1; } +} - if (r_outfp) - { - if (create_inheritable_pipe (outpipe, INHERIT_WRITE)) - { - err = gpg_err_make (errsource, GPG_ERR_GENERAL); - log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); - return err; - } - - syshd.type = ES_SYSHD_HANDLE; - syshd.u.handle = outpipe[0]; - outfp = es_sysopen (&syshd, nonblock? "r,nonblock" : "r"); - if (!outfp) - { - err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); - log_error (_("error creating a stream for a pipe: %s\n"), - gpg_strerror (err)); - CloseHandle (outpipe[0]); - CloseHandle (outpipe[1]); - outpipe[0] = outpipe[1] = INVALID_HANDLE_VALUE; - if (infp) - es_fclose (infp); - else if (inpipe[1] != INVALID_HANDLE_VALUE) - CloseHandle (inpipe[1]); - if (inpipe[0] != INVALID_HANDLE_VALUE) - CloseHandle (inpipe[0]); - return err; - } - } - - if (r_errfp) - { - if (create_inheritable_pipe (errpipe, INHERIT_WRITE)) - { - err = gpg_err_make (errsource, GPG_ERR_GENERAL); - log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); - return err; - } - - syshd.type = ES_SYSHD_HANDLE; - syshd.u.handle = errpipe[0]; - errfp = es_sysopen (&syshd, nonblock? "r,nonblock" : "r"); - if (!errfp) - { - err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); - log_error (_("error creating a stream for a pipe: %s\n"), - gpg_strerror (err)); - CloseHandle (errpipe[0]); - CloseHandle (errpipe[1]); - errpipe[0] = errpipe[1] = INVALID_HANDLE_VALUE; - if (outfp) - es_fclose (outfp); - else if (outpipe[0] != INVALID_HANDLE_VALUE) - CloseHandle (outpipe[0]); - if (outpipe[1] != INVALID_HANDLE_VALUE) - CloseHandle (outpipe[1]); - if (infp) - es_fclose (infp); - else if (inpipe[1] != INVALID_HANDLE_VALUE) - CloseHandle (inpipe[1]); - if (inpipe[0] != INVALID_HANDLE_VALUE) - CloseHandle (inpipe[0]); - return err; - } - } - - /* Prepare security attributes. */ - memset (&sec_attr, 0, sizeof sec_attr ); - sec_attr.nLength = sizeof sec_attr; - sec_attr.bInheritHandle = FALSE; - - /* Build the command line. */ - err = build_w32_commandline (pgmname, argv, &cmdline); - if (err) - return err; - - if (inpipe[0] == INVALID_HANDLE_VALUE) - nullhd[0] = ((flags & GNUPG_SPAWN_KEEP_STDIN)? - GetStdHandle (STD_INPUT_HANDLE) : w32_open_null (0)); - if (outpipe[1] == INVALID_HANDLE_VALUE) - nullhd[1] = ((flags & GNUPG_SPAWN_KEEP_STDOUT)? - GetStdHandle (STD_OUTPUT_HANDLE) : w32_open_null (1)); - if (errpipe[1] == INVALID_HANDLE_VALUE) - nullhd[2] = ((flags & GNUPG_SPAWN_KEEP_STDOUT)? - GetStdHandle (STD_ERROR_HANDLE) : w32_open_null (1)); - - memset (&si, 0, sizeof si); - si.cb = sizeof (si); - si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_HIDE; - si.hStdInput = inpipe[0] == INVALID_HANDLE_VALUE? nullhd[0] : inpipe[0]; - si.hStdOutput = outpipe[1] == INVALID_HANDLE_VALUE? nullhd[1] : outpipe[1]; - si.hStdError = errpipe[1] == INVALID_HANDLE_VALUE? nullhd[2] : errpipe[1]; - - cr_flags = (CREATE_DEFAULT_ERROR_MODE - | ((flags & GNUPG_SPAWN_DETACHED)? DETACHED_PROCESS : 0) - | GetPriorityClass (GetCurrentProcess ()) - | CREATE_SUSPENDED); - /* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", */ - /* pgmname, cmdline); */ - /* Take care: CreateProcessW may modify wpgmname */ - if (!(wpgmname = utf8_to_wchar (pgmname))) - rc = 0; - else if (!(wcmdline = utf8_to_wchar (cmdline))) - rc = 0; - else - rc = CreateProcessW (wpgmname, /* Program to start. */ - wcmdline, /* Command line arguments. */ - &sec_attr, /* Process security attributes. */ - &sec_attr, /* Thread security attributes. */ - TRUE, /* Inherit handles. */ - cr_flags, /* Creation flags. */ - NULL, /* Environment. */ - NULL, /* Use current drive/directory. */ - &si, /* Startup information. */ - &pi /* Returns process information. */ - ); - if (!rc) - { - if (!wpgmname || !wcmdline) - log_error ("CreateProcess failed (utf8_to_wchar): %s\n", - strerror (errno)); - else - log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); - xfree (wpgmname); - xfree (wcmdline); - xfree (cmdline); - if (infp) - es_fclose (infp); - else if (inpipe[1] != INVALID_HANDLE_VALUE) - CloseHandle (outpipe[1]); - if (inpipe[0] != INVALID_HANDLE_VALUE) - CloseHandle (inpipe[0]); - if (outfp) - es_fclose (outfp); - else if (outpipe[0] != INVALID_HANDLE_VALUE) - CloseHandle (outpipe[0]); - if (outpipe[1] != INVALID_HANDLE_VALUE) - CloseHandle (outpipe[1]); - if (errfp) - es_fclose (errfp); - else if (errpipe[0] != INVALID_HANDLE_VALUE) - CloseHandle (errpipe[0]); - if (errpipe[1] != INVALID_HANDLE_VALUE) - CloseHandle (errpipe[1]); - return gpg_err_make (errsource, GPG_ERR_GENERAL); - } - xfree (wpgmname); - xfree (wcmdline); - xfree (cmdline); - cmdline = NULL; - - /* Close the inherited handles to /dev/null. */ - for (i=0; i < DIM (nullhd); i++) - if (nullhd[i] != INVALID_HANDLE_VALUE) - CloseHandle (nullhd[i]); - - /* Close the inherited ends of the pipes. */ - if (inpipe[0] != INVALID_HANDLE_VALUE) - CloseHandle (inpipe[0]); - if (outpipe[1] != INVALID_HANDLE_VALUE) - CloseHandle (outpipe[1]); - if (errpipe[1] != INVALID_HANDLE_VALUE) - CloseHandle (errpipe[1]); - - /* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ - /* " dwProcessID=%d dwThreadId=%d\n", */ - /* pi.hProcess, pi.hThread, */ - /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - /* log_debug (" outfp=%p errfp=%p\n", outfp, errfp); */ - - /* Fixme: For unknown reasons AllowSetForegroundWindow returns an - invalid argument error if we pass it the correct processID. As a - workaround we use -1 (ASFW_ANY). */ - if ((flags & GNUPG_SPAWN_RUN_ASFW)) - gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/); - - /* Process has been created suspended; resume it now. */ - ResumeThread (pi.hThread); - CloseHandle (pi.hThread); - - if (r_infp) - *r_infp = infp; - if (r_outfp) - *r_outfp = outfp; - if (r_errfp) - *r_errfp = errfp; - - *pid = handle_to_pid (pi.hProcess); - return 0; +static void +pre_syscall (void) +{ + if (pre_syscall_func) + pre_syscall_func (); +} +static void +post_syscall (void) +{ + if (post_syscall_func) + post_syscall_func (); } - -/* Simplified version of gnupg_spawn_process. This function forks and - then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout - and ERRFD to stderr (any of them may be -1 to connect them to - /dev/null). The arguments for the process are expected in the NULL - terminated array ARGV. The program name itself should not be - included there. Calling gnupg_wait_process is required. - - Returns 0 on success or an error code. */ -gpg_error_t -gnupg_spawn_process_fd (const char *pgmname, const char *argv[], - int infd, int outfd, int errfd, pid_t *pid) +/* + * Check if STARTUPINFOEXW supports PROC_THREAD_ATTRIBUTE_HANDLE_LIST. + */ +static int +check_windows_version (void) +{ + static int is_vista_or_later = -1; + + OSVERSIONINFO osvi; + + if (is_vista_or_later == -1) + { + memset (&osvi,0,sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof(osvi); + GetVersionEx (&osvi); + + /* The feature is available on Vista or later. */ + is_vista_or_later = (osvi.dwMajorVersion >= 6); + } + + return is_vista_or_later; +} + + +static gpg_err_code_t +spawn_detached (const char *pgmname, char *cmdline, + void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) { - gpg_error_t err; SECURITY_ATTRIBUTES sec_attr; PROCESS_INFORMATION pi = { NULL, 0, 0, 0 }; - STARTUPINFOW si; - char *cmdline; + STARTUPINFOEXW si; + int cr_flags; wchar_t *wcmdline = NULL; wchar_t *wpgmname = NULL; - int i, rc; - HANDLE stdhd[3]; + gpg_err_code_t ec; + int ret; + struct spawn_cb_arg sca; + BOOL ask_inherit = FALSE; - /* Setup return values. */ - *pid = (pid_t)(-1); - - /* Prepare security attributes. */ - memset (&sec_attr, 0, sizeof sec_attr ); - sec_attr.nLength = sizeof sec_attr; - sec_attr.bInheritHandle = FALSE; - - /* Build the command line. */ - err = build_w32_commandline (pgmname, argv, &cmdline); - if (err) - return err; + ec = gnupg_access (pgmname, X_OK); + if (ec) + { + xfree (cmdline); + return ec; + } memset (&si, 0, sizeof si); - si.cb = sizeof (si); - si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; - stdhd[0] = infd == -1? w32_open_null (0) : INVALID_HANDLE_VALUE; - stdhd[1] = outfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE; - stdhd[2] = errfd == -1? w32_open_null (1) : INVALID_HANDLE_VALUE; - si.hStdInput = infd == -1? stdhd[0] : (void*)_get_osfhandle (infd); - si.hStdOutput = outfd == -1? stdhd[1] : (void*)_get_osfhandle (outfd); - si.hStdError = errfd == -1? stdhd[2] : (void*)_get_osfhandle (errfd); -/* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */ - /* Take care: CreateProcessW may modify wpgmname */ - if (!(wpgmname = utf8_to_wchar (pgmname))) - rc = 0; - else if (!(wcmdline = utf8_to_wchar (cmdline))) - rc = 0; - else - rc = CreateProcessW (wpgmname, /* Program to start. */ - wcmdline, /* Command line arguments. */ - &sec_attr, /* Process security attributes. */ - &sec_attr, /* Thread security attributes. */ - TRUE, /* Inherit handles. */ - (CREATE_DEFAULT_ERROR_MODE - | GetPriorityClass (GetCurrentProcess ()) - | CREATE_SUSPENDED | DETACHED_PROCESS), - NULL, /* Environment. */ - NULL, /* Use current drive/directory. */ - &si, /* Startup information. */ - &pi /* Returns process information. */ - ); - if (!rc) + sca.allow_foreground_window = FALSE; + sca.hd[0] = INVALID_HANDLE_VALUE; + sca.hd[1] = INVALID_HANDLE_VALUE; + sca.hd[2] = INVALID_HANDLE_VALUE; + sca.inherit_hds = NULL; + sca.arg = spawn_cb_arg; + if (spawn_cb) + (*spawn_cb) (&sca); + + if (sca.inherit_hds) { - if (!wpgmname || !wcmdline) - log_error ("CreateProcess failed (utf8_to_wchar): %s\n", - strerror (errno)); - else - log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); - err = my_error (GPG_ERR_GENERAL); - } - else - err = 0; - xfree (wpgmname); - xfree (wcmdline); - xfree (cmdline); - for (i=0; i < 3; i++) - if (stdhd[i] != INVALID_HANDLE_VALUE) - CloseHandle (stdhd[i]); - if (err) - return err; + SIZE_T attr_list_size = 0; + HANDLE hd[16]; + HANDLE *hd_p = sca.inherit_hds; + int j = 0; -/* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ -/* " dwProcessID=%d dwThreadId=%d\n", */ -/* pi.hProcess, pi.hThread, */ -/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - - /* Process has been created suspended; resume it now. */ - ResumeThread (pi.hThread); - CloseHandle (pi.hThread); - - *pid = handle_to_pid (pi.hProcess); - return 0; - -} - - -/* See exechelp.h for a description. */ -gpg_error_t -gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode) -{ - return gnupg_wait_processes (&pgmname, &pid, 1, hang, r_exitcode); -} - -/* See exechelp.h for a description. */ -gpg_error_t -gnupg_wait_processes (const char **pgmnames, pid_t *pids, size_t count, - int hang, int *r_exitcodes) -{ - gpg_err_code_t ec = 0; - size_t i; - HANDLE *procs; - int code; - - procs = xtrycalloc (count, sizeof *procs); - if (procs == NULL) - return my_error_from_syserror (); - - for (i = 0; i < count; i++) - { - if (r_exitcodes) - r_exitcodes[i] = -1; - - if (pids[i] == (pid_t)(-1)) - return my_error (GPG_ERR_INV_VALUE); - - procs[i] = pid_to_handle (pids[i]); - } - - /* FIXME: We should do a pth_waitpid here. However this has not yet - been implemented. A special W32 pth system call would even be - better. */ - code = WaitForMultipleObjects (count, procs, TRUE, hang? INFINITE : 0); - switch (code) - { - case WAIT_TIMEOUT: - ec = GPG_ERR_TIMEOUT; - goto leave; - - case WAIT_FAILED: - log_error (_("waiting for processes to terminate failed: %s\n"), - w32_strerror (-1)); - ec = GPG_ERR_GENERAL; - goto leave; - - case WAIT_OBJECT_0: - for (i = 0; i < count; i++) + if (hd_p) { - DWORD exc; - - if (! GetExitCodeProcess (procs[i], &exc)) - { - log_error (_("error getting exit code of process %d: %s\n"), - (int) pids[i], w32_strerror (-1) ); - ec = GPG_ERR_GENERAL; - } - else if (exc) - { - if (!r_exitcodes) - log_error (_("error running '%s': exit status %d\n"), - pgmnames[i], (int)exc); - else - r_exitcodes[i] = (int)exc; - ec = GPG_ERR_GENERAL; - } - else - { - if (r_exitcodes) - r_exitcodes[i] = 0; - } + while (*hd_p != INVALID_HANDLE_VALUE) + if (j < DIM (hd)) + hd[j++] = *hd_p++; + else + { + log_error ("Too much handles\n"); + break; + } } - break; - default: - log_error ("WaitForMultipleObjects returned unexpected " - "code %d\n", code); - ec = GPG_ERR_GENERAL; - break; + if (j) + { + if (check_windows_version ()) + { + InitializeProcThreadAttributeList (NULL, 1, 0, &attr_list_size); + si.lpAttributeList = xtrymalloc (attr_list_size); + if (si.lpAttributeList == NULL) + { + xfree (cmdline); + return gpg_err_code_from_syserror (); + } + InitializeProcThreadAttributeList (si.lpAttributeList, 1, 0, + &attr_list_size); + UpdateProcThreadAttribute (si.lpAttributeList, 0, + PROC_THREAD_ATTRIBUTE_HANDLE_LIST, + hd, sizeof (HANDLE) * j, NULL, NULL); + } + + ask_inherit = TRUE; + } } - leave: - return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec); -} - - - -void -gnupg_release_process (pid_t pid) -{ - if (pid != (pid_t)INVALID_HANDLE_VALUE) - { - HANDLE process = (HANDLE)pid; - - CloseHandle (process); - } -} - - -/* Spawn a new process and immediately detach from it. The name of - the program to exec is PGMNAME and its arguments are in ARGV (the - programname is automatically passed as first argument). - Environment strings in ENVP are set. An error is returned if - pgmname is not executable; to make this work it is necessary to - provide an absolute file name. All standard file descriptors are - connected to /dev/null. */ -gpg_error_t -gnupg_spawn_process_detached (const char *pgmname, const char *argv[], - const char *envp[] ) -{ - gpg_error_t err; - SECURITY_ATTRIBUTES sec_attr; - PROCESS_INFORMATION pi = - { - NULL, /* Returns process handle. */ - 0, /* Returns primary thread handle. */ - 0, /* Returns pid. */ - 0 /* Returns tid. */ - }; - STARTUPINFOW si; - int cr_flags; - char *cmdline; - wchar_t *wcmdline = NULL; - wchar_t *wpgmname = NULL; - BOOL in_job = FALSE; - gpg_err_code_t ec; - int rc; - int jobdebug; - - /* We don't use ENVP. */ - (void)envp; - - cmdline = getenv ("GNUPG_EXEC_DEBUG_FLAGS"); - jobdebug = (cmdline && (atoi (cmdline) & 1)); - - if ((ec = gnupg_access (pgmname, X_OK))) - return gpg_err_make (default_errsource, ec); - /* Prepare security attributes. */ memset (&sec_attr, 0, sizeof sec_attr ); sec_attr.nLength = sizeof sec_attr; sec_attr.bInheritHandle = FALSE; - /* Build the command line. */ - err = build_w32_commandline (pgmname, argv, &cmdline); - if (err) - return err; - /* Start the process. */ - memset (&si, 0, sizeof si); - si.cb = sizeof (si); - si.dwFlags = STARTF_USESHOWWINDOW; - si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; + si.StartupInfo.cb = sizeof (si); + si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW; + si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; cr_flags = (CREATE_DEFAULT_ERROR_MODE | GetPriorityClass (GetCurrentProcess ()) | CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS); - /* Check if we were spawned as part of a Job. - * In a job we need to add CREATE_BREAKAWAY_FROM_JOB - * to the cr_flags, otherwise our child processes - * are killed when we terminate. */ - if (!IsProcessInJob (GetCurrentProcess(), NULL, &in_job)) - { - log_error ("IsProcessInJob() failed: %s\n", w32_strerror (-1)); - in_job = FALSE; - } - - if (in_job) - { - /* Only try to break away from job if it is allowed, otherwise - * CreateProcess() would fail with an "Access is denied" error. */ - JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; - if (!QueryInformationJobObject (NULL, JobObjectExtendedLimitInformation, - &info, sizeof info, NULL)) - { - log_error ("QueryInformationJobObject() failed: %s\n", - w32_strerror (-1)); - } - else if ((info.BasicLimitInformation.LimitFlags & - JOB_OBJECT_LIMIT_BREAKAWAY_OK)) - { - if (jobdebug) - log_debug ("Using CREATE_BREAKAWAY_FROM_JOB flag\n"); - cr_flags |= CREATE_BREAKAWAY_FROM_JOB; - } - else if ((info.BasicLimitInformation.LimitFlags & - JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)) - { - /* The child process should automatically detach from the job. */ - if (jobdebug) - log_debug ("Not using CREATE_BREAKAWAY_FROM_JOB flag; " - "JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK is set\n"); - } - else - { - /* It seems that the child process must remain in the job. - * This is not necessarily an error, although it can cause premature - * termination of the child process when the job is closed. */ - if (jobdebug) - log_debug ("Not using CREATE_BREAKAWAY_FROM_JOB flag\n"); - } - } - else - { - if (jobdebug) - log_debug ("Process is not in a Job\n"); - } - - /* log_debug ("CreateProcess(detached), path='%s' cmdline='%s'\n", */ - /* pgmname, cmdline); */ /* Take care: CreateProcessW may modify wpgmname */ if (!(wpgmname = utf8_to_wchar (pgmname))) - rc = 0; + ret = 0; else if (!(wcmdline = utf8_to_wchar (cmdline))) - rc = 0; + ret = 0; else - rc = CreateProcessW (wpgmname, /* Program to start. */ - wcmdline, /* Command line arguments. */ - &sec_attr, /* Process security attributes. */ - &sec_attr, /* Thread security attributes. */ - FALSE, /* Inherit handles. */ - cr_flags, /* Creation flags. */ - NULL, /* Environment. */ - NULL, /* Use current drive/directory. */ - &si, /* Startup information. */ - &pi /* Returns process information. */ - ); - if (!rc) + ret = CreateProcessW (wpgmname, /* Program to start. */ + wcmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + ask_inherit, /* Inherit handles. */ + cr_flags, /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + (STARTUPINFOW *)&si, /* Startup information. */ + &pi /* Returns process information. */ + ); + if (!ret) { if (!wpgmname || !wcmdline) log_error ("CreateProcess failed (utf8_to_wchar): %s\n", strerror (errno)); else - log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1)); + log_error ("CreateProcess(detached) failed: %d\n", + (int)GetLastError ()); xfree (wpgmname); xfree (wcmdline); xfree (cmdline); - return my_error (GPG_ERR_GENERAL); + return GPG_ERR_GENERAL; } + if (si.lpAttributeList) + DeleteProcThreadAttributeList (si.lpAttributeList); xfree (wpgmname); xfree (wcmdline); xfree (cmdline); - cmdline = NULL; -/* log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p" */ -/* " dwProcessID=%d dwThreadId=%d\n", */ -/* pi.hProcess, pi.hThread, */ -/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + /* log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p" */ + /* " dwProcessID=%d dwThreadId=%d\n", */ + /* pi.hProcess, pi.hThread, */ + /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + + /* Note: AllowSetForegroundWindow doesn't make sense for background + process. */ CloseHandle (pi.hThread); CloseHandle (pi.hProcess); - return 0; } -/* Kill a process; that is send an appropriate signal to the process. - gnupg_wait_process must be called to actually remove the process - from the system. An invalid PID is ignored. */ void -gnupg_kill_process (pid_t pid) +gnupg_spawn_helper (struct spawn_cb_arg *sca) { - if (pid != (pid_t) INVALID_HANDLE_VALUE) - { - HANDLE process = (HANDLE) pid; - - /* Arbitrary error code. */ - TerminateProcess (process, 1); - } + HANDLE *user_except = sca->arg; + sca->inherit_hds = user_except; +} + +gpg_err_code_t +gnupg_process_spawn (const char *pgmname, const char *argv[], + unsigned int flags, + void (*spawn_cb) (struct spawn_cb_arg *), + void *spawn_cb_arg, + gnupg_process_t *r_process) +{ + gpg_err_code_t ec; + gnupg_process_t process; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = { NULL, 0, 0, 0 }; + STARTUPINFOEXW si; + int cr_flags; + char *cmdline; + wchar_t *wcmdline = NULL; + wchar_t *wpgmname = NULL; + int ret; + HANDLE hd_in[2]; + HANDLE hd_out[2]; + HANDLE hd_err[2]; + struct spawn_cb_arg sca; + int i; + BOOL ask_inherit = FALSE; + + check_syscall_func (); + + /* Build the command line. */ + ec = build_w32_commandline (pgmname, argv, &cmdline); + if (ec) + return ec; + + if ((flags & GNUPG_PROCESS_DETACHED)) + { + if ((flags & GNUPG_PROCESS_STDFDS_SETTING)) + { + xfree (cmdline); + return GPG_ERR_INV_FLAG; + } + + /* In detached case, it must be no R_PROCESS. */ + if (r_process) + { + xfree (cmdline); + return GPG_ERR_INV_ARG; + } + + return spawn_detached (pgmname, cmdline, spawn_cb, spawn_cb_arg); + } + + if (r_process) + *r_process = NULL; + + process = xtrymalloc (sizeof (struct gnupg_process)); + if (process == NULL) + { + xfree (cmdline); + return gpg_err_code_from_syserror (); + } + + process->pgmname = pgmname; + process->flags = flags; + + if ((flags & GNUPG_PROCESS_STDINOUT_SOCKETPAIR)) + { + xfree (process); + xfree (cmdline); + return GPG_ERR_NOT_SUPPORTED; + } + + if ((flags & GNUPG_PROCESS_STDIN_PIPE)) + { + ec = create_inheritable_pipe (hd_in, INHERIT_READ); + if (ec) + { + xfree (process); + xfree (cmdline); + return ec; + } + } + else if ((flags & GNUPG_PROCESS_STDIN_KEEP)) + { + hd_in[0] = GetStdHandle (STD_INPUT_HANDLE); + hd_in[1] = INVALID_HANDLE_VALUE; + } + else + { + hd_in[0] = w32_open_null (0); + hd_in[1] = INVALID_HANDLE_VALUE; + } + + if ((flags & GNUPG_PROCESS_STDOUT_PIPE)) + { + ec = create_inheritable_pipe (hd_out, INHERIT_WRITE); + if (ec) + { + if (hd_in[0] != INVALID_HANDLE_VALUE) + CloseHandle (hd_in[0]); + if (hd_in[1] != INVALID_HANDLE_VALUE) + CloseHandle (hd_in[1]); + xfree (process); + xfree (cmdline); + return ec; + } + } + else if ((flags & GNUPG_PROCESS_STDOUT_KEEP)) + { + hd_out[0] = INVALID_HANDLE_VALUE; + hd_out[1] = GetStdHandle (STD_OUTPUT_HANDLE); + } + else + { + hd_out[0] = INVALID_HANDLE_VALUE; + hd_out[1] = w32_open_null (1); + } + + if ((flags & GNUPG_PROCESS_STDERR_PIPE)) + { + ec = create_inheritable_pipe (hd_err, INHERIT_WRITE); + if (ec) + { + if (hd_in[0] != INVALID_HANDLE_VALUE) + CloseHandle (hd_in[0]); + if (hd_in[1] != INVALID_HANDLE_VALUE) + CloseHandle (hd_in[1]); + if (hd_out[0] != INVALID_HANDLE_VALUE) + CloseHandle (hd_out[0]); + if (hd_out[1] != INVALID_HANDLE_VALUE) + CloseHandle (hd_out[1]); + xfree (process); + xfree (cmdline); + return ec; + } + } + else if ((flags & GNUPG_PROCESS_STDERR_KEEP)) + { + hd_err[0] = INVALID_HANDLE_VALUE; + hd_err[1] = GetStdHandle (STD_ERROR_HANDLE); + } + else + { + hd_err[0] = INVALID_HANDLE_VALUE; + hd_err[1] = w32_open_null (1); + } + + memset (&si, 0, sizeof si); + + sca.allow_foreground_window = FALSE; + sca.hd[0] = hd_in[0]; + sca.hd[1] = hd_out[1]; + sca.hd[2] = hd_err[1]; + sca.inherit_hds = NULL; + sca.arg = spawn_cb_arg; + if (spawn_cb) + (*spawn_cb) (&sca); + + i = 0; + if (sca.hd[0] != INVALID_HANDLE_VALUE) + i++; + if (sca.hd[1] != INVALID_HANDLE_VALUE) + i++; + if (sca.hd[2] != INVALID_HANDLE_VALUE) + i++; + + if (i != 0 || sca.inherit_hds) + { + SIZE_T attr_list_size = 0; + HANDLE hd[16]; + HANDLE *hd_p = sca.inherit_hds; + int j = 0; + + if (sca.hd[0] != INVALID_HANDLE_VALUE) + hd[j++] = sca.hd[0]; + if (sca.hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = sca.hd[1]; + if (sca.hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = sca.hd[2]; + if (hd_p) + { + while (*hd_p != INVALID_HANDLE_VALUE) + if (j < DIM (hd)) + hd[j++] = *hd_p++; + else + { + log_error ("Too much handles\n"); + break; + } + } + + if (j) + { + if (check_windows_version ()) + { + InitializeProcThreadAttributeList (NULL, 1, 0, &attr_list_size); + si.lpAttributeList = xtrymalloc (attr_list_size); + if (si.lpAttributeList == NULL) + { + if ((flags & GNUPG_PROCESS_STDIN_PIPE) + || !(flags & GNUPG_PROCESS_STDIN_KEEP)) + CloseHandle (hd_in[0]); + if ((flags & GNUPG_PROCESS_STDIN_PIPE)) + CloseHandle (hd_in[1]); + if ((flags & GNUPG_PROCESS_STDOUT_PIPE)) + CloseHandle (hd_out[0]); + if ((flags & GNUPG_PROCESS_STDOUT_PIPE) + || !(flags & GNUPG_PROCESS_STDOUT_KEEP)) + CloseHandle (hd_out[1]); + if ((flags & GNUPG_PROCESS_STDERR_PIPE)) + CloseHandle (hd_err[0]); + if ((flags & GNUPG_PROCESS_STDERR_PIPE) + || !(flags & GNUPG_PROCESS_STDERR_KEEP)) + CloseHandle (hd_err[1]); + xfree (process); + xfree (cmdline); + return gpg_err_code_from_syserror (); + } + InitializeProcThreadAttributeList (si.lpAttributeList, 1, 0, + &attr_list_size); + UpdateProcThreadAttribute (si.lpAttributeList, 0, + PROC_THREAD_ATTRIBUTE_HANDLE_LIST, + hd, sizeof (HANDLE) * j, NULL, NULL); + } + ask_inherit = TRUE; + } + } + + /* Prepare security attributes. */ + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + /* Start the process. */ + si.StartupInfo.cb = sizeof (si); + si.StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_HIDE; + si.StartupInfo.hStdInput = sca.hd[0]; + si.StartupInfo.hStdOutput = sca.hd[1]; + si.StartupInfo.hStdError = sca.hd[2]; + + /* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */ + cr_flags = (CREATE_DEFAULT_ERROR_MODE + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_SUSPENDED); + if (!(wpgmname = utf8_to_wchar (pgmname))) + ret = 0; + else if (!(wcmdline = utf8_to_wchar (cmdline))) + ret = 0; + else + ret = CreateProcessW (wpgmname, /* Program to start. */ + wcmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + ask_inherit, /* Inherit handles. */ + cr_flags, /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + (STARTUPINFOW *)&si, /* Startup information. */ + &pi /* Returns process information. */ + ); + if (!ret) + { + if (!wpgmname || !wcmdline) + log_error ("CreateProcess failed (utf8_to_wchar): %s\n", + strerror (errno)); + else + log_error ("CreateProcess failed: ec=%d\n", + (int)GetLastError ()); + if ((flags & GNUPG_PROCESS_STDIN_PIPE) + || !(flags & GNUPG_PROCESS_STDIN_KEEP)) + CloseHandle (hd_in[0]); + if ((flags & GNUPG_PROCESS_STDIN_PIPE)) + CloseHandle (hd_in[1]); + if ((flags & GNUPG_PROCESS_STDOUT_PIPE)) + CloseHandle (hd_out[0]); + if ((flags & GNUPG_PROCESS_STDOUT_PIPE) + || !(flags & GNUPG_PROCESS_STDOUT_KEEP)) + CloseHandle (hd_out[1]); + if ((flags & GNUPG_PROCESS_STDERR_PIPE)) + CloseHandle (hd_err[0]); + if ((flags & GNUPG_PROCESS_STDERR_PIPE) + || !(flags & GNUPG_PROCESS_STDERR_KEEP)) + CloseHandle (hd_err[1]); + xfree (wpgmname); + xfree (wcmdline); + xfree (process); + xfree (cmdline); + return GPG_ERR_GENERAL; + } + + if (si.lpAttributeList) + DeleteProcThreadAttributeList (si.lpAttributeList); + xfree (wpgmname); + xfree (wcmdline); + xfree (cmdline); + + if ((flags & GNUPG_PROCESS_STDIN_PIPE) + || !(flags & GNUPG_PROCESS_STDIN_KEEP)) + CloseHandle (hd_in[0]); + if ((flags & GNUPG_PROCESS_STDOUT_PIPE) + || !(flags & GNUPG_PROCESS_STDOUT_KEEP)) + CloseHandle (hd_out[1]); + if ((flags & GNUPG_PROCESS_STDERR_PIPE) + || !(flags & GNUPG_PROCESS_STDERR_KEEP)) + CloseHandle (hd_err[1]); + + /* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ + /* " dwProcessID=%d dwThreadId=%d\n", */ + /* pi.hProcess, pi.hThread, */ + /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + + if (sca.allow_foreground_window) + { + /* Fixme: For unknown reasons AllowSetForegroundWindow returns + * an invalid argument error if we pass it the correct + * processID. As a workaround we use -1 (ASFW_ANY). */ + if (!AllowSetForegroundWindow (ASFW_ANY /*pi.dwProcessId*/)) + log_info ("AllowSetForegroundWindow() failed: ec=%d\n", + (int)GetLastError ()); + } + + /* Process has been created suspended; resume it now. */ + pre_syscall (); + ResumeThread (pi.hThread); + CloseHandle (pi.hThread); + post_syscall (); + + process->hProcess = pi.hProcess; + process->hd_in = hd_in[1]; + process->hd_out = hd_out[0]; + process->hd_err = hd_err[0]; + process->exitcode = -1; + process->terminated = 0; + + if (r_process == NULL) + { + ec = gnupg_process_wait (process, 1); + gnupg_process_release (process); + return ec; + } + + *r_process = process; + return 0; +} + +gpg_err_code_t +gnupg_process_get_fds (gnupg_process_t process, unsigned int flags, + int *r_fd_in, int *r_fd_out, int *r_fd_err) +{ + (void)flags; + if (r_fd_in) + { + *r_fd_in = _open_osfhandle ((intptr_t)process->hd_in, O_APPEND); + process->hd_in = INVALID_HANDLE_VALUE; + } + if (r_fd_out) + { + *r_fd_out = _open_osfhandle ((intptr_t)process->hd_out, O_RDONLY); + process->hd_out = INVALID_HANDLE_VALUE; + } + if (r_fd_err) + { + *r_fd_err = _open_osfhandle ((intptr_t)process->hd_err, O_RDONLY); + process->hd_err = INVALID_HANDLE_VALUE; + } + + return 0; +} + +gpg_err_code_t +gnupg_process_get_streams (gnupg_process_t process, unsigned int flags, + estream_t *r_fp_in, estream_t *r_fp_out, + estream_t *r_fp_err) +{ + int nonblock = (flags & GNUPG_PROCESS_STREAM_NONBLOCK)? 1: 0; + es_syshd_t syshd; + + syshd.type = ES_SYSHD_HANDLE; + if (r_fp_in) + { + syshd.u.handle = process->hd_in; + *r_fp_in = es_sysopen (&syshd, nonblock? "w,nonblock" : "w"); + process->hd_in = INVALID_HANDLE_VALUE; + } + if (r_fp_out) + { + syshd.u.handle = process->hd_out; + *r_fp_out = es_sysopen (&syshd, nonblock? "r,nonblock" : "r"); + process->hd_out = INVALID_HANDLE_VALUE; + } + if (r_fp_err) + { + syshd.u.handle = process->hd_err; + *r_fp_err = es_sysopen (&syshd, nonblock? "r,nonblock" : "r"); + process->hd_err = INVALID_HANDLE_VALUE; + } + return 0; +} + +static gpg_err_code_t +process_kill (gnupg_process_t process, unsigned int exitcode) +{ + gpg_err_code_t ec = 0; + + pre_syscall (); + if (TerminateProcess (process->hProcess, exitcode)) + ec = gpg_err_code_from_syserror (); + post_syscall (); + return ec; +} + +static gpg_err_code_t +process_vctl (gnupg_process_t process, unsigned int request, va_list arg_ptr) +{ + switch (request) + { + case GNUPG_PROCESS_NOP: + return 0; + + case GNUPG_PROCESS_GET_PROC_ID: + { + int *r_id = va_arg (arg_ptr, int *); + + if (r_id == NULL) + return GPG_ERR_INV_VALUE; + + *r_id = (int)GetProcessId (process->hProcess); + return 0; + } + + case GNUPG_PROCESS_GET_EXIT_ID: + { + int *r_exit_status = va_arg (arg_ptr, int *); + unsigned long exit_code; + + *r_exit_status = -1; + + if (!process->terminated) + return GPG_ERR_UNFINISHED; + + if (process->hProcess == INVALID_HANDLE_VALUE) + return 0; + + if (GetExitCodeProcess (process->hProcess, &exit_code) == 0) + return gpg_err_code_from_syserror (); + + *r_exit_status = (int)exit_code; + return 0; + } + + case GNUPG_PROCESS_GET_P_HANDLE: + { + HANDLE *r_hProcess = va_arg (arg_ptr, HANDLE *); + + if (r_hProcess == NULL) + return GPG_ERR_INV_VALUE; + + *r_hProcess = process->hProcess; + process->hProcess = INVALID_HANDLE_VALUE; + return 0; + } + + case GNUPG_PROCESS_GET_HANDLES: + { + HANDLE *r_hd_in = va_arg (arg_ptr, HANDLE *); + HANDLE *r_hd_out = va_arg (arg_ptr, HANDLE *); + HANDLE *r_hd_err = va_arg (arg_ptr, HANDLE *); + + if (r_hd_in) + { + *r_hd_in = process->hd_in; + process->hd_in = INVALID_HANDLE_VALUE; + } + if (r_hd_out) + { + *r_hd_out = process->hd_out; + process->hd_out = INVALID_HANDLE_VALUE; + } + if (r_hd_err) + { + *r_hd_err = process->hd_err; + process->hd_err = INVALID_HANDLE_VALUE; + } + return 0; + } + + case GNUPG_PROCESS_GET_EXIT_CODE: + { + unsigned long *r_exitcode = va_arg (arg_ptr, unsigned long *); + + if (!process->terminated) + return GPG_ERR_UNFINISHED; + + if (process->hProcess == INVALID_HANDLE_VALUE) + { + *r_exitcode = (unsigned long)-1; + return 0; + } + + if (GetExitCodeProcess (process->hProcess, r_exitcode) == 0) + return gpg_err_code_from_syserror (); + return 0; + } + + case GNUPG_PROCESS_KILL_WITH_EC: + { + unsigned int exitcode = va_arg (arg_ptr, unsigned int); + + if (process->terminated) + return 0; + + if (process->hProcess == INVALID_HANDLE_VALUE) + return 0; + + return process_kill (process, exitcode); + } + + default: + break; + } + + return GPG_ERR_UNKNOWN_COMMAND; +} + +gpg_err_code_t +gnupg_process_ctl (gnupg_process_t process, unsigned int request, ...) +{ + va_list arg_ptr; + gpg_err_code_t ec; + + va_start (arg_ptr, request); + ec = process_vctl (process, request, arg_ptr); + va_end (arg_ptr); + return ec; +} + +gpg_err_code_t +gnupg_process_wait (gnupg_process_t process, int hang) +{ + gpg_err_code_t ec; + int code; + + if (process->hProcess == INVALID_HANDLE_VALUE) + return 0; + + pre_syscall (); + code = WaitForSingleObject (process->hProcess, hang? INFINITE : 0); + post_syscall (); + + switch (code) + { + case WAIT_TIMEOUT: + ec = GPG_ERR_TIMEOUT; /* Still running. */ + break; + + case WAIT_FAILED: + log_error (_("waiting for process to terminate failed: ec=%d\n"), + (int)GetLastError ()); + ec = GPG_ERR_GENERAL; + break; + + case WAIT_OBJECT_0: + process->terminated = 1; + ec = 0; + break; + + default: + log_debug ("WaitForSingleObject returned unexpected code %d\n", code); + ec = GPG_ERR_GENERAL; + break; + } + + return ec; +} + +gpg_err_code_t +gnupg_process_terminate (gnupg_process_t process) +{ + return process_kill (process, 1); +} + +void +gnupg_process_release (gnupg_process_t process) +{ + if (!process) + return; + + if (process->terminated) + { + gnupg_process_terminate (process); + gnupg_process_wait (process, 1); + } + + xfree (process); +} + +gpg_err_code_t +gnupg_process_wait_list (gnupg_process_t *process_list, int count, int hang) +{ + gpg_err_code_t ec = 0; + int i; + + for (i = 0; i < count; i++) + { + if (process_list[i]->terminated) + continue; + + ec = gnupg_process_wait (process_list[i], hang); + if (ec) + break; + } + + return ec; } diff --git a/common/exechelp.h b/common/exechelp.h index 3343fe598..0370b23a4 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -73,140 +73,103 @@ gpg_error_t gnupg_create_pipe (int filedes[2]); void gnupg_close_pipe (int fd); -#define GNUPG_SPAWN_NONBLOCK 16 -#define GNUPG_SPAWN_RUN_ASFW 64 -#define GNUPG_SPAWN_DETACHED 128 -#define GNUPG_SPAWN_KEEP_STDIN 256 -#define GNUPG_SPAWN_KEEP_STDOUT 512 -#define GNUPG_SPAWN_KEEP_STDERR 1024 +/* The opaque type for a subprocess. */ +typedef struct gnupg_process *gnupg_process_t; +#ifdef HAVE_W32_SYSTEM +struct spawn_cb_arg; +#ifdef NEED_STRUCT_SPAWN_CB_ARG +struct spawn_cb_arg { + HANDLE hd[3]; + HANDLE *inherit_hds; + BOOL allow_foreground_window; + void *arg; +}; +#endif +#else +struct spawn_cb_arg { + int fds[3]; + int *except_fds; + void *arg; +}; +#endif -/* Fork and exec the program PGMNAME. +#define GNUPG_PROCESS_DETACHED (1 << 1) - If R_INFP is NULL connect stdin of the new process to /dev/null; if - it is not NULL store the address of a pointer to a new estream - there. If R_OUTFP is NULL connect stdout of the new process to - /dev/null; if it is not NULL store the address of a pointer to a - new estream there. If R_ERRFP is NULL connect stderr of the new - process to /dev/null; if it is not NULL store the address of a - pointer to a new estream there. On success the pid of the new - process is stored at PID. On error -1 is stored at PID and if - R_OUTFP or R_ERRFP are not NULL, NULL is stored there. +/* Specify how to keep/connect standard fds. */ +#define GNUPG_PROCESS_STDIN_PIPE (1 << 8) +#define GNUPG_PROCESS_STDOUT_PIPE (1 << 9) +#define GNUPG_PROCESS_STDERR_PIPE (1 << 10) +#define GNUPG_PROCESS_STDINOUT_SOCKETPAIR (1 << 11) +#define GNUPG_PROCESS_STDIN_KEEP (1 << 12) +#define GNUPG_PROCESS_STDOUT_KEEP (1 << 13) +#define GNUPG_PROCESS_STDERR_KEEP (1 << 14) +#define GNUPG_PROCESS_STDFDS_SETTING ( GNUPG_PROCESS_STDIN_PIPE \ + | GNUPG_PROCESS_STDOUT_PIPE | GNUPG_PROCESS_STDERR_PIPE \ + | GNUPG_PROCESS_STDINOUT_SOCKETPAIR | GNUPG_PROCESS_STDIN_KEEP \ + | GNUPG_PROCESS_STDOUT_KEEP | GNUPG_PROCESS_STDERR_KEEP) - The arguments for the process are expected in the NULL terminated - array ARGV. The program name itself should not be included there. - If PREEXEC is not NULL, the given function will be called right - before the exec. +#define GNUPG_PROCESS_STREAM_NONBLOCK (1 << 16) - IF EXCEPT is not NULL, it is expected to be an ordered list of file - descriptors, terminated by an entry with the value (-1). These - file descriptors won't be closed before spawning a new program. +/* Spawn helper. */ +void gnupg_spawn_helper (struct spawn_cb_arg *sca); - Returns 0 on success or an error code. Calling gnupg_wait_process - and gnupg_release_process is required if the function succeeded. +/* Spawn PGMNAME. */ +gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv[], + unsigned int flags, + void (*spawn_cb) (struct spawn_cb_arg *), + void *spawn_cb_arg, + gnupg_process_t *r_process); - FLAGS is a bit vector: +/* Get FDs for subprocess I/O. It is the caller which should care + FDs (closing FDs). */ +gpg_err_code_t gnupg_process_get_fds (gnupg_process_t process, + unsigned int flags, + int *r_fd_in, int *r_fd_out, + int *r_fd_err); - GNUPG_SPAWN_NONBLOCK - If set the two output streams are created in non-blocking - mode and the input stream is switched to non-blocking mode. - This is merely a convenience feature because the caller - could do the same with gpgrt_set_nonblock. Does not yet - work for Windows. +/* Get STREAMs for subprocess I/O. It is the caller which should care + STREAMs (closing STREAMs). */ +gpg_err_code_t gnupg_process_get_streams (gnupg_process_t process, + unsigned int flags, + gpgrt_stream_t *r_fp_in, + gpgrt_stream_t *r_fp_out, + gpgrt_stream_t *r_fp_err); - GNUPG_SPAWN_DETACHED - If set the process will be started as a background process. - This flag is only useful under W32 (but not W32CE) systems, - so that no new console is created and pops up a console - window when starting the server. Does not work on W32CE. +enum gnupg_process_requests + { + /* Portable requests */ + GNUPG_PROCESS_NOP = 0, + GNUPG_PROCESS_GET_PROC_ID = 1, + GNUPG_PROCESS_GET_EXIT_ID = 2, - GNUPG_SPAWN_RUN_ASFW - On W32 (but not on W32CE) run AllowSetForegroundWindow for - the child. Note that due to unknown problems this actually - allows SetForegroundWindow for all children of this process. + /* POSIX only */ + GNUPG_PROCESS_GET_PID = 16, + GNUPG_PROCESS_GET_WSTATUS = 17, + GNUPG_PROCESS_KILL = 18, - GNUPG_SPAWN_KEEP_STDIN - GNUPG_SPAWN_KEEP_STDOUT - GNUPG_SPAWN_KEEP_STDERR - Do not assign /dev/null to a non-required standard file - descriptor. + /* Windows only */ + GNUPG_PROCESS_GET_P_HANDLE = 32, + GNUPG_PROCESS_GET_HANDLES = 33, + GNUPG_PROCESS_GET_EXIT_CODE = 34, + GNUPG_PROCESS_KILL_WITH_EC = 35 + }; - */ -gpg_error_t -gnupg_spawn_process (const char *pgmname, const char *argv[], - int *execpt, unsigned int flags, - estream_t *r_infp, - estream_t *r_outfp, - estream_t *r_errfp, - pid_t *pid); +/* Control of a process. */ +gpg_err_code_t gnupg_process_ctl (gnupg_process_t process, + unsigned int request, ...); +/* Wait for a single PROCESS. */ +gpg_err_code_t gnupg_process_wait (gnupg_process_t process, int hang); -/* Simplified version of gnupg_spawn_process. This function forks and - then execs PGMNAME, while connecting INFD to stdin, OUTFD to stdout - and ERRFD to stderr (any of them may be -1 to connect them to - /dev/null). The arguments for the process are expected in the NULL - terminated array ARGV. The program name itself should not be - included there. Calling gnupg_wait_process and - gnupg_release_process is required. Returns 0 on success or an - error code. */ -gpg_error_t gnupg_spawn_process_fd (const char *pgmname, - const char *argv[], - int infd, int outfd, int errfd, - pid_t *pid); +/* Terminate a PROCESS. */ +gpg_err_code_t gnupg_process_terminate (gnupg_process_t process); +/* Release PROCESS resources. */ +void gnupg_process_release (gnupg_process_t process); -/* If HANG is true, waits for the process identified by PID to exit; - if HANG is false, checks whether the process has terminated. - PGMNAME should be the same as supplied to the spawn function and is - only used for diagnostics. Return values: - - 0 - The process exited successful. 0 is stored at R_EXITCODE. - - GPG_ERR_GENERAL - The process exited without success. The exit code of process - is then stored at R_EXITCODE. An exit code of -1 indicates - that the process terminated abnormally (e.g. due to a signal). - - GPG_ERR_TIMEOUT - The process is still running (returned only if HANG is false). - - GPG_ERR_INV_VALUE - An invalid PID has been specified. - - Other error codes may be returned as well. Unless otherwise noted, - -1 will be stored at R_EXITCODE. R_EXITCODE may be passed as NULL - if the exit code is not required (in that case an error message will - be printed). Note that under Windows PID is not the process id but - the handle of the process. */ -gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid, int hang, - int *r_exitcode); - -/* Like gnupg_wait_process, but for COUNT processes. */ -gpg_error_t gnupg_wait_processes (const char **pgmnames, pid_t *pids, - size_t count, int hang, int *r_exitcodes); - - -/* Kill a process; that is send an appropriate signal to the process. - gnupg_wait_process must be called to actually remove the process - from the system. An invalid PID is ignored. */ -void gnupg_kill_process (pid_t pid); - -/* Release the process identified by PID. This function is actually - only required for Windows but it does not harm to always call it. - It is a nop if PID is invalid. */ -void gnupg_release_process (pid_t pid); - - -/* Spawn a new process and immediately detach from it. The name of - the program to exec is PGMNAME and its arguments are in ARGV (the - programname is automatically passed as first argument). - Environment strings in ENVP are set. An error is returned if - pgmname is not executable; to make this work it is necessary to - provide an absolute file name. */ -gpg_error_t gnupg_spawn_process_detached (const char *pgmname, - const char *argv[], - const char *envp[] ); - +/* Wait for a multiple processes. */ +gpg_err_code_t gnupg_process_wait_list (gnupg_process_t *process_list, + int count, int hang); #endif /*GNUPG_COMMON_EXECHELP_H*/ diff --git a/common/exectool.c b/common/exectool.c index aaf5898d0..3505c25f1 100644 --- a/common/exectool.c +++ b/common/exectool.c @@ -38,10 +38,14 @@ #include #include + #include "i18n.h" #include "logging.h" #include "membuf.h" #include "mischelp.h" +#ifdef HAVE_W32_SYSTEM +#define NEED_STRUCT_SPAWN_CB_ARG 1 +#endif #include "exechelp.h" #include "sysutils.h" #include "util.h" @@ -301,7 +305,6 @@ copy_buffer_flush (struct copy_buffer *c, estream_t sink) } - /* Run the program PGMNAME with the command line arguments given in * the NULL terminates array ARGV. If INPUT is not NULL it will be * fed to stdin of the process. stderr is logged using log_info and @@ -321,7 +324,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], void *status_cb_value) { gpg_error_t err; - pid_t pid = (pid_t) -1; + gnupg_process_t proc = NULL; estream_t infp = NULL; estream_t extrafp = NULL; estream_t outfp = NULL, errfp = NULL; @@ -335,7 +338,6 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], read_and_log_buffer_t fderrstate; struct copy_buffer *cpbuf_in = NULL, *cpbuf_out = NULL, *cpbuf_extra = NULL; int quiet = 0; - int dummy_exitcode; memset (fds, 0, sizeof fds); memset (&fderrstate, 0, sizeof fderrstate); @@ -411,10 +413,15 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], else exceptclose[0] = -1; - err = gnupg_spawn_process (pgmname, argv, - exceptclose, GNUPG_SPAWN_NONBLOCK, - input? &infp : NULL, - &outfp, &errfp, &pid); + err = gnupg_process_spawn (pgmname, argv, + ((input + ? GNUPG_PROCESS_STDIN_PIPE + : 0) + | GNUPG_PROCESS_STDOUT_PIPE + | GNUPG_PROCESS_STDERR_PIPE), + gnupg_spawn_helper, exceptclose, &proc); + gnupg_process_get_streams (proc, GNUPG_PROCESS_STREAM_NONBLOCK, + input? &infp : NULL, &outfp, &errfp); if (extrapipe[0] != -1) close (extrapipe[0]); if (argsave) @@ -546,20 +553,25 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], es_fclose (outfp); outfp = NULL; es_fclose (errfp); errfp = NULL; - err = gnupg_wait_process (pgmname, pid, 1, quiet? &dummy_exitcode : NULL); - pid = (pid_t)(-1); + err = gnupg_process_wait (proc, 1); + if (!err) + { /* To be compatible to old wait_process. */ + int status; + + gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &status); + if (status) + err = gpg_error (GPG_ERR_GENERAL); + } leave: - if (err && pid != (pid_t) -1) - gnupg_kill_process (pid); + if (err && proc) + gnupg_process_terminate (proc); es_fclose (infp); es_fclose (extrafp); es_fclose (outfp); es_fclose (errfp); - if (pid != (pid_t)(-1)) - gnupg_wait_process (pgmname, pid, 1, quiet? &dummy_exitcode : NULL); - gnupg_release_process (pid); + gnupg_process_release (proc); copy_buffer_shred (cpbuf_in); xfree (cpbuf_in); diff --git a/dirmngr/ldap-wrapper.c b/dirmngr/ldap-wrapper.c index 23d514cf9..2ec944c72 100644 --- a/dirmngr/ldap-wrapper.c +++ b/dirmngr/ldap-wrapper.c @@ -87,7 +87,7 @@ struct wrapper_context_s { struct wrapper_context_s *next; - pid_t pid; /* The pid of the wrapper process. */ + gnupg_process_t proc;/* The wrapper process. */ int printable_pid; /* Helper to print diagnostics after the process has * been cleaned up. */ estream_t fp; /* Connected with stdout of the ldap wrapper. */ @@ -170,10 +170,10 @@ read_buffer (ksba_reader_t reader, unsigned char *buffer, size_t count) static void destroy_wrapper (struct wrapper_context_s *ctx) { - if (ctx->pid != (pid_t)(-1)) + if (ctx->proc) { - gnupg_kill_process (ctx->pid); - gnupg_release_process (ctx->pid); + gnupg_process_terminate (ctx->proc); + gnupg_process_release (ctx->proc); } ksba_reader_release (ctx->reader); SAFE_CLOSE (ctx->fp); @@ -260,7 +260,7 @@ read_log_data (struct wrapper_context_s *ctx) if (gpg_err_code (err) == GPG_ERR_EAGAIN) return 0; log_error (_("error reading log from ldap wrapper %d: %s\n"), - (int)ctx->pid, gpg_strerror (err)); + ctx->printable_pid, gpg_strerror (err)); } print_log_line (ctx, NULL); /* Flush. */ SAFE_CLOSE (ctx->log_fp); @@ -438,50 +438,44 @@ ldap_reaper_thread (void *dummy) } /* Check whether the process is still running. */ - if (ctx->pid != (pid_t)(-1)) + if (ctx->proc) { - int status; - - err = gnupg_wait_process ("[dirmngr_ldap]", ctx->pid, 0, - &status); + err = gnupg_process_wait (ctx->proc, 0); if (!err) { + int status; + + gnupg_process_ctl (ctx->proc, GNUPG_PROCESS_GET_EXIT_ID, + &status); if (DBG_EXTPROG) - log_info (_("ldap wrapper %d ready"), (int)ctx->pid); + log_info (_("ldap wrapper %d ready"), ctx->printable_pid); ctx->ready = 1; - gnupg_release_process (ctx->pid); - ctx->pid = (pid_t)(-1); + gnupg_process_release (ctx->proc); + ctx->proc = NULL; any_action = 1; - } - else if (gpg_err_code (err) == GPG_ERR_GENERAL) - { + if (status == 10) log_info (_("ldap wrapper %d ready: timeout\n"), - (int)ctx->pid); + ctx->printable_pid); else log_info (_("ldap wrapper %d ready: exitcode=%d\n"), - (int)ctx->pid, status); - ctx->ready = 1; - gnupg_release_process (ctx->pid); - ctx->pid = (pid_t)(-1); - any_action = 1; + ctx->printable_pid, status); } else if (gpg_err_code (err) != GPG_ERR_TIMEOUT) { log_error (_("waiting for ldap wrapper %d failed: %s\n"), - (int)ctx->pid, gpg_strerror (err)); + ctx->printable_pid, gpg_strerror (err)); any_action = 1; } } /* Check whether we should terminate the process. */ - if (ctx->pid != (pid_t)(-1) - && ctx->stamp != (time_t)(-1) && ctx->stamp < exptime) + if (ctx->proc && ctx->stamp != (time_t)(-1) && ctx->stamp < exptime) { - gnupg_kill_process (ctx->pid); + gnupg_process_terminate (ctx->proc); ctx->stamp = (time_t)(-1); log_info (_("ldap wrapper %d stalled - killing\n"), - (int)ctx->pid); + ctx->printable_pid); /* We need to close the log stream because the cleanup * loop waits for it. */ SAFE_CLOSE (ctx->log_fp); @@ -496,10 +490,10 @@ ldap_reaper_thread (void *dummy) { log_debug ("ldap worker states:\n"); for (ctx = reaper_list; ctx; ctx = ctx->next) - log_debug (" c=%p pid=%d/%d rdr=%p logfp=%p" + log_debug (" c=%p pid=%d rdr=%p logfp=%p" " ctrl=%p/%d la=%lu rdy=%d\n", ctx, - (int)ctx->pid, (int)ctx->printable_pid, + ctx->printable_pid, ctx->reader, ctx->log_fp, ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0, (unsigned long)ctx->stamp, ctx->ready); @@ -602,9 +596,9 @@ ldap_wrapper_release_context (ksba_reader_t reader) if (ctx->reader == reader) { if (DBG_EXTPROG) - log_debug ("releasing ldap worker c=%p pid=%d/%d rdr=%p" + log_debug ("releasing ldap worker c=%p pid=%d rdr=%p" " ctrl=%p/%d\n", ctx, - (int)ctx->pid, (int)ctx->printable_pid, + ctx->printable_pid, ctx->reader, ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0); @@ -639,8 +633,8 @@ ldap_wrapper_connection_cleanup (ctrl_t ctrl) { ctx->ctrl->refcount--; ctx->ctrl = NULL; - if (ctx->pid != (pid_t)(-1)) - gnupg_kill_process (ctx->pid); + if (ctx->proc) + gnupg_process_terminate (ctx->proc); if (ctx->fp_err) log_info ("%s: reading from ldap wrapper %d failed: %s\n", __func__, ctx->printable_pid, gpg_strerror (ctx->fp_err)); @@ -798,7 +792,7 @@ gpg_error_t ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[]) { gpg_error_t err; - pid_t pid; + gnupg_process_t process; struct wrapper_context_s *ctx; int i; int j; @@ -854,19 +848,22 @@ ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[]) return err; } - err = gnupg_spawn_process (pgmname, arg_list, - NULL, GNUPG_SPAWN_NONBLOCK, - NULL, &outfp, &errfp, &pid); + err = gnupg_process_spawn (pgmname, arg_list, + (GNUPG_PROCESS_STDOUT_PIPE + | GNUPG_PROCESS_STDERR_PIPE), + NULL, NULL, &process); if (err) { - xfree (arg_list); + xfree (arg_list); xfree (ctx); log_error ("error running '%s': %s\n", pgmname, gpg_strerror (err)); return err; } + gnupg_process_get_streams (process, GNUPG_PROCESS_STREAM_NONBLOCK, + NULL, &outfp, &errfp); + gnupg_process_ctl (process, GNUPG_PROCESS_GET_PROC_ID, &ctx->printable_pid); - ctx->pid = pid; - ctx->printable_pid = (int) pid; + ctx->proc = process; ctx->fp = outfp; ctx->log_fp = errfp; ctx->ctrl = ctrl; @@ -902,7 +899,7 @@ ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[]) if (DBG_EXTPROG) { log_debug ("ldap wrapper %d started (%p, %s)", - (int)ctx->pid, ctx->reader, pgmname); + ctx->printable_pid, ctx->reader, pgmname); for (i=0; arg_list[i]; i++) log_printf (" [%s]", arg_list[i]); log_printf ("\n"); diff --git a/g10/photoid.c b/g10/photoid.c index 72e6acf7d..a866eb083 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -594,34 +594,35 @@ run_with_pipe (struct spawn_info *info, const void *image, u32 len) " external programs\n")); return; #else /* !EXEC_TEMPFILE_ONLY */ - int to[2]; - pid_t pid; gpg_error_t err; const char *argv[4]; - - err = gnupg_create_pipe (to); - if (err) - return; + gnupg_process_t proc; fill_command_argv (argv, info->command); - err = gnupg_spawn_process_fd (argv[0], argv+1, to[0], -1, -1, &pid); - - close (to[0]); - + err = gnupg_process_spawn (argv[0], argv+1, GNUPG_PROCESS_STDIN_PIPE, + NULL, NULL, &proc); if (err) - { - log_error (_("unable to execute shell '%s': %s\n"), - argv[0], gpg_strerror (err)); - close (to[1]); - } + log_error (_("unable to execute shell '%s': %s\n"), + argv[0], gpg_strerror (err)); else { - write (to[1], image, len); - close (to[1]); + int fd_in; - err = gnupg_wait_process (argv[0], pid, 1, NULL); + err = gnupg_process_get_fds (proc, 0, &fd_in, NULL, NULL); + if (err) + log_error ("unable to get pipe connection '%s': %s\n", + argv[2], gpg_strerror (err)); + else + { + write (fd_in, image, len); + close (fd_in); + } + + err = gnupg_process_wait (proc, 1); if (err) log_error (_("unnatural exit of external program\n")); + + gnupg_process_release (proc); } #endif /* !EXEC_TEMPFILE_ONLY */ } @@ -689,14 +690,11 @@ show_photo (const char *command, const char *name, const void *image, u32 len) log_error (_("system error while calling external program: %s\n"), strerror (errno)); #else - pid_t pid; gpg_error_t err; const char *argv[4]; fill_command_argv (argv, spawn->command); - err = gnupg_spawn_process_fd (argv[0], argv+1, -1, -1, -1, &pid); - if (!err) - err = gnupg_wait_process (argv[0], pid, 1, NULL); + err = gnupg_process_spawn (argv[0], argv+1, 0, NULL, NULL, NULL); if (err) log_error (_("unnatural exit of external program\n")); #endif diff --git a/g13/be-encfs.c b/g13/be-encfs.c index 0e2c68bf3..ac6d6d6cd 100644 --- a/g13/be-encfs.c +++ b/g13/be-encfs.c @@ -28,10 +28,10 @@ #include "g13.h" #include "../common/i18n.h" #include "keyblob.h" -#include "be-encfs.h" -#include "runner.h" #include "../common/sysutils.h" #include "../common/exechelp.h" +#include "runner.h" +#include "be-encfs.h" /* Command values used to run the encfs tool. */ @@ -81,7 +81,9 @@ run_umount_helper (const char *mountpoint) args[1] = mountpoint; args[2] = NULL; - err = gnupg_spawn_process_detached (pgmname, args, NULL); + err = gnupg_process_spawn (pgmname, args, + GNUPG_PROCESS_DETACHED, + NULL, NULL, NULL); if (err) log_error ("failed to run '%s': %s\n", pgmname, gpg_strerror (err)); @@ -218,12 +220,11 @@ run_encfs_tool (ctrl_t ctrl, enum encfs_cmds cmd, gpg_error_t err; encfs_parm_t parm; runner_t runner = NULL; - int outbound[2] = { -1, -1 }; - int inbound[2] = { -1, -1 }; const char *pgmname; const char *argv[10]; - pid_t pid = (pid_t)(-1); int idx; + gnupg_process_t proc; + int inbound, outbound; (void)ctrl; @@ -246,15 +247,6 @@ run_encfs_tool (ctrl_t ctrl, enum encfs_cmds cmd, if (err) goto leave; - err = gnupg_create_inbound_pipe (inbound, NULL, 0); - if (!err) - err = gnupg_create_outbound_pipe (outbound, NULL, 0); - if (err) - { - log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); - goto leave; - } - pgmname = ENCFS; idx = 0; argv[idx++] = "-f"; @@ -267,47 +259,42 @@ run_encfs_tool (ctrl_t ctrl, enum encfs_cmds cmd, argv[idx++] = NULL; assert (idx <= DIM (argv)); - err = gnupg_spawn_process_fd (pgmname, argv, - outbound[0], -1, inbound[1], &pid); + err = gnupg_process_spawn (pgmname, argv, + (GNUPG_PROCESS_STDIN_PIPE + | GNUPG_PROCESS_STDERR_PIPE), + NULL, NULL, &proc); if (err) { log_error ("error spawning '%s': %s\n", pgmname, gpg_strerror (err)); goto leave; } - close (outbound[0]); outbound[0] = -1; - close ( inbound[1]); inbound[1] = -1; - runner_set_fds (runner, inbound[0], outbound[1]); - inbound[0] = -1; /* Now owned by RUNNER. */ - outbound[1] = -1; /* Now owned by RUNNER. */ + err = gnupg_process_get_fds (proc, 0, &outbound, NULL, &inbound); + if (err) + { + log_error ("error get fds '%s': %s\n", pgmname, gpg_strerror (err)); + gnupg_process_release (proc); + goto leave; + } + + runner_set_fds (runner, inbound, outbound); runner_set_handler (runner, encfs_handler, encfs_handler_cleanup, parm); parm = NULL; /* Now owned by RUNNER. */ - runner_set_pid (runner, pid); - pid = (pid_t)(-1); /* The process is now owned by RUNNER. */ + runner_set_proc (runner, proc); err = runner_spawn (runner); if (err) - goto leave; + { + gnupg_process_release (proc); + goto leave; + } *r_id = runner_get_rid (runner); log_info ("running '%s' in the background\n", pgmname); leave: - if (inbound[0] != -1) - close (inbound[0]); - if (inbound[1] != -1) - close (inbound[1]); - if (outbound[0] != -1) - close (outbound[0]); - if (outbound[1] != -1) - close (outbound[1]); - if (pid != (pid_t)(-1)) - { - gnupg_wait_process (pgmname, pid, 1, NULL); - gnupg_release_process (pid); - } runner_release (runner); encfs_handler_cleanup (parm); return err; diff --git a/g13/g13.c b/g13/g13.c index 2bbb453eb..785c91950 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -40,6 +40,7 @@ #include "../common/gc-opt-flags.h" #include "../common/asshelp.h" #include "../common/init.h" +#include "../common/exechelp.h" #include "keyblob.h" #include "server.h" #include "runner.h" diff --git a/g13/mount.c b/g13/mount.c index 45b60806c..071b76b67 100644 --- a/g13/mount.c +++ b/g13/mount.c @@ -34,10 +34,11 @@ #include "backend.h" #include "g13tuple.h" #include "mountinfo.h" -#include "runner.h" #include "../common/host2net.h" #include "server.h" /*(g13_keyblob_decrypt)*/ #include "../common/sysutils.h" +#include "../common/exechelp.h" +#include "runner.h" #include "call-syshelp.h" diff --git a/g13/runner.c b/g13/runner.c index b08d99030..c0534fe5d 100644 --- a/g13/runner.c +++ b/g13/runner.c @@ -29,8 +29,8 @@ #include "g13.h" #include "../common/i18n.h" #include "keyblob.h" -#include "runner.h" #include "../common/exechelp.h" +#include "runner.h" #include "mountinfo.h" /* The runner object. */ @@ -55,7 +55,7 @@ struct runner_s 2 = Thread is running and someone is holding a reference. */ int refcount; - pid_t pid; /* PID of the backend's process (the engine). */ + gnupg_process_t proc; /* Process of the backend's process (the engine). */ int in_fd; /* File descriptors to read from the engine. */ int out_fd; /* File descriptors to write to the engine. */ engine_handler_fnc_t handler; /* The handler functions. */ @@ -157,16 +157,16 @@ runner_release (runner_t runner) if (runner->handler_cleanup) runner->handler_cleanup (runner->handler_data); - if (runner->pid != (pid_t)(-1)) + if (runner->proc) { /* The process has not been cleaned up - do it now. */ - gnupg_kill_process (runner->pid); + gnupg_process_terminate (runner->proc); /* (Actually we should use the program name and not the arbitrary NAME of the runner object. However it does not matter because that information is only used for diagnostics.) */ - gnupg_wait_process (runner->name, runner->pid, 1, NULL); - gnupg_release_process (runner->pid); + gnupg_process_wait (runner->proc, 1); + gnupg_process_release (runner->proc); } xfree (runner->name); @@ -212,7 +212,7 @@ runner_new (runner_t *r_runner, const char *name) return gpg_error_from_syserror (); } runner->refcount = 1; - runner->pid = (pid_t)(-1); + runner->proc = NULL; runner->in_fd = -1; runner->out_fd = -1; @@ -266,15 +266,15 @@ runner_set_fds (runner_t runner, int in_fd, int out_fd) } -/* Set the PID of the backend engine. After this call the engine is +/* Set the PROC of the backend engine. After this call the engine is owned by the runner object. */ void -runner_set_pid (runner_t runner, pid_t pid) +runner_set_proc (runner_t runner, gnupg_process_t proc) { - if (check_already_spawned (runner, "runner_set_fds")) + if (check_already_spawned (runner, "runner_set_proc")) return; - runner->pid = pid; + runner->proc = proc; } @@ -366,15 +366,17 @@ runner_thread (void *arg) } /* Now wait for the process to finish. */ - if (!err && runner->pid != (pid_t)(-1)) + if (!err && runner->proc) { int exitcode; log_debug ("runner thread waiting ...\n"); - err = gnupg_wait_process (runner->name, runner->pid, 1, &exitcode); - gnupg_release_process (runner->pid); - runner->pid = (pid_t)(-1); - if (err) + err = gnupg_process_wait (runner->proc, 1); + if (!err) + gnupg_process_ctl (runner->proc, GNUPG_PROCESS_GET_EXIT_ID, &exitcode); + gnupg_process_release (runner->proc); + runner->proc = NULL; + if (exitcode) log_error ("running '%s' failed (exitcode=%d): %s\n", runner->name, exitcode, gpg_strerror (err)); log_debug ("runner thread waiting finished\n"); @@ -473,7 +475,7 @@ runner_cancel (runner_t runner) need to change the thread to wait on an event. */ runner->cancel_flag = 1; /* For now we use the brutal way and kill the process. */ - gnupg_kill_process (runner->pid); + gnupg_process_terminate (runner->proc); } } diff --git a/g13/runner.h b/g13/runner.h index 36181adf9..01c395e02 100644 --- a/g13/runner.h +++ b/g13/runner.h @@ -49,7 +49,7 @@ runner_t runner_find_by_rid (unsigned int rid); /* Functions to set properties of the runner. */ void runner_set_fds (runner_t runner, int in_fd, int out_fd); -void runner_set_pid (runner_t runner, pid_t pid); +void runner_set_proc (runner_t runner, gnupg_process_t proc); /* Register the handler functions with a runner. */ void runner_set_handler (runner_t runner, diff --git a/scd/app.c b/scd/app.c index 3686c0f6c..468fed294 100644 --- a/scd/app.c +++ b/scd/app.c @@ -2333,6 +2333,18 @@ app_check_pin (card_t card, ctrl_t ctrl, const char *keyidstr, } +static void +setup_env (struct spawn_cb_arg *sca) +{ +#ifdef HAVE_W32_SYSTEM + (void)sca; /* Not supported on Windows. */ +#else + char *v = sca->arg; + + putenv (v); +#endif +} + static void report_change (int slot, int old_status, int cur_status) { @@ -2360,12 +2372,9 @@ report_change (int slot, int old_status, int cur_status) else { gpg_error_t err; - const char *args[9], *envs[2]; + const char *args[9]; char numbuf1[30], numbuf2[30], numbuf3[30]; - envs[0] = envstr; - envs[1] = NULL; - sprintf (numbuf1, "%d", slot); sprintf (numbuf2, "0x%04X", old_status); sprintf (numbuf3, "0x%04X", cur_status); @@ -2382,7 +2391,9 @@ report_change (int slot, int old_status, int cur_status) args[8] = NULL; fname = make_filename (gnupg_homedir (), "scd-event", NULL); - err = gnupg_spawn_process_detached (fname, args, envs); + err = gnupg_process_spawn (fname, args, + GNUPG_PROCESS_DETACHED, + setup_env, envstr, NULL); if (err && gpg_err_code (err) != GPG_ERR_ENOENT) log_error ("failed to run event handler '%s': %s\n", fname, gpg_strerror (err)); diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index ce18e0794..b46d5cb61 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -42,6 +42,9 @@ #endif #include "../../common/util.h" +#ifdef HAVE_W32_SYSTEM +#define NEED_STRUCT_SPAWN_CB_ARG +#endif #include "../../common/exechelp.h" #include "../../common/sysutils.h" @@ -753,25 +756,86 @@ do_es_write (scheme *sc, pointer args) } - /* Process handling. */ +struct proc_object_box +{ + gnupg_process_t proc; +}; + +static void +proc_object_finalize (scheme *sc, void *data) +{ + struct proc_object_box *box = data; + (void) sc; + + if (!box->proc) + gnupg_process_release (box->proc); + xfree (box); +} + +static void +proc_object_to_string (scheme *sc, char *out, size_t size, void *data) +{ + struct proc_object_box *box = data; + (void) sc; + + snprintf (out, size, "#proc %p", box->proc); +} + +static struct foreign_object_vtable proc_object_vtable = + { + proc_object_finalize, + proc_object_to_string, + }; + static pointer -do_spawn_process (scheme *sc, pointer args) +proc_wrap (scheme *sc, gnupg_process_t proc) +{ + struct proc_object_box *box = xmalloc (sizeof *box); + if (box == NULL) + return sc->NIL; + + box->proc = proc; + return sc->vptr->mk_foreign_object (sc, &proc_object_vtable, box); +} + +static struct proc_object_box * +proc_unwrap (scheme *sc, pointer object) +{ + (void) sc; + + if (! is_foreign_object (object)) + return NULL; + + if (sc->vptr->get_foreign_object_vtable (object) != &proc_object_vtable) + return NULL; + + return sc->vptr->get_foreign_object_data (object); +} + +#define CONVERSION_proc(SC, X) proc_unwrap (SC, X) +#define IS_A_proc(SC, X) proc_unwrap (SC, X) + + +static pointer +do_process_spawn (scheme *sc, pointer args) { FFI_PROLOG (); pointer arguments; char **argv; size_t len; unsigned int flags; - + gnupg_process_t proc = NULL; estream_t infp; estream_t outfp; estream_t errfp; - pid_t pid; FFI_ARG_OR_RETURN (sc, pointer, arguments, list, args); FFI_ARG_OR_RETURN (sc, unsigned int, flags, number, args); + flags |= (GNUPG_PROCESS_STDIN_PIPE + | GNUPG_PROCESS_STDOUT_PIPE + | GNUPG_PROCESS_STDERR_PIPE); FFI_ARGS_DONE_OR_RETURN (sc, args); err = ffi_list2argv (sc, arguments, &argv, &len); @@ -791,38 +855,55 @@ do_spawn_process (scheme *sc, pointer args) fprintf (stderr, "\n"); } - err = gnupg_spawn_process (argv[0], (const char **) &argv[1], - NULL, - flags, - &infp, &outfp, &errfp, &pid); + err = gnupg_process_spawn (argv[0], (const char **) &argv[1], + flags, NULL, NULL, &proc); + err = gnupg_process_get_streams (proc, 0, &infp, &outfp, &errfp); xfree (argv); -#define IMC(A, B) \ - _cons (sc, sc->vptr->mk_integer (sc, (unsigned long) (A)), (B), 1) +#define IMP(A, B) \ + _cons (sc, proc_wrap (sc, (A)), (B), 1) #define IMS(A, B) \ _cons (sc, es_wrap (sc, (A)), (B), 1) FFI_RETURN_POINTER (sc, IMS (infp, IMS (outfp, IMS (errfp, - IMC (pid, sc->NIL))))); + IMP (proc, sc->NIL))))); #undef IMS #undef IMC } +static void +setup_std_fds (struct spawn_cb_arg *sca) +{ + int *std_fds = sca->arg; + +#ifdef HAVE_W32_SYSTEM + sca->hd[0] = std_fds[0] == -1? + INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[0]); + sca->hd[1] = std_fds[1] == -1? + INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[1]); + sca->hd[2] = std_fds[2] == -1? + INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[2]); +#else + sca->fds[0] = std_fds[0]; + sca->fds[1] = std_fds[1]; + sca->fds[2] = std_fds[2]; +#endif +} + static pointer -do_spawn_process_fd (scheme *sc, pointer args) +do_process_spawn_fd (scheme *sc, pointer args) { FFI_PROLOG (); pointer arguments; char **argv; size_t len; - int infd, outfd, errfd; - - pid_t pid; + int std_fds[3]; + gnupg_process_t proc = NULL; FFI_ARG_OR_RETURN (sc, pointer, arguments, list, args); - FFI_ARG_OR_RETURN (sc, int, infd, number, args); - FFI_ARG_OR_RETURN (sc, int, outfd, number, args); - FFI_ARG_OR_RETURN (sc, int, errfd, number, args); + FFI_ARG_OR_RETURN (sc, int, std_fds[0], number, args); + FFI_ARG_OR_RETURN (sc, int, std_fds[1], number, args); + FFI_ARG_OR_RETURN (sc, int, std_fds[2], number, args); FFI_ARGS_DONE_OR_RETURN (sc, args); err = ffi_list2argv (sc, arguments, &argv, &len); @@ -839,107 +920,35 @@ do_spawn_process_fd (scheme *sc, pointer args) fprintf (stderr, "Executing:"); for (p = argv; *p; p++) fprintf (stderr, " '%s'", *p); - fprintf (stderr, "\n"); + fprintf (stderr, " (%d %d %d)\n", std_fds[0], std_fds[1], std_fds[2]); } - err = gnupg_spawn_process_fd (argv[0], (const char **) &argv[1], - infd, outfd, errfd, &pid); + err = gnupg_process_spawn (argv[0], (const char **) &argv[1], + 0, setup_std_fds, std_fds, &proc); xfree (argv); - FFI_RETURN_INT (sc, pid); + FFI_RETURN_POINTER (sc, proc_wrap (sc, proc)); } static pointer -do_wait_process (scheme *sc, pointer args) +do_process_wait (scheme *sc, pointer args) { FFI_PROLOG (); - const char *name; - pid_t pid; + struct proc_object_box *box; int hang; + int retcode = -1; - int retcode; - - FFI_ARG_OR_RETURN (sc, const char *, name, string, args); - FFI_ARG_OR_RETURN (sc, pid_t, pid, number, args); + FFI_ARG_OR_RETURN (sc, struct proc_object_box *, box, proc, args); FFI_ARG_OR_RETURN (sc, int, hang, bool, args); FFI_ARGS_DONE_OR_RETURN (sc, args); - err = gnupg_wait_process (name, pid, hang, &retcode); - if (err == GPG_ERR_GENERAL) - err = 0; /* Let the return code speak for itself. */ + err = gnupg_process_wait (box->proc, hang); + if (!err) + err = gnupg_process_ctl (box->proc, GNUPG_PROCESS_GET_EXIT_ID, &retcode); + if (err == GPG_ERR_TIMEOUT) + err = 0; FFI_RETURN_INT (sc, retcode); } - -static pointer -do_wait_processes (scheme *sc, pointer args) -{ - FFI_PROLOG (); - pointer list_names; - char **names; - pointer list_pids; - size_t i, count; - pid_t *pids; - int hang; - int *retcodes; - pointer retcodes_list = sc->NIL; - - FFI_ARG_OR_RETURN (sc, pointer, list_names, list, args); - FFI_ARG_OR_RETURN (sc, pointer, list_pids, list, args); - FFI_ARG_OR_RETURN (sc, int, hang, bool, args); - FFI_ARGS_DONE_OR_RETURN (sc, args); - - if (sc->vptr->list_length (sc, list_names) - != sc->vptr->list_length (sc, list_pids)) - return - sc->vptr->mk_string (sc, "length of first two arguments must match"); - - err = ffi_list2argv (sc, list_names, &names, &count); - if (err == gpg_error (GPG_ERR_INV_VALUE)) - return ffi_sprintf (sc, "%lu%s element of first argument is " - "neither string nor symbol", - (unsigned long) count, - ordinal_suffix ((int) count)); - if (err) - FFI_RETURN_ERR (sc, err); - - err = ffi_list2intv (sc, list_pids, (int **) &pids, &count); - if (err == gpg_error (GPG_ERR_INV_VALUE)) - return ffi_sprintf (sc, "%lu%s element of second argument is " - "not a number", - (unsigned long) count, - ordinal_suffix ((int) count)); - if (err) - FFI_RETURN_ERR (sc, err); - - retcodes = xtrycalloc (sizeof *retcodes, count); - if (retcodes == NULL) - { - xfree (names); - xfree (pids); - FFI_RETURN_ERR (sc, gpg_error_from_syserror ()); - } - - err = gnupg_wait_processes ((const char **) names, pids, count, hang, - retcodes); - if (err == GPG_ERR_GENERAL) - err = 0; /* Let the return codes speak. */ - if (err == GPG_ERR_TIMEOUT) - err = 0; /* We may have got some results. */ - - for (i = 0; i < count; i++) - retcodes_list = - (sc->vptr->cons) (sc, - sc->vptr->mk_integer (sc, - (long) retcodes[count-1-i]), - retcodes_list); - - xfree (names); - xfree (pids); - xfree (retcodes); - FFI_RETURN_POINTER (sc, retcodes_list); -} - - static pointer do_pipe (scheme *sc, pointer args) { @@ -1398,13 +1407,12 @@ ffi_init (scheme *sc, const char *argv0, const char *scriptname, ffi_define_function (sc, make_random_string); /* Process management. */ - ffi_define_function (sc, spawn_process); - ffi_define_function (sc, spawn_process_fd); - ffi_define_function (sc, wait_process); - ffi_define_function (sc, wait_processes); ffi_define_function (sc, pipe); ffi_define_function (sc, inbound_pipe); ffi_define_function (sc, outbound_pipe); + ffi_define_function (sc, process_spawn); + ffi_define_function (sc, process_spawn_fd); + ffi_define_function (sc, process_wait); /* estream functions. */ ffi_define_function_name (sc, "es-fclose", es_fclose); diff --git a/tests/gpgscm/t-child.scm b/tests/gpgscm/t-child.scm index fd1dcc3fe..461413b9c 100644 --- a/tests/gpgscm/t-child.scm +++ b/tests/gpgscm/t-child.scm @@ -69,37 +69,36 @@ (assert (string=? "" (:stderr r)))) (define (spawn what) - (spawn-process-fd what CLOSED_FD STDOUT_FILENO STDERR_FILENO)) + (process-spawn-fd what CLOSED_FD STDOUT_FILENO STDERR_FILENO)) -(let ((pid0 (spawn `(,(qualify "t-child") "return0"))) - (pid1 (spawn `(,(qualify "t-child") "return0")))) - (assert (equal? '(0 0) - (wait-processes '("child0" "child1") (list pid0 pid1) #t)))) +(let ((proc0 (spawn `(,(qualify "t-child") "return0"))) + (proc1 (spawn `(,(qualify "t-child") "return0")))) + (assert (= (process-wait proc0 #t) 0)) + (assert (= (process-wait proc1 #t) 0))) -(let ((pid0 (spawn `(,(qualify "t-child") "return1"))) - (pid1 (spawn `(,(qualify "t-child") "return0")))) - (assert (equal? '(1 0) - (wait-processes '("child0" "child1") (list pid0 pid1) #t)))) +(let ((proc0 (spawn `(,(qualify "t-child") "return1"))) + (proc1 (spawn `(,(qualify "t-child") "return0")))) + (assert (= (process-wait proc0 #t) 1)) + (assert (= (process-wait proc1 #t) 0))) -(let ((pid0 (spawn `(,(qualify "t-child") "return0"))) - (pid1 (spawn `(,(qualify "t-child") "return77"))) - (pid2 (spawn `(,(qualify "t-child") "return1")))) - (assert (equal? '(0 77 1) - (wait-processes '("child0" "child1" "child2") - (list pid0 pid1 pid2) #t)))) +(let ((proc0 (spawn `(,(qualify "t-child") "return0"))) + (proc1 (spawn `(,(qualify "t-child") "return77"))) + (proc2 (spawn `(,(qualify "t-child") "return1")))) + (assert (= (process-wait proc0 #t) 0)) + (assert (= (process-wait proc1 #t) 77)) + (assert (= (process-wait proc2 #t) 1))) (let* ((p (pipe)) - (pid0 (spawn-process-fd + (proc0 (process-spawn-fd `(,(qualify "t-child") "hello_stdout") CLOSED_FD (:write-end p) STDERR_FILENO)) (_ (close (:write-end p))) - (pid1 (spawn-process-fd + (proc1 (process-spawn-fd `(,(qualify "t-child") "cat") (:read-end p) STDOUT_FILENO STDERR_FILENO))) (close (:read-end p)) - (assert - (equal? '(0 0) - (wait-processes '("child0" "child1") (list pid0 pid1) #t)))) + (assert (= (process-wait proc0 #t) 0)) + (assert (= (process-wait proc1 #t) 0))) (echo " world.") (tr:do diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm index db1025bbb..6a11e55f1 100644 --- a/tests/gpgscm/tests.scm +++ b/tests/gpgscm/tests.scm @@ -81,7 +81,7 @@ ;; Process management. (define CLOSED_FD -1) (define (call-with-fds what infd outfd errfd) - (wait-process (stringify what) (spawn-process-fd what infd outfd errfd) #t)) + (process-wait (process-spawn-fd what infd outfd errfd) #t)) (define (call what) (call-with-fds what CLOSED_FD @@ -92,19 +92,19 @@ (define :stdin car) (define :stdout cadr) (define :stderr caddr) -(define :pid cadddr) +(define :proc cadddr) (define (call-with-io what in) - (let ((h (spawn-process what 0))) + (let ((h (process-spawn what 0))) (es-write (:stdin h) in) (es-fclose (:stdin h)) (let* ((out (es-read-all (:stdout h))) (err (es-read-all (:stderr h))) - (result (wait-process (car what) (:pid h) #t))) + (result (process-wait (:proc h) #t))) (es-fclose (:stdout h)) (es-fclose (:stderr h)) (if (> (*verbose*) 2) - (info "Child" (:pid h) "returned:" + (info "Child" (:proc h) "returned:" `((command ,(stringify what)) (status ,result) (stdout ,out) @@ -351,12 +351,8 @@ (define (dump) (write (list procs source sink producer)) (newline)) - (define (add-proc command pid) - (new (cons (list command pid) procs) source sink producer)) - (define (commands) - (map car procs)) - (define (pids) - (map cadr procs)) + (define (add-proc proc) + (new (cons proc procs) source sink producer)) (define (set-source source') (new procs source' sink producer)) (define (set-sink sink') @@ -367,17 +363,19 @@ (new procs source sink producer')))))) +(define (process-wait-list procs hang) + (map (lambda (p) (process-wait p hang)) procs)) + (define (pipe:do . commands) (let loop ((M (pipeM::new '() CLOSED_FD CLOSED_FD #f)) (cmds commands)) (if (null? cmds) (begin (if M::producer (M::producer)) (if (not (null? M::procs)) - (let* ((retcodes (wait-processes (map stringify (M::commands)) - (M::pids) #t)) - (results (map (lambda (p r) (append p (list r))) + (let* ((retcodes (process-wait-list M::procs #t)) + (results (map (lambda (p r) (cons p r)) M::procs retcodes)) - (failed (filter (lambda (x) (not (= 0 (caddr x)))) + (failed (filter (lambda (x) (not (= 0 (cdr x)))) results))) (if (not (null? failed)) (throw failed))))) ; xxx nicer reporting @@ -408,11 +406,11 @@ (define (pipe:spawn command) (lambda (M) (define (do-spawn M new-source) - (let ((pid (spawn-process-fd command M::source M::sink - (if (> (*verbose*) 0) - STDERR_FILENO CLOSED_FD))) + (let ((proc (process-spawn-fd command M::source M::sink + (if (> (*verbose*) 0) + STDERR_FILENO CLOSED_FD))) (M' (M::set-source new-source))) - (M'::add-proc command pid))) + (M'::add-proc proc))) (if (= CLOSED_FD M::sink) (let* ((p (pipe)) (M' (do-spawn (M::set-sink (:write-end p)) (:read-end p)))) @@ -568,8 +566,8 @@ (assert (= (length enqueued) (- i 1))) test))))) - (define (pid->test pid) - (let ((t (filter (lambda (x) (= pid x::pid)) procs))) + (define (proc->test proc) + (let ((t (filter (lambda (x) (eq? proc x::proc)) procs))) (if (null? t) #f (car t)))) (define (wait) (if (null? enqueued) @@ -587,7 +585,7 @@ (if (null? unfinished) (current-environment) (let ((names (map (lambda (t) t::name) unfinished)) - (pids (map (lambda (t) t::pid) unfinished)) + (procs (map (lambda (t) t::proc) unfinished)) (any #f)) (for-each (lambda (test retcode) @@ -597,8 +595,8 @@ (test::report) (sem::release!) (set! any #t))) - (map pid->test pids) - (wait-processes (map stringify names) pids hang)) + (map proc->test procs) + (process-wait-list procs hang)) ;; If some processes finished, try to start new ones. (let loop () @@ -682,7 +680,7 @@ (define (scm setup variant name path . args) ;; Start the process. (define (spawn-scm args' in out err) - (spawn-process-fd `(,*argv0* ,@(verbosity (*verbose*)) + (process-spawn-fd `(,*argv0* ,@(verbosity (*verbose*)) ,(locate-test (test-name path)) ,@(if setup (force setup) '()) ,@args' ,@args) in out err)) @@ -691,12 +689,12 @@ (define (binary setup name path . args) ;; Start the process. (define (spawn-binary args' in out err) - (spawn-process-fd `(,(test-name path) + (process-spawn-fd `(,(test-name path) ,@(if setup (force setup) '()) ,@args' ,@args) in out err)) (new #f name #f spawn-binary #f #f CLOSED_FD (expect-failure? name))) - (define (new variant name directory spawn pid retcode logfd expect-failure) + (define (new variant name directory spawn proc retcode logfd expect-failure) (package ;; XXX: OO glue. @@ -721,7 +719,7 @@ ;; Has the test been started yet? (define (started?) - (number? pid)) + proc) (define (open-log-file) (unless log-file-name @@ -738,26 +736,26 @@ (letfd ((log (open-log-file))) (with-working-directory directory (let* ((p (inbound-pipe)) - (pid' (spawn args 0 (:write-end p) (:write-end p)))) + (proc' (spawn args 0 (:write-end p) (:write-end p)))) (close (:write-end p)) (splice (:read-end p) STDERR_FILENO log) (close (:read-end p)) - (set! pid pid') - (set! retcode (wait-process name pid' #t))))) + (set! proc proc') + (set! retcode (process-wait proc' #t))))) (report) (current-environment)) (define (run-sync-quiet . args) (set-start-time!) (with-working-directory directory - (set! pid (spawn args CLOSED_FD CLOSED_FD CLOSED_FD))) - (set! retcode (wait-process name pid #t)) + (set! proc (spawn args CLOSED_FD CLOSED_FD CLOSED_FD))) + (set! retcode (process-wait proc #t)) (set-end-time!) (current-environment)) (define (run-async . args) (set-start-time!) (let ((log (open-log-file))) (with-working-directory directory - (set! pid (spawn args CLOSED_FD log log))) + (set! proc (spawn args CLOSED_FD log log))) (set! logfd log)) (current-environment)) (define (status) diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm index bf3714f50..1ac25bf65 100644 --- a/tests/openpgp/defs.scm +++ b/tests/openpgp/defs.scm @@ -268,13 +268,14 @@ (define (gpg-pipe args0 args1 errfd) (lambda (source sink) (let* ((p (pipe)) - (task0 (spawn-process-fd `(,@GPG ,@args0) + (task0 (process-spawn-fd `(,@GPG ,@args0) source (:write-end p) errfd)) (_ (close (:write-end p))) - (task1 (spawn-process-fd `(,@GPG ,@args1) + (task1 (process-spawn-fd `(,@GPG ,@args1) (:read-end p) sink errfd))) (close (:read-end p)) - (wait-processes (list GPG GPG) (list task0 task1) #t)))) + (process-wait task0 #t) + (process-wait task1 #t)))) (setenv "GPG_AGENT_INFO" "" #t) (setenv "GNUPGHOME" (getcwd) #t) diff --git a/tests/tpm2dtests/defs.scm b/tests/tpm2dtests/defs.scm index 0fef71806..a913818f5 100644 --- a/tests/tpm2dtests/defs.scm +++ b/tests/tpm2dtests/defs.scm @@ -217,13 +217,14 @@ (define (gpg-pipe args0 args1 errfd) (lambda (source sink) (let* ((p (pipe)) - (task0 (spawn-process-fd `(,@GPG ,@args0) + (task0 (process-spawn-fd `(,@GPG ,@args0) source (:write-end p) errfd)) (_ (close (:write-end p))) - (task1 (spawn-process-fd `(,@GPG ,@args1) + (task1 (process-spawn-fd `(,@GPG ,@args1) (:read-end p) sink errfd))) (close (:read-end p)) - (wait-processes (list GPG GPG) (list task0 task1) #t)))) + (process-wait task0 #t) + (process-wait task1 #t)))) ;; ;; Do we have a software tpm diff --git a/tools/gpg-card.c b/tools/gpg-card.c index a94aabea9..919e61195 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -3641,7 +3641,7 @@ cmd_gpg (card_info_t info, char *argstr, int use_gpgsm) char **argarray; ccparray_t ccp; const char **argv = NULL; - pid_t pid; + gnupg_process_t proc; int i; if (!info) @@ -3669,15 +3669,15 @@ cmd_gpg (card_info_t info, char *argstr, int use_gpgsm) goto leave; } - err = gnupg_spawn_process (use_gpgsm? opt.gpgsm_program:opt.gpg_program, - argv, NULL, (GNUPG_SPAWN_KEEP_STDOUT - |GNUPG_SPAWN_KEEP_STDERR), - NULL, NULL, NULL, &pid); + err = gnupg_process_spawn (use_gpgsm? opt.gpgsm_program:opt.gpg_program, + argv, + (GNUPG_PROCESS_STDOUT_KEEP + | GNUPG_PROCESS_STDERR_KEEP), + NULL, NULL, &proc); if (!err) { - err = gnupg_wait_process (use_gpgsm? opt.gpgsm_program:opt.gpg_program, - pid, 1, NULL); - gnupg_release_process (pid); + err = gnupg_process_wait (proc, 1); + gnupg_process_release (proc); } diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 90f2f53d3..d6aa9d61b 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -744,7 +744,7 @@ gpg_agent_runtime_change (int killflag) gpg_error_t err = 0; const char *pgmname; const char *argv[5]; - pid_t pid = (pid_t)(-1); + gnupg_process_t proc = NULL; int i = 0; int cmdidx; @@ -761,13 +761,13 @@ gpg_agent_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); if (!err) - err = gnupg_wait_process (pgmname, pid, 1, NULL); + err = gnupg_process_wait (proc, 1); if (err) gc_error (0, 0, "error running '%s %s': %s", pgmname, argv[cmdidx], gpg_strerror (err)); - gnupg_release_process (pid); + gnupg_process_release (proc); } @@ -777,7 +777,7 @@ scdaemon_runtime_change (int killflag) gpg_error_t err = 0; const char *pgmname; const char *argv[9]; - pid_t pid = (pid_t)(-1); + gnupg_process_t proc = NULL; int i = 0; int cmdidx; @@ -805,13 +805,13 @@ scdaemon_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); if (!err) - err = gnupg_wait_process (pgmname, pid, 1, NULL); + err = gnupg_process_wait (proc, 1); if (err) gc_error (0, 0, "error running '%s %s': %s", pgmname, argv[cmdidx], gpg_strerror (err)); - gnupg_release_process (pid); + gnupg_process_release (proc); } @@ -822,7 +822,7 @@ tpm2daemon_runtime_change (int killflag) gpg_error_t err = 0; const char *pgmname; const char *argv[9]; - pid_t pid = (pid_t)(-1); + gnupg_process_t proc = NULL; int i = 0; int cmdidx; @@ -850,13 +850,13 @@ tpm2daemon_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); if (!err) - err = gnupg_wait_process (pgmname, pid, 1, NULL); + err = gnupg_process_wait (proc, 1); if (err) gc_error (0, 0, "error running '%s %s': %s", pgmname, argv[cmdidx], gpg_strerror (err)); - gnupg_release_process (pid); + gnupg_process_release (proc); } #endif @@ -867,7 +867,7 @@ dirmngr_runtime_change (int killflag) gpg_error_t err = 0; const char *pgmname; const char *argv[6]; - pid_t pid = (pid_t)(-1); + gnupg_process_t proc = NULL; int i = 0; int cmdidx; @@ -885,13 +885,13 @@ dirmngr_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); if (!err) - err = gnupg_wait_process (pgmname, pid, 1, NULL); + err = gnupg_process_wait (proc, 1); if (err) gc_error (0, 0, "error running '%s %s': %s", pgmname, argv[cmdidx], gpg_strerror (err)); - gnupg_release_process (pid); + gnupg_process_release (proc); } @@ -901,7 +901,7 @@ keyboxd_runtime_change (int killflag) gpg_error_t err = 0; const char *pgmname; const char *argv[6]; - pid_t pid = (pid_t)(-1); + gnupg_process_t proc = NULL; int i = 0; int cmdidx; @@ -919,13 +919,13 @@ keyboxd_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); if (!err) - err = gnupg_wait_process (pgmname, pid, 1, NULL); + err = gnupg_process_wait (proc, 1); if (err) gc_error (0, 0, "error running '%s %s': %s", pgmname, argv[cmdidx], gpg_strerror (err)); - gnupg_release_process (pid); + gnupg_process_release (proc); } @@ -937,7 +937,7 @@ gc_component_launch (int component) const char *pgmname; const char *argv[6]; int i; - pid_t pid; + gnupg_process_t proc = NULL; if (component < 0) { @@ -985,9 +985,9 @@ gc_component_launch (int component) argv[i] = NULL; log_assert (i < DIM(argv)); - err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); if (!err) - err = gnupg_wait_process (pgmname, pid, 1, NULL); + err = gnupg_process_wait (proc, 1); if (err) gc_error (0, 0, "error running '%s%s%s': %s", pgmname, @@ -995,7 +995,7 @@ gc_component_launch (int component) : component == GC_COMPONENT_KEYBOXD? " --keyboxd":"", " NOP", gpg_strerror (err)); - gnupg_release_process (pid); + gnupg_process_release (proc); return err; } @@ -1336,8 +1336,7 @@ gc_component_check_options (int component, estream_t out, const char *conf_file) const char *pgmname; const char *argv[6]; int i; - pid_t pid; - int exitcode; + gnupg_process_t proc; estream_t errfp; error_line_t errlines; @@ -1370,22 +1369,28 @@ gc_component_check_options (int component, estream_t out, const char *conf_file) result = 0; errlines = NULL; - err = gnupg_spawn_process (pgmname, argv, NULL, 0, - NULL, NULL, &errfp, &pid); + err = gnupg_process_spawn (pgmname, argv, + GNUPG_PROCESS_STDERR_PIPE, + NULL, NULL, &proc); if (err) result |= 1; /* Program could not be run. */ else { + gnupg_process_get_streams (proc, 0, NULL, NULL, &errfp); errlines = collect_error_output (errfp, gc_component[component].name); - if (gnupg_wait_process (pgmname, pid, 1, &exitcode)) + if (!gnupg_process_wait (proc, 1)) { + int exitcode; + + gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &exitcode); if (exitcode == -1) result |= 1; /* Program could not be run or it terminated abnormally. */ - result |= 2; /* Program returned an error. */ + else if (exitcode) + result |= 2; /* Program returned an error. */ } - gnupg_release_process (pid); + gnupg_process_release (proc); es_fclose (errfp); } @@ -1725,8 +1730,7 @@ retrieve_options_from_program (gc_component_id_t component, int only_installed) const char *pgmname; const char *argv[2]; estream_t outfp; - int exitcode; - pid_t pid; + gnupg_process_t proc; known_option_t *known_option; gc_option_t *option; char *line = NULL; @@ -1759,14 +1763,17 @@ retrieve_options_from_program (gc_component_id_t component, int only_installed) /* First we need to read the option table from the program. */ argv[0] = "--dump-option-table"; argv[1] = NULL; - err = gnupg_spawn_process (pgmname, argv, NULL, 0, - NULL, &outfp, NULL, &pid); + err = gnupg_process_spawn (pgmname, argv, + GNUPG_PROCESS_STDOUT_PIPE, + NULL, NULL, &proc); if (err) { gc_error (1, 0, "could not gather option table from '%s': %s", pgmname, gpg_strerror (err)); } + gnupg_process_get_streams (proc, 0, NULL, &outfp, NULL); + read_line_parm.pgmname = pgmname; read_line_parm.fp = outfp; read_line_parm.line = line; @@ -1925,12 +1932,17 @@ retrieve_options_from_program (gc_component_id_t component, int only_installed) line_len = read_line_parm.line_len; log_assert (opt_table_used + pseudo_count == opt_info_used); + err = gnupg_process_wait (proc, 1); + if (!err) + { + int exitcode; - err = gnupg_wait_process (pgmname, pid, 1, &exitcode); - if (err) - gc_error (1, 0, "running %s failed (exitcode=%d): %s", - pgmname, exitcode, gpg_strerror (err)); - gnupg_release_process (pid); + gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &exitcode); + if (exitcode) + gc_error (1, 0, "running %s failed (exitcode=%d): %s", + pgmname, exitcode, gpg_strerror (err)); + } + gnupg_process_release (proc); /* Make the gpgrt option table and the internal option table available. */ gc_component[component].opt_table = opt_table; @@ -1940,14 +1952,17 @@ retrieve_options_from_program (gc_component_id_t component, int only_installed) /* Now read the default options. */ argv[0] = "--gpgconf-list"; argv[1] = NULL; - err = gnupg_spawn_process (pgmname, argv, NULL, 0, - NULL, &outfp, NULL, &pid); + err = gnupg_process_spawn (pgmname, argv, + GNUPG_PROCESS_STDOUT_PIPE, + NULL, NULL, &proc); if (err) { gc_error (1, 0, "could not gather active options from '%s': %s", pgmname, gpg_strerror (err)); } + gnupg_process_get_streams (proc, 0, NULL, &outfp, NULL); + while ((length = es_read_line (outfp, &line, &line_len, NULL)) > 0) { char *linep; @@ -2030,11 +2045,17 @@ retrieve_options_from_program (gc_component_id_t component, int only_installed) if (es_fclose (outfp)) gc_error (1, errno, "error closing %s", pgmname); - err = gnupg_wait_process (pgmname, pid, 1, &exitcode); - if (err) - gc_error (1, 0, "running %s failed (exitcode=%d): %s", - pgmname, exitcode, gpg_strerror (err)); - gnupg_release_process (pid); + err = gnupg_process_wait (proc, 1); + if (!err) + { + int exitcode; + + gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &exitcode); + if (exitcode) + gc_error (1, 0, "running %s failed (exitcode=%d): %s", + pgmname, exitcode, gpg_strerror (err)); + } + gnupg_process_release (proc); /* At this point, we can parse the configuration file. */ diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 6dcdc9f3c..522ce517b 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -1173,17 +1173,17 @@ show_versions_via_dirmngr (estream_t fp) const char *pgmname; const char *argv[2]; estream_t outfp; - pid_t pid; + gnupg_process_t proc; char *line = NULL; size_t line_len = 0; ssize_t length; - int exitcode; pgmname = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR); argv[0] = "--gpgconf-versions"; argv[1] = NULL; - err = gnupg_spawn_process (pgmname, argv, NULL, 0, - NULL, &outfp, NULL, &pid); + err = gnupg_process_spawn (pgmname, argv, + GNUPG_PROCESS_STDOUT_PIPE, + NULL, NULL, &proc); if (err) { log_error ("error spawning %s: %s", pgmname, gpg_strerror (err)); @@ -1191,6 +1191,7 @@ show_versions_via_dirmngr (estream_t fp) return; } + gnupg_process_get_streams (proc, 0, NULL, &outfp, NULL); while ((length = es_read_line (outfp, &line, &line_len, NULL)) > 0) { /* Strip newline and carriage return, if present. */ @@ -1211,14 +1212,17 @@ show_versions_via_dirmngr (estream_t fp) pgmname, gpg_strerror (err)); } - err = gnupg_wait_process (pgmname, pid, 1, &exitcode); - if (err) + err = gnupg_process_wait (proc, 1); + if (!err) { + int exitcode; + + gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &exitcode); log_error ("running %s failed (exitcode=%d): %s\n", pgmname, exitcode, gpg_strerror (err)); es_fprintf (fp, "[error: can't get further info]\n"); } - gnupg_release_process (pid); + gnupg_process_release (proc); xfree (line); } diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index 26d37a332..e6f5b55a2 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -1069,7 +1069,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, estream_t files_from_stream = NULL; estream_t outstream = NULL; int eof_seen = 0; - pid_t pid = (pid_t)(-1); + gnupg_process_t proc = NULL; unsigned int skipped_open = 0; memset (scanctrl, 0, sizeof *scanctrl); @@ -1284,14 +1284,15 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, goto leave; } - err = gnupg_spawn_process (opt.gpg_program, argv, - except[0] == -1? NULL : except, - (GNUPG_SPAWN_KEEP_STDOUT - | GNUPG_SPAWN_KEEP_STDERR), - &outstream, NULL, NULL, &pid); + err = gnupg_process_spawn (opt.gpg_program, argv, + (GNUPG_PROCESS_STDIN_PIPE + | GNUPG_PROCESS_STDOUT_KEEP + | GNUPG_PROCESS_STDERR_KEEP), + gnupg_spawn_helper, except, &proc); xfree (argv); if (err) goto leave; + gnupg_process_get_streams (proc, 0, &outstream, NULL, NULL); es_set_binary (outstream); } else if (opt.outfile) /* No crypto */ @@ -1330,23 +1331,25 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, write_progress (1, global_written_files, global_total_files); write_progress (0, global_written_data, global_total_data); - if (pid != (pid_t)(-1)) + if (proc) { - int exitcode; - err = es_fclose (outstream); outstream = NULL; if (err) log_error ("error closing pipe: %s\n", gpg_strerror (err)); - else + + err = gnupg_process_wait (proc, 1); + if (!err) { - err = gnupg_wait_process (opt.gpg_program, pid, 1, &exitcode); - if (err) + int exitcode; + + gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &exitcode); + if (exitcode) log_error ("running %s failed (exitcode=%d): %s", opt.gpg_program, exitcode, gpg_strerror (err)); - gnupg_release_process (pid); - pid = (pid_t)(-1); } + gnupg_process_release (proc); + proc = NULL; } if (skipped_open) @@ -1359,7 +1362,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, if (!err) { gpg_error_t first_err; - if (outstream != es_stdout || pid != (pid_t)(-1)) + if (outstream != es_stdout) first_err = es_fclose (outstream); else first_err = es_fflush (outstream); diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index 936d03e3e..be483f87c 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -339,7 +339,7 @@ gpgtar_extract (const char *filename, int decrypt) char *dirname = NULL; struct tarinfo_s tarinfo_buffer; tarinfo_t tarinfo = &tarinfo_buffer; - pid_t pid = (pid_t)(-1); + gnupg_process_t proc; char *logfilename = NULL; unsigned long long notextracted; @@ -425,14 +425,14 @@ gpgtar_extract (const char *filename, int decrypt) goto leave; } - err = gnupg_spawn_process (opt.gpg_program, argv, - except[0] == -1? NULL : except, - ((filename? 0 : GNUPG_SPAWN_KEEP_STDIN) - | GNUPG_SPAWN_KEEP_STDERR), - NULL, &stream, NULL, &pid); + err = gnupg_process_spawn (opt.gpg_program, argv, + ((filename ? 0 : GNUPG_PROCESS_STDIN_KEEP) + | GNUPG_PROCESS_STDOUT_PIPE), + gnupg_spawn_helper, except, &proc); xfree (argv); if (err) goto leave; + gnupg_process_get_streams (proc, 0, NULL, &stream, NULL); es_set_binary (stream); } else if (filename) @@ -472,23 +472,25 @@ gpgtar_extract (const char *filename, int decrypt) header = NULL; } - if (pid != (pid_t)(-1)) + if (proc) { - int exitcode; - err = es_fclose (stream); stream = NULL; if (err) log_error ("error closing pipe: %s\n", gpg_strerror (err)); - else + + err = gnupg_process_wait (proc, 1); + if (!err) { - err = gnupg_wait_process (opt.gpg_program, pid, 1, &exitcode); - if (err) + int exitcode; + + gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &exitcode); + if (exitcode) log_error ("running %s failed (exitcode=%d): %s", opt.gpg_program, exitcode, gpg_strerror (err)); - gnupg_release_process (pid); - pid = (pid_t)(-1); } + gnupg_process_release (proc); + proc = NULL; } leave: diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c index c5bf25825..31bcd8d46 100644 --- a/tools/gpgtar-list.c +++ b/tools/gpgtar-list.c @@ -460,7 +460,7 @@ gpgtar_list (const char *filename, int decrypt) strlist_t extheader = NULL; struct tarinfo_s tarinfo_buffer; tarinfo_t tarinfo = &tarinfo_buffer; - pid_t pid = (pid_t)(-1); + gnupg_process_t proc = NULL; memset (&tarinfo_buffer, 0, sizeof tarinfo_buffer); @@ -503,14 +503,14 @@ gpgtar_list (const char *filename, int decrypt) goto leave; } - err = gnupg_spawn_process (opt.gpg_program, argv, - except[0] == -1? NULL : except, - ((filename? 0 : GNUPG_SPAWN_KEEP_STDIN) - | GNUPG_SPAWN_KEEP_STDERR), - NULL, &stream, NULL, &pid); + err = gnupg_process_spawn (opt.gpg_program, argv, + ((filename ? 0 : GNUPG_PROCESS_STDIN_KEEP) + | GNUPG_PROCESS_STDOUT_PIPE), + gnupg_spawn_helper, except, &proc); xfree (argv); if (err) goto leave; + gnupg_process_get_streams (proc, 0, NULL, &stream, NULL); es_set_binary (stream); } else if (filename) /* No decryption requested. */ @@ -550,23 +550,24 @@ gpgtar_list (const char *filename, int decrypt) header = NULL; } - if (pid != (pid_t)(-1)) + if (proc) { - int exitcode; - err = es_fclose (stream); stream = NULL; if (err) log_error ("error closing pipe: %s\n", gpg_strerror (err)); - else + + err = gnupg_process_wait (proc, 1); + if (!err) { - err = gnupg_wait_process (opt.gpg_program, pid, 1, &exitcode); - if (err) - log_error ("running %s failed (exitcode=%d): %s", - opt.gpg_program, exitcode, gpg_strerror (err)); - gnupg_release_process (pid); - pid = (pid_t)(-1); + int exitcode; + + gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &exitcode); + log_error ("running %s failed (exitcode=%d): %s", + opt.gpg_program, exitcode, gpg_strerror (err)); } + gnupg_process_release (proc); + proc = NULL; } leave: From 23bb92b755b569d678348c1ccfdbd14a58674dc8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 May 2023 15:50:40 +0200 Subject: [PATCH 002/869] common: Fix malloc nit in regression test. * common/t-iobuf.c: Add boilerplate. (xmalloc): New. Use it everywhere. -- GnuPG-bug-id: 6483 --- common/t-iobuf.c | 56 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/common/t-iobuf.c b/common/t-iobuf.c index bdeab99a4..aacf27a8b 100644 --- a/common/t-iobuf.c +++ b/common/t-iobuf.c @@ -1,3 +1,36 @@ +/* t-iobuf.c - Simple module test for iobuf.c + * Copyright (C) 2015 g10 Code GmbH + * + * This file is part of GnuPG. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either + * + * - the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * or + * + * - the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * or both in parallel, as here. + * + * 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 General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later) + */ + +/* The whole code here does not very fill into our general test frame + * work patter. But let's keep it as it is. */ + #include #include #include @@ -7,6 +40,20 @@ #include "iobuf.h" #include "stringhelp.h" + +static void * +xmalloc (size_t n) +{ + void *p = malloc (n); + if (!p) + { + fprintf (stderr, "t-iobuf: out of core\n"); + abort (); + } + return p; +} + + /* Return every other byte. In particular, reads two bytes, returns the second one. */ static int @@ -86,7 +133,7 @@ static struct content_filter_state * content_filter_new (const char *buffer) { struct content_filter_state *state - = malloc (sizeof (struct content_filter_state)); + = xmalloc (sizeof (struct content_filter_state)); state->pos = 0; state->len = strlen (buffer); @@ -215,8 +262,7 @@ main (int argc, char *argv[]) allocate a buffer that is 5 bytes long, then no reallocation should be required. */ size = 5; - buffer = malloc (size); - assert (buffer); + buffer = xmalloc (size); max_len = 100; n = iobuf_read_line (iobuf, &buffer, &size, &max_len); assert (n == 4); @@ -229,7 +275,7 @@ main (int argc, char *argv[]) requires 6 bytes of storage. We pass a buffer that is 5 bytes large and we allow the buffer to be grown. */ size = 5; - buffer = malloc (size); + buffer = xmalloc (size); max_len = 100; n = iobuf_read_line (iobuf, &buffer, &size, &max_len); assert (n == 5); @@ -243,7 +289,7 @@ main (int argc, char *argv[]) requires 7 bytes of storage. We pass a buffer that is 5 bytes large and we don't allow the buffer to be grown. */ size = 5; - buffer = malloc (size); + buffer = xmalloc (size); max_len = 5; n = iobuf_read_line (iobuf, &buffer, &size, &max_len); assert (n == 4); From 5c7c6065f32d7e85dcffbefb744ca4069900721d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 16 May 2023 10:16:31 +0900 Subject: [PATCH 003/869] w32: Remove support of Windows 95/98/Me. * g10/photoid.c (VER_PLATFORM_WIN32_WINDOWS): Remove fallback definition. (get_default_photo_command): Remove use of "start /w" for Windows 95. Signed-off-by: NIIBE Yutaka --- g10/photoid.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/g10/photoid.c b/g10/photoid.c index a866eb083..80fc35f8c 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -27,9 +27,6 @@ # include # endif # include -# ifndef VER_PLATFORM_WIN32_WINDOWS -# define VER_PLATFORM_WIN32_WINDOWS 1 -# endif #endif #include "gpg.h" @@ -375,16 +372,7 @@ static const char * get_default_photo_command(void) { #if defined(_WIN32) - OSVERSIONINFO osvi; - - memset(&osvi,0,sizeof(osvi)); - osvi.dwOSVersionInfoSize=sizeof(osvi); - GetVersionEx(&osvi); - - if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) - return "start /w %i"; - else - return "!ShellExecute 400 %i"; + return "!ShellExecute 400 %i"; #elif defined(__APPLE__) /* OS X. This really needs more than just __APPLE__. */ return "open %I"; From 86cdb49097a1ed08870a51fe5e4eb72aae6742d2 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 16 May 2023 16:25:13 +0900 Subject: [PATCH 004/869] w32: Use _putenv_s. * common/sysutils.c (gnupg_setenv): Use _putenv_s. -- This may break build on original MinGW, but works well with MinGW-W64. Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/common/sysutils.c b/common/sysutils.c index 01510ddb0..0c2831541 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -1148,6 +1148,19 @@ gnupg_setenv (const char *name, const char *value, int overwrite) return setenv (name, value, overwrite); #else /*!HAVE_SETENV*/ if (! getenv (name) || overwrite) +#ifdef HAVE_W32_SYSTEM + { + int e = _putenv_s (name, value); + + if (e) + { + gpg_err_set_errno (e); + return -1; + } + else + return 0; + } +#else { char *buf; @@ -1165,6 +1178,7 @@ gnupg_setenv (const char *name, const char *value, int overwrite) # endif return putenv (buf); } +#endif /*!HAVE_W32_SYSTEM*/ return 0; #endif /*!HAVE_SETENV*/ } From d22106276947ac05a0fae1d1e037c948d80fe627 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 16 May 2023 19:11:16 +0900 Subject: [PATCH 005/869] w32: Also use _putenv_s for gnupg_unsetenv. * common/sysutils.c (gnupg_setenv): Only enable use of _putenv_s with Security Feature in the CRT. (gnupg_unsetenv): Use _putenv_s when available. -- Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/common/sysutils.c b/common/sysutils.c index 0c2831541..ff75b698e 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -1148,7 +1148,7 @@ gnupg_setenv (const char *name, const char *value, int overwrite) return setenv (name, value, overwrite); #else /*!HAVE_SETENV*/ if (! getenv (name) || overwrite) -#ifdef HAVE_W32_SYSTEM +#if defined(HAVE_W32_SYSTEM) && defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) { int e = _putenv_s (name, value); @@ -1203,6 +1203,18 @@ gnupg_unsetenv (const char *name) #ifdef HAVE_UNSETENV return unsetenv (name); +#elif defined(HAVE_W32_SYSTEM) && defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) + { + int e = _putenv_s (name, ""); + + if (e) + { + gpg_err_set_errno (e); + return -1; + } + else + return 0; + } #else /*!HAVE_UNSETENV*/ { char *buf; From b789ada2b07a700b6efdbb4d2096c4cb8a5edbaa Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 17 May 2023 15:28:01 +0900 Subject: [PATCH 006/869] scd: Fix send_client_notifications for Windows. * scd/command.c (send_client_notifications): Don't use assuan_get_pid for Windows. -- Signed-off-by: NIIBE Yutaka --- scd/command.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/scd/command.c b/scd/command.c index 0cf66d08c..9ce3889d2 100644 --- a/scd/command.c +++ b/scd/command.c @@ -2942,10 +2942,10 @@ void send_client_notifications (card_t card, int removal) { struct { - pid_t pid; #ifdef HAVE_W32_SYSTEM HANDLE handle; #else + pid_t pid; int signo; #endif } killed[50]; @@ -2965,10 +2965,10 @@ send_client_notifications (card_t card, int removal) if (sl->ctrl_backlink && sl->ctrl_backlink->card_ctx == card) { - pid_t pid; #ifdef HAVE_W32_SYSTEM HANDLE handle; #else + pid_t pid; int signo; #endif @@ -2983,32 +2983,29 @@ send_client_notifications (card_t card, int removal) if (!sl->event_signal || !sl->assuan_ctx) continue; - pid = assuan_get_pid (sl->assuan_ctx); - #ifdef HAVE_W32_SYSTEM handle = sl->event_signal; for (kidx=0; kidx < killidx; kidx++) - if (killed[kidx].pid == pid - && killed[kidx].handle == handle) + if (killed[kidx].handle == handle) break; if (kidx < killidx) - log_info ("event %p (%p) already triggered for client %d\n", - sl->event_signal, handle, (int)pid); + log_info ("event %p already triggered for client\n", + sl->event_signal); else { - log_info ("triggering event %p (%p) for client %d\n", - sl->event_signal, handle, (int)pid); + log_info ("triggering event %p for client\n", + sl->event_signal); if (!SetEvent (handle)) log_error ("SetEvent(%p) failed: %s\n", sl->event_signal, w32_strerror (-1)); if (killidx < DIM (killed)) { - killed[killidx].pid = pid; killed[killidx].handle = handle; killidx++; } } #else /*!HAVE_W32_SYSTEM*/ + pid = assuan_get_pid (sl->assuan_ctx); signo = sl->event_signal; if (pid != (pid_t)(-1) && pid && signo > 0) From 6944aefa3c2ef79cf3f14306ed384d22de36ba7f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 May 2023 15:54:40 +0200 Subject: [PATCH 007/869] kbx,w32: Disable the fd-passing. * kbx/kbxserver.c (kbxd_start_command_handler): No fd-passing udner Windows. -- file descriptor passing does not work reliable in libassuan for Windows and we actually don't need it here. It is not even used by gpg or gpgsm. As soon as we enable fd-passing in gpgme for Windows and see that it is robust enough we should back out this patch. --- kbx/kbxserver.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kbx/kbxserver.c b/kbx/kbxserver.c index 990840980..ae9ae5c75 100644 --- a/kbx/kbxserver.c +++ b/kbx/kbxserver.c @@ -946,9 +946,15 @@ kbxd_start_command_handler (ctrl_t ctrl, gnupg_fd_t fd, unsigned int session_id) } else { + /* The fd-passing does not work reliable on Windows, and even it + * it is not used by gpg and gpgsm the current libassuan slows + * down things if it is allowed for the server.*/ rc = assuan_init_socket_server (ctx, fd, (ASSUAN_SOCKET_SERVER_ACCEPTED - |ASSUAN_SOCKET_SERVER_FDPASSING)); +#ifndef HAVE_W32_SYSTEM + |ASSUAN_SOCKET_SERVER_FDPASSING +#endif + )); } if (rc) From cd7f286486f23f89367048730e651ac17b7f8b3f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 19 May 2023 13:06:18 +0200 Subject: [PATCH 008/869] gpgtar: Emit FAILURE status line. * tools/gpgtar.c (main): Write status line before exit. -- Due to the new way we support gpgtar in GPGME we need status lines to detect a final error. GnuPG-bug-id: 6497 --- tools/gpgtar.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/gpgtar.c b/tools/gpgtar.c index b2ccc9f8a..492b3d5e5 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -588,9 +588,19 @@ main (int argc, char **argv) default: log_error (_("invalid command (there is no implicit command)\n")); + err = 0; break; } + if (opt.status_stream) + { + if (err || log_get_errorcount (0)) + es_fprintf (opt.status_stream, "[GNUPG:] FAILURE - %u\n", + err? err : gpg_error (GPG_ERR_GENERAL)); + else + es_fprintf (opt.status_stream, "[GNUPG:] SUCCESS\n"); + } + return log_get_errorcount (0)? 1:0; } From 5f46bcaaa0826a7b32f3f3bb5ef7a528ec0515a6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 May 2023 17:00:54 +0200 Subject: [PATCH 009/869] sm: Emit STATUS_FAILURE for non-implemented commands. * sm/gpgsm.c (main): Do it here. --- sm/gpgsm.c | 16 ++++++++++++---- sm/server.c | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 55173f8a2..07c3ff480 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1951,11 +1951,17 @@ main ( int argc, char **argv) break; case aSignEncr: /* sign and encrypt the given file */ - log_error ("this command has not yet been implemented\n"); + log_error ("the command '%s' has not yet been implemented\n", + "--sign --encrypt"); + gpgsm_status_with_error (&ctrl, STATUS_FAILURE, "option-parser", + gpg_error (GPG_ERR_NOT_IMPLEMENTED)); break; case aClearsign: /* make a clearsig */ - log_error ("this command has not yet been implemented\n"); + log_error ("the command '%s' has not yet been implemented\n", + "--clearsign"); + gpgsm_status_with_error (&ctrl, STATUS_FAILURE, "option-parser", + gpg_error (GPG_ERR_NOT_IMPLEMENTED)); break; case aVerify: @@ -2188,8 +2194,10 @@ main ( int argc, char **argv) default: - log_error (_("invalid command (there is no implicit command)\n")); - break; + log_error (_("invalid command (there is no implicit command)\n")); + gpgsm_status_with_error (&ctrl, STATUS_FAILURE, "option-parser", + gpg_error (GPG_ERR_MISSING_ACTION)); + break; } /* Print the audit result if needed. */ diff --git a/sm/server.c b/sm/server.c index e44856ab9..3ec1c0c4b 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1530,7 +1530,7 @@ gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, { char buf[30]; - sprintf (buf, "%u", (unsigned int)ec); + snprintf (buf, sizeof buf, "%u", (unsigned int)ec); if (text) return gpgsm_status2 (ctrl, no, text, buf, NULL); else From 48b56485548e11e901b762f39f9dcd14aa650184 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 May 2023 14:50:22 +0200 Subject: [PATCH 010/869] common,w32: Set a proper error code when creating an output file. * common/iobuf.c (direct_open) [W32]: Set errno. (fd_cache_open): Ditto. -- --- common/iobuf.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index 62cde27f9..825b97704 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -311,6 +311,13 @@ direct_open (const char *fname, const char *mode, int mode700) { hfile = CreateFileW (wfname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL); + if (hfile == INVALID_HANDLE_VALUE) + { + gnupg_w32_set_errno (-1); + if (DBG_IOBUF) + log_debug ("iobuf:direct_open '%s' CreateFile failed: %s\n", + fname, gpg_strerror (gpg_error_from_syserror())); + } xfree (wfname); } else @@ -426,8 +433,9 @@ fd_cache_open (const char *fname, const char *mode) #ifdef HAVE_W32_SYSTEM if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff) { - log_error ("rewind file failed on handle %p: ec=%d\n", - fp, (int) GetLastError ()); + int ec = (int) GetLastError (); + log_error ("rewind file failed on handle %p: ec=%d\n", fp, ec); + gnupg_w32_set_errno (ec); fp = GNUPG_INVALID_FD; } #else From 2f872fa68c6576724b9dabee9fb0844266f55d0d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 24 May 2023 10:36:04 +0900 Subject: [PATCH 011/869] gpg: Report BEGIN_* status before examining the input. * common/miscellaneous.c (is_openpgp_compressed_packet) (is_file_compressed): Moved to ... * common/iobuf.c: ... in this file. (is_file_compressed): Change the argument to INP, the iobuf. * common/util.h (is_file_compressed): Remove. * common/iobuf.h (is_file_compressed): Add. * g10/cipher-aead.c (write_header): Don't call write_status_printf here. (cipher_filter_aead): Call write_status_printf when called with IOBUFCTRL_INIT. * g10/cipher-cfb.c (write_header): Don't call write_status_printf here. (cipher_filter_cfb): Call write_status_printf when called with IOBUFCTRL_INIT. * g10/encrypt.c (encrypt_simple): Use new is_file_compressed function, after call of iobuf_push_filter. (encrypt_crypt): Likewise. * g10/sign.c (sign_file): Likewise. -- GnuPG-bug-id: 6481 Signed-off-by: NIIBE Yutaka --- common/iobuf.c | 120 +++++++++++++++++++++++++++++++++++++++++ common/iobuf.h | 3 ++ common/miscellaneous.c | 106 ------------------------------------ common/util.h | 2 - g10/cipher-aead.c | 7 ++- g10/cipher-cfb.c | 9 ++-- g10/encrypt.c | 103 ++++++++++++++--------------------- g10/sign.c | 13 +---- 8 files changed, 174 insertions(+), 189 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index 62cde27f9..e088812a6 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -3057,3 +3057,123 @@ iobuf_skip_rest (iobuf_t a, unsigned long n, int partial) } } } + + +/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed + * packet. LEN should be at least 6. */ +static int +is_openpgp_compressed_packet (const unsigned char *buf, size_t len) +{ + int c, ctb, pkttype; + int lenbytes; + + ctb = *buf++; len--; + if (!(ctb & 0x80)) + return 0; /* Invalid packet. */ + + if ((ctb & 0x40)) /* New style (OpenPGP) CTB. */ + { + pkttype = (ctb & 0x3f); + if (!len) + return 0; /* Expected first length octet missing. */ + c = *buf++; len--; + if (c < 192) + ; + else if (c < 224) + { + if (!len) + return 0; /* Expected second length octet missing. */ + } + else if (c == 255) + { + if (len < 4) + return 0; /* Expected length octets missing */ + } + } + else /* Old style CTB. */ + { + pkttype = (ctb>>2)&0xf; + lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); + if (len < lenbytes) + return 0; /* Not enough length bytes. */ + } + + return (pkttype == 8); +} + + +/* + * Check if the file is compressed, by peeking the iobuf. You need to + * pass the iobuf with INP. Returns true if the buffer seems to be + * compressed. + */ +int +is_file_compressed (iobuf_t inp) +{ + int i; + char buf[32]; + int buflen; + + struct magic_compress_s + { + byte len; + byte extchk; + byte magic[5]; + } magic[] = + { + { 3, 0, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */ + { 3, 0, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */ + { 4, 0, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */ + { 5, 0, { '%', 'P', 'D', 'F', '-'} }, /* PDF */ + { 4, 1, { 0xff, 0xd8, 0xff, 0xe0 } }, /* Maybe JFIF */ + { 5, 2, { 0x89, 'P','N','G', 0x0d} } /* Likely PNG */ + }; + + if (!inp) + return 0; + + for ( ; inp->chain; inp = inp->chain ) + ; + + buflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof buf, buf); + if (buflen < 0) + { + buflen = 0; + log_debug ("peeking at input failed\n"); + } + + if ( buflen < 6 ) + { + return 0; /* Too short to check - assume uncompressed. */ + } + + for ( i = 0; i < DIM (magic); i++ ) + { + if (!memcmp( buf, magic[i].magic, magic[i].len)) + { + switch (magic[i].extchk) + { + case 0: + return 1; /* Is compressed. */ + case 1: + if (buflen > 11 && !memcmp (buf + 6, "JFIF", 5)) + return 1; /* JFIF: this likely a compressed JPEG. */ + break; + case 2: + if (buflen > 8 + && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a) + return 1; /* This is a PNG. */ + break; + default: + break; + } + } + } + + if (buflen >= 6 && is_openpgp_compressed_packet (buf, buflen)) + { + return 1; /* Already compressed. */ + } + + return 0; /* Not detected as compressed. */ +} diff --git a/common/iobuf.h b/common/iobuf.h index c132c2f3c..ad416fe86 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -629,6 +629,9 @@ void iobuf_set_partial_body_length_mode (iobuf_t a, size_t len); from the following filter (which may or may not return EOF). */ void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial); +/* Check if the file is compressed, by peeking the iobuf. */ +int is_file_compressed (iobuf_t inp); + #define iobuf_where(a) "[don't know]" /* Each time a filter is allocated (via iobuf_alloc()), a diff --git a/common/miscellaneous.c b/common/miscellaneous.c index f19cc539d..1a090b1f5 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -415,112 +415,6 @@ decode_c_string (const char *src) } -/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed - * packet. LEN should be at least 6. */ -static int -is_openpgp_compressed_packet (const unsigned char *buf, size_t len) -{ - int c, ctb, pkttype; - int lenbytes; - - ctb = *buf++; len--; - if (!(ctb & 0x80)) - return 0; /* Invalid packet. */ - - if ((ctb & 0x40)) /* New style (OpenPGP) CTB. */ - { - pkttype = (ctb & 0x3f); - if (!len) - return 0; /* Expected first length octet missing. */ - c = *buf++; len--; - if (c < 192) - ; - else if (c < 224) - { - if (!len) - return 0; /* Expected second length octet missing. */ - } - else if (c == 255) - { - if (len < 4) - return 0; /* Expected length octets missing */ - } - } - else /* Old style CTB. */ - { - pkttype = (ctb>>2)&0xf; - lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); - if (len < lenbytes) - return 0; /* Not enough length bytes. */ - } - - return (pkttype == 8); -} - - - -/* - * Check if the file is compressed. You need to pass the first bytes - * of the file as (BUF,BUFLEN). Returns true if the buffer seems to - * be compressed. - */ -int -is_file_compressed (const byte *buf, unsigned int buflen) -{ - int i; - - struct magic_compress_s - { - byte len; - byte extchk; - byte magic[5]; - } magic[] = - { - { 3, 0, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */ - { 3, 0, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */ - { 4, 0, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */ - { 5, 0, { '%', 'P', 'D', 'F', '-'} }, /* PDF */ - { 4, 1, { 0xff, 0xd8, 0xff, 0xe0 } }, /* Maybe JFIF */ - { 5, 2, { 0x89, 'P','N','G', 0x0d} } /* Likely PNG */ - }; - - if ( buflen < 6 ) - { - return 0; /* Too short to check - assume uncompressed. */ - } - - for ( i = 0; i < DIM (magic); i++ ) - { - if (!memcmp( buf, magic[i].magic, magic[i].len)) - { - switch (magic[i].extchk) - { - case 0: - return 1; /* Is compressed. */ - case 1: - if (buflen > 11 && !memcmp (buf + 6, "JFIF", 5)) - return 1; /* JFIF: this likely a compressed JPEG. */ - break; - case 2: - if (buflen > 8 - && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a) - return 1; /* This is a PNG. */ - break; - default: - break; - } - } - } - - if (buflen >= 6 && is_openpgp_compressed_packet (buf, buflen)) - { - return 1; /* Already compressed. */ - } - - return 0; /* Not detected as compressed. */ -} - - /* Try match against each substring of multistr, delimited by | */ int match_multistr (const char *multistr,const char *match) diff --git a/common/util.h b/common/util.h index aa24e39e6..6b948510e 100644 --- a/common/util.h +++ b/common/util.h @@ -360,8 +360,6 @@ char *try_make_printable_string (const void *p, size_t n, int delim); char *make_printable_string (const void *p, size_t n, int delim); char *decode_c_string (const char *src); -int is_file_compressed (const byte *buf, unsigned int buflen); - int match_multistr (const char *multistr,const char *match); int gnupg_compare_version (const char *a, const char *b); diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c index 640d8432f..0c07e65de 100644 --- a/g10/cipher-aead.c +++ b/g10/cipher-aead.c @@ -174,8 +174,6 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) log_debug ("aead packet: len=%lu extralen=%d\n", (unsigned long)ed.len, ed.extralen); - write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d", - cfx->dek->algo, ed.aead_algo); print_cipher_algo_note (cfx->dek->algo); if (build_packet( a, &pkt)) @@ -488,6 +486,11 @@ cipher_filter_aead (void *opaque, int control, { mem2str (buf, "cipher_filter_aead", *ret_len); } + else if (control == IOBUFCTRL_INIT) + { + write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d", + cfx->dek->algo, cfx->dek->use_aead); + } return rc; } diff --git a/g10/cipher-cfb.c b/g10/cipher-cfb.c index 3ba8eb738..29bf2477c 100644 --- a/g10/cipher-cfb.c +++ b/g10/cipher-cfb.c @@ -72,9 +72,6 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) log_info (_("Hint: Do not use option %s\n"), "--rfc2440"); } - write_status_printf (STATUS_BEGIN_ENCRYPTION, "%d %d", - ed.mdc_method, cfx->dek->algo); - init_packet (&pkt); pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED; pkt.pkt.encrypted = &ed; @@ -182,6 +179,12 @@ cipher_filter_cfb (void *opaque, int control, { mem2str (buf, "cipher_filter_cfb", *ret_len); } + else if (control == IOBUFCTRL_INIT) + { + write_status_printf (STATUS_BEGIN_ENCRYPTION, "%d %d", + cfx->dek->use_mdc ? DIGEST_ALGO_SHA1 : 0, + cfx->dek->algo); + } return rc; } diff --git a/g10/encrypt.c b/g10/encrypt.c index 687b4344e..a524326bb 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -410,8 +410,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) text_filter_context_t tfx; progress_filter_context_t *pfx; int do_compress = !!default_compress_algo(); - char peekbuf[32]; - int peekbuflen; if (!gnupg_rng_is_compliant (opt.compliance)) { @@ -448,14 +446,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) return rc; } - peekbuflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof peekbuf, peekbuf); - if (peekbuflen < 0) - { - peekbuflen = 0; - if (DBG_FILTER) - log_debug ("peeking at input failed\n"); - } - handle_progress (pfx, inp, filename); if (opt.textmode) @@ -517,17 +507,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) /**/ : "CFB"); } - if (do_compress - && cfx.dek - && (cfx.dek->use_mdc || cfx.dek->use_aead) - && !opt.explicit_compress_option - && is_file_compressed (peekbuf, peekbuflen)) - { - if (opt.verbose) - log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); - do_compress = 0; - } - if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, 0, &out ))) { iobuf_cancel (inp); @@ -598,6 +577,24 @@ encrypt_simple (const char *filename, int mode, int use_seskey) else filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ + /* Register the cipher filter. */ + if (mode) + iobuf_push_filter (out, + cfx.dek->use_aead? cipher_filter_aead + /**/ : cipher_filter_cfb, + &cfx ); + + if (do_compress + && cfx.dek + && (cfx.dek->use_mdc || cfx.dek->use_aead) + && !opt.explicit_compress_option + && is_file_compressed (inp)) + { + if (opt.verbose) + log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); + do_compress = 0; + } + if (!opt.no_literal) { /* Note that PT has been initialized above in !no_literal mode. */ @@ -617,13 +614,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) pkt.pkt.generic = NULL; } - /* Register the cipher filter. */ - if (mode) - iobuf_push_filter (out, - cfx.dek->use_aead? cipher_filter_aead - /**/ : cipher_filter_cfb, - &cfx ); - /* Register the compress filter. */ if ( do_compress ) { @@ -783,7 +773,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, PKT_plaintext *pt = NULL; DEK *symkey_dek = NULL; STRING2KEY *symkey_s2k = NULL; - int rc = 0, rc2 = 0; + int rc = 0; u32 filesize; cipher_filter_context_t cfx; armor_filter_context_t *afx = NULL; @@ -792,8 +782,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, progress_filter_context_t *pfx; PK_LIST pk_list; int do_compress; - char peekbuf[32]; - int peekbuflen; if (filefd != -1 && filename) return gpg_error (GPG_ERR_INV_ARG); /* Both given. */ @@ -866,14 +854,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, if (opt.verbose) log_info (_("reading from '%s'\n"), iobuf_get_fname_nonnull (inp)); - peekbuflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof peekbuf, peekbuf); - if (peekbuflen < 0) - { - peekbuflen = 0; - if (DBG_FILTER) - log_debug ("peeking at input failed\n"); - } - handle_progress (pfx, inp, filename); if (opt.textmode) @@ -900,25 +880,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, if (!cfx.dek->use_aead) cfx.dek->use_mdc = !!use_mdc (pk_list, cfx.dek->algo); - /* Only do the is-file-already-compressed check if we are using a - * MDC or AEAD. This forces compressed files to be re-compressed if - * we do not have a MDC to give some protection against chosen - * ciphertext attacks. */ - if (do_compress - && (cfx.dek->use_mdc || cfx.dek->use_aead) - && !opt.explicit_compress_option - && is_file_compressed (peekbuf, peekbuflen)) - { - if (opt.verbose) - log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); - do_compress = 0; - } - if (rc2) - { - rc = rc2; - goto leave; - } - make_session_key (cfx.dek); if (DBG_CRYPTO) log_printhex (cfx.dek->key, cfx.dek->keylen, "DEK is: "); @@ -960,6 +921,26 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, else filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ + /* Register the cipher filter. */ + iobuf_push_filter (out, + cfx.dek->use_aead? cipher_filter_aead + /**/ : cipher_filter_cfb, + &cfx); + + /* Only do the is-file-already-compressed check if we are using a + * MDC or AEAD. This forces compressed files to be re-compressed if + * we do not have a MDC to give some protection against chosen + * ciphertext attacks. */ + if (do_compress + && (cfx.dek->use_mdc || cfx.dek->use_aead) + && !opt.explicit_compress_option + && is_file_compressed (inp)) + { + if (opt.verbose) + log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); + do_compress = 0; + } + if (!opt.no_literal) { pt->timestamp = make_timestamp(); @@ -974,12 +955,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, else cfx.datalen = filesize && !do_compress ? filesize : 0; - /* Register the cipher filter. */ - iobuf_push_filter (out, - cfx.dek->use_aead? cipher_filter_aead - /**/ : cipher_filter_cfb, - &cfx); - /* Register the compress filter. */ if (do_compress) { diff --git a/g10/sign.c b/g10/sign.c index b5e9d422d..fcb1bb749 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1035,9 +1035,6 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, int multifile = 0; u32 duration=0; pt_extra_hash_data_t extrahash = NULL; - char peekbuf[32]; - int peekbuflen = 0; - pfx = new_progress_context (); afx = new_armor_context (); @@ -1096,14 +1093,6 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, goto leave; } - peekbuflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof peekbuf, peekbuf); - if (peekbuflen < 0) - { - peekbuflen = 0; - if (DBG_FILTER) - log_debug ("peeking at input failed\n"); - } - handle_progress (pfx, inp, fname); } @@ -1261,7 +1250,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, int compr_algo = opt.compress_algo; if (!opt.explicit_compress_option - && is_file_compressed (peekbuf, peekbuflen)) + && is_file_compressed (inp)) { if (opt.verbose) log_info(_("'%s' already compressed\n"), fname? fname: "[stdin]"); From 3fbe10172f0a0d9fddad19c1e04a4f7870c88fbe Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 May 2023 12:06:37 +0200 Subject: [PATCH 012/869] w32: Add missing manifests and set a requestedExecutionLevel. * agent/gpg-agent.w32-manifest.in: New. * dirmngr/dirmngr-client-w32info.rc: New. * dirmngr/dirmngr-client.w32-manifest.in: New. * dirmngr/dirmngr-w32info.rc: New. * dirmngr/dirmngr.w32-manifest.in: New. * dirmngr/dirmngr_ldap-w32info.rc: New. * dirmngr/dirmngr_ldap.w32-manifest.in: New. * g10/gpgv-w32info.rc: New. * g10/gpgv.w32-manifest.in: New. * kbx/keyboxd.w32-manifest.in: New. * scd/scdaemon.w32-manifest.in: New. * sm/gpgsm.w32-manifest.in: New. -- This avoids the use of the VirtualStore uner Windows. GnuPG-bug-id: 6503 --- agent/Makefile.am | 7 +++- agent/gpg-agent-w32info.rc | 2 + agent/gpg-agent.w32-manifest.in | 24 ++++++++++++ configure.ac | 8 ++++ dirmngr/Makefile.am | 30 ++++++++++++-- dirmngr/dirmngr-client-w32info.rc | 52 +++++++++++++++++++++++++ dirmngr/dirmngr-client.w32-manifest.in | 25 ++++++++++++ dirmngr/dirmngr-w32info.rc | 52 +++++++++++++++++++++++++ dirmngr/dirmngr.w32-manifest.in | 25 ++++++++++++ dirmngr/dirmngr_ldap-w32info.rc | 52 +++++++++++++++++++++++++ dirmngr/dirmngr_ldap.w32-manifest.in | 25 ++++++++++++ g10/Makefile.am | 17 ++++---- g10/gpg.w32-manifest.in | 7 ++++ g10/gpgv-w32info.rc | 52 +++++++++++++++++++++++++ g10/gpgv.w32-manifest.in | 24 ++++++++++++ kbx/Makefile.am | 5 ++- kbx/keyboxd-w32info.rc | 2 + kbx/keyboxd.w32-manifest.in | 24 ++++++++++++ scd/Makefile.am | 7 +++- scd/scdaemon-w32info.rc | 2 + scd/scdaemon.w32-manifest.in | 24 ++++++++++++ sm/Makefile.am | 5 ++- sm/gpgsm-w32info.rc | 2 + sm/gpgsm.w32-manifest.in | 24 ++++++++++++ tools/Makefile.am | 17 +++++--- tools/gpg-card.w32-manifest.in | 7 ++++ tools/gpg-check-pattern.w32-manifest.in | 7 ++++ tools/gpg-connect-agent.w32-manifest.in | 7 ++++ tools/gpg-wks-client.w32-manifest.in | 7 ++++ tools/gpgconf.w32-manifest.in | 7 ++++ tools/gpgtar.w32-manifest.in | 7 ++++ 31 files changed, 534 insertions(+), 22 deletions(-) create mode 100644 agent/gpg-agent.w32-manifest.in create mode 100644 dirmngr/dirmngr-client-w32info.rc create mode 100644 dirmngr/dirmngr-client.w32-manifest.in create mode 100644 dirmngr/dirmngr-w32info.rc create mode 100644 dirmngr/dirmngr.w32-manifest.in create mode 100644 dirmngr/dirmngr_ldap-w32info.rc create mode 100644 dirmngr/dirmngr_ldap.w32-manifest.in create mode 100644 g10/gpgv-w32info.rc create mode 100644 g10/gpgv.w32-manifest.in create mode 100644 kbx/keyboxd.w32-manifest.in create mode 100644 scd/scdaemon.w32-manifest.in create mode 100644 sm/gpgsm.w32-manifest.in diff --git a/agent/Makefile.am b/agent/Makefile.am index 4da1ea9d8..b2a32b1fd 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -1,3 +1,4 @@ +# Makefile.am - agent # Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc. # # This file is part of GnuPG. @@ -23,8 +24,8 @@ libexec_PROGRAMS = gpg-protect-tool libexec_PROGRAMS += gpg-preset-passphrase noinst_PROGRAMS = $(TESTS) -EXTRA_DIST = ChangeLog-2011 gpg-agent-w32info.rc all-tests.scm - +EXTRA_DIST = ChangeLog-2011 all-tests.scm \ + gpg-agent-w32info.rc gpg-agent.w32-manifest.in AM_CPPFLAGS = @@ -32,6 +33,8 @@ include $(top_srcdir)/am/cmacros.am if HAVE_W32_SYSTEM resource_objs += gpg-agent-w32info.o + +gpg-agent-w32info.o : gpg-agent.w32-manifest ../common/w32info-rc.h endif AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) diff --git a/agent/gpg-agent-w32info.rc b/agent/gpg-agent-w32info.rc index d586cad0c..a0311b2cd 100644 --- a/agent/gpg-agent-w32info.rc +++ b/agent/gpg-agent-w32info.rc @@ -48,3 +48,5 @@ VALUE "Translation", 0x409, 0x4b0 END END + +1 RT_MANIFEST "gpg-agent.w32-manifest" diff --git a/agent/gpg-agent.w32-manifest.in b/agent/gpg-agent.w32-manifest.in new file mode 100644 index 000000000..87f09aa49 --- /dev/null +++ b/agent/gpg-agent.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (Private Key Daemon) + + + + + + + + + + + + + + + + + diff --git a/configure.ac b/configure.ac index 24448c157..a54740108 100644 --- a/configure.ac +++ b/configure.ac @@ -2102,6 +2102,14 @@ tests/tpm2dtests/Makefile tests/gpgme/Makefile tests/pkits/Makefile g10/gpg.w32-manifest +g10/gpgv.w32-manifest +sm/gpgsm.w32-manifest +kbx/keyboxd.w32-manifest +agent/gpg-agent.w32-manifest +scd/scdaemon.w32-manifest +dirmngr/dirmngr.w32-manifest +dirmngr/dirmngr_ldap.w32-manifest +dirmngr/dirmngr-client.w32-manifest tools/gpg-connect-agent.w32-manifest tools/gpgconf.w32-manifest tools/gpgtar.w32-manifest diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index feee2f5c8..3846fdf35 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -21,7 +21,14 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = OAUTHORS ONEWS ChangeLog-2011 tls-ca.pem +EXTRA_DIST = OAUTHORS ONEWS ChangeLog-2011 tls-ca.pem \ + dirmngr-w32info.rc dirmngr.w32-manifest.in \ + dirmngr_ldap-w32info.rc dirmngr_ldap.w32-manifest.in \ + dirmngr-client-w32info.rc dirmngr-client.w32-manifest.in + + + + dist_pkgdata_DATA = sks-keyservers.netCA.pem bin_PROGRAMS = dirmngr dirmngr-client @@ -43,6 +50,16 @@ AM_CPPFLAGS = include $(top_srcdir)/am/cmacros.am +if HAVE_W32_SYSTEM +dirmngr_rc_objs = dirmngr-w32info.o +dirmngr_ldap_rc_objs = dirmngr_ldap-w32info.o +dirmngr_client_rc_objs = dirmngr-client-w32info.o + +dirmngr-w32info.o : dirmngr.w32-manifest ../common/w32info-rc.h +dirmngr_ldap-w32info.o : dirmngr_ldap.w32-manifest ../common/w32info-rc.h +dirmngr-client-w32info.o : dirmngr-client.w32-manifest ../common/w32info-rc.h +endif + AM_CFLAGS = $(USE_C99_CFLAGS) \ $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) \ $(GPG_ERROR_CFLAGS) $(NPTH_CFLAGS) $(NTBTLS_CFLAGS) \ @@ -89,12 +106,13 @@ dirmngr_LDADD = $(libcommonpth) \ $(DNSLIBS) $(LIBASSUAN_LIBS) \ $(KSBA_LIBS) $(NPTH_LIBS) $(NTBTLS_LIBS) $(LIBGNUTLS_LIBS) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) \ - $(NETLIBS) + $(NETLIBS) $(dirmngr_rc_objs) if USE_LDAP dirmngr_LDADD += $(ldaplibs) $(LBER_LIBS) endif dirmngr_LDFLAGS = +dirmngr_DEPENDENCIES = $(dirmngr_rc_objs) if USE_LDAP dirmngr_ldap_SOURCES = dirmngr_ldap.c ldap-misc.c ldap-misc.h $(ldap_url) @@ -102,14 +120,18 @@ dirmngr_ldap_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS) dirmngr_ldap_LDFLAGS = dirmngr_ldap_LDADD = $(libcommon) \ $(GPG_ERROR_LIBS) $(LIBGCRYPT_LIBS) $(LDAPLIBS) \ - $(LBER_LIBS) $(LIBINTL) $(LIBICONV) $(NETLIBS) + $(LBER_LIBS) $(LIBINTL) $(LIBICONV) $(NETLIBS) \ + $(dirmngr_ldap_rc_objs) +dirmngr_ldap_DEPENDENCIES = $(dirmngr_ldap_rc_objs) endif dirmngr_client_SOURCES = dirmngr-client.c dirmngr_client_LDADD = $(libcommon) \ $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ - $(LIBGCRYPT_LIBS) $(NETLIBS) $(LIBINTL) $(LIBICONV) + $(LIBGCRYPT_LIBS) $(NETLIBS) $(LIBINTL) $(LIBICONV) \ + $(dirmngr_client_rc_objs) dirmngr_client_LDFLAGS = +dirmngr_client_DEPENDENCIES = $(dirmngr_client_rc_objs) t_common_src = t-support.h t-support.c diff --git a/dirmngr/dirmngr-client-w32info.rc b/dirmngr/dirmngr-client-w32info.rc new file mode 100644 index 000000000..020447bca --- /dev/null +++ b/dirmngr/dirmngr-client-w32info.rc @@ -0,0 +1,52 @@ +/* dirmngr-client-w32info.rc -*- c -*- + * Copyright (C) 2023 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "afxres.h" +#include "../common/w32info-rc.h" + +1 ICON "../common/gnupg.ico" + +1 VERSIONINFO + FILEVERSION W32INFO_VI_FILEVERSION + PRODUCTVERSION W32INFO_VI_PRODUCTVERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x01L /* VS_FF_DEBUG (0x1)*/ +#else + FILEFLAGS 0x00L +#endif + FILEOS 0x40004L /* VOS_NT (0x40000) | VOS__WINDOWS32 (0x4) */ + FILETYPE 0x1L /* VFT_APP (0x1) */ + FILESUBTYPE 0x0L /* VFT2_UNKNOWN */ + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" /* US English (0409), Unicode (04b0) */ + BEGIN + VALUE "FileDescription", L"GnuPG\x2019s dirmngr client\0" + VALUE "InternalName", "dirmngr-client\0" + VALUE "OriginalFilename", "dirmngr-client.exe\0" + VALUE "ProductName", W32INFO_PRODUCTNAME + VALUE "ProductVersion", W32INFO_PRODUCTVERSION + VALUE "CompanyName", W32INFO_COMPANYNAME + VALUE "FileVersion", W32INFO_FILEVERSION + VALUE "LegalCopyright", W32INFO_LEGALCOPYRIGHT + VALUE "Comments", W32INFO_COMMENTS + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0x4b0 + END + END + +1 RT_MANIFEST "dirmngr-client.w32-manifest" diff --git a/dirmngr/dirmngr-client.w32-manifest.in b/dirmngr/dirmngr-client.w32-manifest.in new file mode 100644 index 000000000..1d46d19ff --- /dev/null +++ b/dirmngr/dirmngr-client.w32-manifest.in @@ -0,0 +1,25 @@ + + +GNU Privacy Guard (Dirmngr Client) + + + + + + + + + + + + + + + + + + diff --git a/dirmngr/dirmngr-w32info.rc b/dirmngr/dirmngr-w32info.rc new file mode 100644 index 000000000..cc1475b8e --- /dev/null +++ b/dirmngr/dirmngr-w32info.rc @@ -0,0 +1,52 @@ +/* dirmngr-w32info.rc -*- c -*- + * Copyright (C) 2023 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "afxres.h" +#include "../common/w32info-rc.h" + +1 ICON "../common/gnupg.ico" + +1 VERSIONINFO + FILEVERSION W32INFO_VI_FILEVERSION + PRODUCTVERSION W32INFO_VI_PRODUCTVERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x01L /* VS_FF_DEBUG (0x1)*/ +#else + FILEFLAGS 0x00L +#endif + FILEOS 0x40004L /* VOS_NT (0x40000) | VOS__WINDOWS32 (0x4) */ + FILETYPE 0x1L /* VFT_APP (0x1) */ + FILESUBTYPE 0x0L /* VFT2_UNKNOWN */ + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" /* US English (0409), Unicode (04b0) */ + BEGIN + VALUE "FileDescription", L"GnuPG\x2019s network access daemon\0" + VALUE "InternalName", "dirmngr\0" + VALUE "OriginalFilename", "dirmngr.exe\0" + VALUE "ProductName", W32INFO_PRODUCTNAME + VALUE "ProductVersion", W32INFO_PRODUCTVERSION + VALUE "CompanyName", W32INFO_COMPANYNAME + VALUE "FileVersion", W32INFO_FILEVERSION + VALUE "LegalCopyright", W32INFO_LEGALCOPYRIGHT + VALUE "Comments", W32INFO_COMMENTS + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0x4b0 + END + END + +1 RT_MANIFEST "dirmngr.w32-manifest" diff --git a/dirmngr/dirmngr.w32-manifest.in b/dirmngr/dirmngr.w32-manifest.in new file mode 100644 index 000000000..115548b5c --- /dev/null +++ b/dirmngr/dirmngr.w32-manifest.in @@ -0,0 +1,25 @@ + + +GNU Privacy Guard (Archive tool) + + + + + + + + + + + + + + + + + + diff --git a/dirmngr/dirmngr_ldap-w32info.rc b/dirmngr/dirmngr_ldap-w32info.rc new file mode 100644 index 000000000..779d85837 --- /dev/null +++ b/dirmngr/dirmngr_ldap-w32info.rc @@ -0,0 +1,52 @@ +/* dirmngr_ldap-w32info.rc -*- c -*- + * Copyright (C) 2023 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "afxres.h" +#include "../common/w32info-rc.h" + +1 ICON "../common/gnupg.ico" + +1 VERSIONINFO + FILEVERSION W32INFO_VI_FILEVERSION + PRODUCTVERSION W32INFO_VI_PRODUCTVERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x01L /* VS_FF_DEBUG (0x1)*/ +#else + FILEFLAGS 0x00L +#endif + FILEOS 0x40004L /* VOS_NT (0x40000) | VOS__WINDOWS32 (0x4) */ + FILETYPE 0x1L /* VFT_APP (0x1) */ + FILESUBTYPE 0x0L /* VFT2_UNKNOWN */ + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" /* US English (0409), Unicode (04b0) */ + BEGIN + VALUE "FileDescription", L"GnuPG\x2019s LDAP helper\0" + VALUE "InternalName", "dirmngr_ldap\0" + VALUE "OriginalFilename", "dirmngr_ldap.exe\0" + VALUE "ProductName", W32INFO_PRODUCTNAME + VALUE "ProductVersion", W32INFO_PRODUCTVERSION + VALUE "CompanyName", W32INFO_COMPANYNAME + VALUE "FileVersion", W32INFO_FILEVERSION + VALUE "LegalCopyright", W32INFO_LEGALCOPYRIGHT + VALUE "Comments", W32INFO_COMMENTS + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0x4b0 + END + END + +1 RT_MANIFEST "dirmngr_ldap.w32-manifest" diff --git a/dirmngr/dirmngr_ldap.w32-manifest.in b/dirmngr/dirmngr_ldap.w32-manifest.in new file mode 100644 index 000000000..67db0841c --- /dev/null +++ b/dirmngr/dirmngr_ldap.w32-manifest.in @@ -0,0 +1,25 @@ + + +GNU Privacy Guard (LDAP Helper) + + + + + + + + + + + + + + + + + + diff --git a/g10/Makefile.am b/g10/Makefile.am index 80b5b8919..c5691f551 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -1,3 +1,4 @@ +# Makefile.am - g10 # Copyright (C) 1998, 1999, 2000, 2001, 2002, # 2003, 2006, 2010 Free Software Foundation, Inc. # @@ -19,8 +20,9 @@ ## Process this file with automake to produce Makefile.in EXTRA_DIST = distsigkey.gpg \ - ChangeLog-2011 gpg-w32info.rc \ - gpg.w32-manifest.in test.c t-keydb-keyring.kbx \ + gpg-w32info.rc gpg.w32-manifest.in \ + gpgv-w32info.rc gpgv.w32-manifest.in \ + ChangeLog-2011 test.c t-keydb-keyring.kbx \ t-keydb-get-keyblock.gpg t-stutter-data.asc \ all-tests.scm @@ -83,10 +85,11 @@ endif if HAVE_W32_SYSTEM -resource_objs += gpg-w32info.o - -gpg-w32info.o : gpg.w32-manifest +gpg_rc_objs = gpg-w32info.o +gpgv_rc_objs = gpgv-w32info.o +gpg-w32info.o : gpg.w32-manifest ../common/w32info-rc.h +gpgv-w32info.o : gpgv.w32-manifest ../common/w32info-rc.h endif common_source = \ @@ -171,11 +174,11 @@ LDADD = $(needed_libs) ../common/libgpgrl.a \ $(ZLIBS) $(LIBINTL) $(CAPLIBS) gpg_LDADD = $(LDADD) $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \ $(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) $(NETLIBS) \ - $(LIBICONV) $(resource_objs) + $(LIBICONV) $(gpg_rc_objs) gpg_LDFLAGS = gpgv_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \ $(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) $(NETLIBS) \ - $(LIBICONV) $(resource_objs) + $(LIBICONV) $(gpgv_rc_objs) gpgv_LDFLAGS = diff --git a/g10/gpg.w32-manifest.in b/g10/gpg.w32-manifest.in index 8c98dc5a7..bf7723925 100644 --- a/g10/gpg.w32-manifest.in +++ b/g10/gpg.w32-manifest.in @@ -14,4 +14,11 @@ + + + + + + + diff --git a/g10/gpgv-w32info.rc b/g10/gpgv-w32info.rc new file mode 100644 index 000000000..a6c1b6cd3 --- /dev/null +++ b/g10/gpgv-w32info.rc @@ -0,0 +1,52 @@ +/* gpgv-w32info.rc -*- c -*- + * Copyright (C) 2013 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "afxres.h" +#include "../common/w32info-rc.h" + +1 ICON "../common/gnupg.ico" + +1 VERSIONINFO + FILEVERSION W32INFO_VI_FILEVERSION + PRODUCTVERSION W32INFO_VI_PRODUCTVERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x01L /* VS_FF_DEBUG (0x1)*/ +#else + FILEFLAGS 0x00L +#endif + FILEOS 0x40004L /* VOS_NT (0x40000) | VOS__WINDOWS32 (0x4) */ + FILETYPE 0x1L /* VFT_APP (0x1) */ + FILESUBTYPE 0x0L /* VFT2_UNKNOWN */ + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" /* US English (0409), Unicode (04b0) */ + BEGIN + VALUE "FileDescription", L"GnuPG\x2019s OpenPGP verify tool\0" + VALUE "InternalName", "gpgv\0" + VALUE "OriginalFilename", "gpgv.exe\0" + VALUE "ProductName", W32INFO_PRODUCTNAME + VALUE "ProductVersion", W32INFO_PRODUCTVERSION + VALUE "CompanyName", W32INFO_COMPANYNAME + VALUE "FileVersion", W32INFO_FILEVERSION + VALUE "LegalCopyright", W32INFO_LEGALCOPYRIGHT + VALUE "Comments", W32INFO_COMMENTS + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0x4b0 + END + END + +1 RT_MANIFEST "gpgv.w32-manifest" diff --git a/g10/gpgv.w32-manifest.in b/g10/gpgv.w32-manifest.in new file mode 100644 index 000000000..794ab15c3 --- /dev/null +++ b/g10/gpgv.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (OpenPGP verify tool) + + + + + + + + + + + + + + + + + diff --git a/kbx/Makefile.am b/kbx/Makefile.am index 66214fa5c..19bdb1061 100644 --- a/kbx/Makefile.am +++ b/kbx/Makefile.am @@ -18,13 +18,16 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = mkerrors keyboxd-w32info.rc +EXTRA_DIST = mkerrors keyboxd-w32info.rc keyboxd.w32-manifest.in AM_CPPFLAGS = include $(top_srcdir)/am/cmacros.am + if HAVE_W32_SYSTEM resource_objs += keyboxd-w32info.o + +keyboxd-w32info.o : keyboxd.w32-manifest ../common/w32info-rc.h endif AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) diff --git a/kbx/keyboxd-w32info.rc b/kbx/keyboxd-w32info.rc index 421747499..c38d9f366 100644 --- a/kbx/keyboxd-w32info.rc +++ b/kbx/keyboxd-w32info.rc @@ -48,3 +48,5 @@ VALUE "Translation", 0x409, 0x4b0 END END + +1 RT_MANIFEST "keyboxd.w32-manifest" diff --git a/kbx/keyboxd.w32-manifest.in b/kbx/keyboxd.w32-manifest.in new file mode 100644 index 000000000..f2e50fb4b --- /dev/null +++ b/kbx/keyboxd.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (Public Key Daemon) + + + + + + + + + + + + + + + + + diff --git a/scd/Makefile.am b/scd/Makefile.am index 0cc50dca8..8cbcd6e05 100644 --- a/scd/Makefile.am +++ b/scd/Makefile.am @@ -1,3 +1,4 @@ +# Makefile.am - scd # Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is part of GnuPG. @@ -17,7 +18,8 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = ChangeLog-2011 scdaemon-w32info.rc +EXTRA_DIST = ChangeLog-2011 \ + scdaemon-w32info.rc scdaemon.w32-manifest.in libexec_PROGRAMS = scdaemon @@ -27,6 +29,7 @@ include $(top_srcdir)/am/cmacros.am if HAVE_W32_SYSTEM resource_objs += scdaemon-w32info.o +scdaemon-w32info.o : scdaemon.w32-manifest ../common/w32info-rc.h endif AM_CFLAGS = $(LIBGCRYPT_CFLAGS) \ @@ -50,3 +53,5 @@ scdaemon_LDADD = $(libcommonpth) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \ $(LIBUSB_LIBS) $(GPG_ERROR_LIBS) \ $(LIBINTL) $(DL_LIBS) $(NETLIBS) $(LIBICONV) $(resource_objs) + +scdaemon_DEPENDENCIES = $(resource_objs) diff --git a/scd/scdaemon-w32info.rc b/scd/scdaemon-w32info.rc index aa0eba4e5..c1dae5421 100644 --- a/scd/scdaemon-w32info.rc +++ b/scd/scdaemon-w32info.rc @@ -48,3 +48,5 @@ VALUE "Translation", 0x409, 0x4b0 END END + +1 RT_MANIFEST "scdaemon.w32-manifest" diff --git a/scd/scdaemon.w32-manifest.in b/scd/scdaemon.w32-manifest.in new file mode 100644 index 000000000..aa0ccb206 --- /dev/null +++ b/scd/scdaemon.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (Smartcard Daemon) + + + + + + + + + + + + + + + + + diff --git a/sm/Makefile.am b/sm/Makefile.am index cfcc36c63..03de7026a 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -17,7 +17,8 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = ChangeLog-2011 gpgsm-w32info.rc +EXTRA_DIST = ChangeLog-2011 \ + gpgsm-w32info.rc gpgsm.w32-manifest.in bin_PROGRAMS = gpgsm noinst_PROGRAMS = $(module_tests) $(module_maint_tests) @@ -36,6 +37,7 @@ include $(top_srcdir)/am/cmacros.am if HAVE_W32_SYSTEM resource_objs += gpgsm-w32info.o +gpgsm-w32info.o : gpgsm.w32-manifest ../common/w32info-rc.h endif gpgsm_SOURCES = \ @@ -72,6 +74,7 @@ gpgsm_LDADD = $(common_libs) ../common/libgpgrl.a \ $(NPTH_LIBS) $(GPG_ERROR_LIBS) $(LIBREADLINE) $(LIBINTL) \ $(LIBICONV) $(resource_objs) $(NETLIBS) gpgsm_LDFLAGS = +gpgsm_DEPENDENCIES = $(resource_objs) module_tests = diff --git a/sm/gpgsm-w32info.rc b/sm/gpgsm-w32info.rc index d813b0dc8..537afdbc7 100644 --- a/sm/gpgsm-w32info.rc +++ b/sm/gpgsm-w32info.rc @@ -48,3 +48,5 @@ VALUE "Translation", 0x409, 0x4b0 END END + +1 RT_MANIFEST "gpgsm.w32-manifest" diff --git a/sm/gpgsm.w32-manifest.in b/sm/gpgsm.w32-manifest.in new file mode 100644 index 000000000..7764be394 --- /dev/null +++ b/sm/gpgsm.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (X.509/CMS Tool) + + + + + + + + + + + + + + + + + diff --git a/tools/Makefile.am b/tools/Makefile.am index 39374e42a..769a81a00 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -38,12 +38,17 @@ gpg_card_rc_objs = gpg-card-w32info.o gpgtar_rc_objs = gpgtar-w32info.o gpg_check_pattern_rc_objs = gpg-check-pattern-w32info.o gpg_wks_client_rc_objs = gpg-wks-client-w32info.o -resource_objs += $(gpg_connect_agent_rc_objs) -resource_objs += $(gpgconf_rc_objs) -resource_objs += $(gpg_card_tool_rc_objs) -resource_objs += $(gpgtar_rc_objs) -resource_objs += $(gpg_check_pattern_rc_objs) -resource_objs += $(gpg_wks_client_rc_objs) + +gpg-connect-agent-w32info.o : gpg-connect-agent.w32-manifest \ + ../common/w32info-rc.h +gpgconf-w32info.o : gpgconf.w32-manifest ../common/w32info-rc.h +gpg-card-w32info.o : gpg-card.w32-manifest ../common/w32info-rc.h +gpgtar-w32info.o : gpgtar.w32-manifest ../common/w32info-rc.h +gpg-check-pattern-w32info.o : gpg-check-pattern.w32-manifest \ + ../common/w32info-rc.h +gpg-wks-client-w32info.o : gpg-wks-client.w32-manifest \ + ../common/w32info-rc.h + endif AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS) diff --git a/tools/gpg-card.w32-manifest.in b/tools/gpg-card.w32-manifest.in index ab853f810..4630fce3e 100644 --- a/tools/gpg-card.w32-manifest.in +++ b/tools/gpg-card.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpg-check-pattern.w32-manifest.in b/tools/gpg-check-pattern.w32-manifest.in index 2a5f8ec72..acb7c914a 100644 --- a/tools/gpg-check-pattern.w32-manifest.in +++ b/tools/gpg-check-pattern.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpg-connect-agent.w32-manifest.in b/tools/gpg-connect-agent.w32-manifest.in index aba542052..c222a6794 100644 --- a/tools/gpg-connect-agent.w32-manifest.in +++ b/tools/gpg-connect-agent.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpg-wks-client.w32-manifest.in b/tools/gpg-wks-client.w32-manifest.in index ba2508e5f..c44620f0e 100644 --- a/tools/gpg-wks-client.w32-manifest.in +++ b/tools/gpg-wks-client.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpgconf.w32-manifest.in b/tools/gpgconf.w32-manifest.in index d7a1b01ec..ab5f17d04 100644 --- a/tools/gpgconf.w32-manifest.in +++ b/tools/gpgconf.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpgtar.w32-manifest.in b/tools/gpgtar.w32-manifest.in index 62d5937fa..b949a6baa 100644 --- a/tools/gpgtar.w32-manifest.in +++ b/tools/gpgtar.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + From faf0a97b2e0b62fe23acdc8473033398ba2ce1bc Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 May 2023 12:09:47 +0200 Subject: [PATCH 013/869] gpg: Improve error code for file already exists. * g10/plaintext.c (get_output_file): Fix error code. --- g10/plaintext.c | 3 +-- sm/server.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/g10/plaintext.c b/g10/plaintext.c index 5c21dd7f6..e12c2bf79 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -137,8 +137,7 @@ get_output_file (const byte *embedded_name, int embedded_namelen, if (!tmp || !*tmp) { xfree (tmp); - /* FIXME: Below used to be GPG_ERR_CREATE_FILE */ - err = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_EEXIST); goto leave; } xfree (fname); diff --git a/sm/server.c b/sm/server.c index e44856ab9..3ec1c0c4b 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1530,7 +1530,7 @@ gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, { char buf[30]; - sprintf (buf, "%u", (unsigned int)ec); + snprintf (buf, sizeof buf, "%u", (unsigned int)ec); if (text) return gpgsm_status2 (ctrl, no, text, buf, NULL); else From 097701e69835774883d9c055462e22e3111737a0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 19 May 2023 13:06:18 +0200 Subject: [PATCH 014/869] gpgtar: Emit FAILURE status line. * tools/gpgtar.c (main): Write status line before exit. -- Due to the new way we support gpgtar in GPGME we need status lines to detect a final error. GnuPG-bug-id: 6497 --- tools/gpgtar.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/gpgtar.c b/tools/gpgtar.c index b2ccc9f8a..492b3d5e5 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -588,9 +588,19 @@ main (int argc, char **argv) default: log_error (_("invalid command (there is no implicit command)\n")); + err = 0; break; } + if (opt.status_stream) + { + if (err || log_get_errorcount (0)) + es_fprintf (opt.status_stream, "[GNUPG:] FAILURE - %u\n", + err? err : gpg_error (GPG_ERR_GENERAL)); + else + es_fprintf (opt.status_stream, "[GNUPG:] SUCCESS\n"); + } + return log_get_errorcount (0)? 1:0; } From 7e681da1b217768b40713825ef8177f0d1010eff Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 May 2023 17:00:54 +0200 Subject: [PATCH 015/869] sm: Emit STATUS_FAILURE for non-implemented commands. * sm/gpgsm.c (main): Do it here. --- sm/gpgsm.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 55173f8a2..07c3ff480 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1951,11 +1951,17 @@ main ( int argc, char **argv) break; case aSignEncr: /* sign and encrypt the given file */ - log_error ("this command has not yet been implemented\n"); + log_error ("the command '%s' has not yet been implemented\n", + "--sign --encrypt"); + gpgsm_status_with_error (&ctrl, STATUS_FAILURE, "option-parser", + gpg_error (GPG_ERR_NOT_IMPLEMENTED)); break; case aClearsign: /* make a clearsig */ - log_error ("this command has not yet been implemented\n"); + log_error ("the command '%s' has not yet been implemented\n", + "--clearsign"); + gpgsm_status_with_error (&ctrl, STATUS_FAILURE, "option-parser", + gpg_error (GPG_ERR_NOT_IMPLEMENTED)); break; case aVerify: @@ -2188,8 +2194,10 @@ main ( int argc, char **argv) default: - log_error (_("invalid command (there is no implicit command)\n")); - break; + log_error (_("invalid command (there is no implicit command)\n")); + gpgsm_status_with_error (&ctrl, STATUS_FAILURE, "option-parser", + gpg_error (GPG_ERR_MISSING_ACTION)); + break; } /* Print the audit result if needed. */ From 42bea7de16e9dd64fefda7b46760b6c309393450 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 May 2023 14:50:22 +0200 Subject: [PATCH 016/869] common,w32: Set a proper error code when creating an output file. * common/iobuf.c (direct_open) [W32]: Set errno. (fd_cache_open): Ditto. -- --- common/iobuf.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index e088812a6..8da591046 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -311,6 +311,13 @@ direct_open (const char *fname, const char *mode, int mode700) { hfile = CreateFileW (wfname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL); + if (hfile == INVALID_HANDLE_VALUE) + { + gnupg_w32_set_errno (-1); + if (DBG_IOBUF) + log_debug ("iobuf:direct_open '%s' CreateFile failed: %s\n", + fname, gpg_strerror (gpg_error_from_syserror())); + } xfree (wfname); } else @@ -426,8 +433,9 @@ fd_cache_open (const char *fname, const char *mode) #ifdef HAVE_W32_SYSTEM if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff) { - log_error ("rewind file failed on handle %p: ec=%d\n", - fp, (int) GetLastError ()); + int ec = (int) GetLastError (); + log_error ("rewind file failed on handle %p: ec=%d\n", fp, ec); + gnupg_w32_set_errno (ec); fp = GNUPG_INVALID_FD; } #else From 3a438a1cc3505390e5e1a33ebbf1bd87d7a22840 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 May 2023 12:06:37 +0200 Subject: [PATCH 017/869] w32: Add missing manifests and set a requestedExecutionLevel. * agent/gpg-agent.w32-manifest.in: New. * dirmngr/dirmngr-client-w32info.rc: New. * dirmngr/dirmngr-client.w32-manifest.in: New. * dirmngr/dirmngr-w32info.rc: New. * dirmngr/dirmngr.w32-manifest.in: New. * dirmngr/dirmngr_ldap-w32info.rc: New. * dirmngr/dirmngr_ldap.w32-manifest.in: New. * g10/gpgv-w32info.rc: New. * g10/gpgv.w32-manifest.in: New. * kbx/keyboxd.w32-manifest.in: New. * scd/scdaemon.w32-manifest.in: New. * sm/gpgsm.w32-manifest.in: New. -- This avoids the use of the VirtualStore uner Windows. GnuPG-bug-id: 6503 --- agent/Makefile.am | 7 +++- agent/gpg-agent-w32info.rc | 2 + agent/gpg-agent.w32-manifest.in | 24 ++++++++++++ configure.ac | 8 ++++ dirmngr/Makefile.am | 30 ++++++++++++-- dirmngr/dirmngr-client-w32info.rc | 52 +++++++++++++++++++++++++ dirmngr/dirmngr-client.w32-manifest.in | 25 ++++++++++++ dirmngr/dirmngr-w32info.rc | 52 +++++++++++++++++++++++++ dirmngr/dirmngr.w32-manifest.in | 25 ++++++++++++ dirmngr/dirmngr_ldap-w32info.rc | 52 +++++++++++++++++++++++++ dirmngr/dirmngr_ldap.w32-manifest.in | 25 ++++++++++++ g10/Makefile.am | 17 ++++---- g10/gpg.w32-manifest.in | 7 ++++ g10/gpgv-w32info.rc | 52 +++++++++++++++++++++++++ g10/gpgv.w32-manifest.in | 24 ++++++++++++ kbx/Makefile.am | 5 ++- kbx/keyboxd-w32info.rc | 2 + kbx/keyboxd.w32-manifest.in | 24 ++++++++++++ scd/Makefile.am | 7 +++- scd/scdaemon-w32info.rc | 2 + scd/scdaemon.w32-manifest.in | 24 ++++++++++++ sm/Makefile.am | 5 ++- sm/gpgsm-w32info.rc | 2 + sm/gpgsm.w32-manifest.in | 24 ++++++++++++ tools/Makefile.am | 17 +++++--- tools/gpg-card.w32-manifest.in | 7 ++++ tools/gpg-check-pattern.w32-manifest.in | 7 ++++ tools/gpg-connect-agent.w32-manifest.in | 7 ++++ tools/gpg-wks-client.w32-manifest.in | 7 ++++ tools/gpgconf.w32-manifest.in | 7 ++++ tools/gpgtar.w32-manifest.in | 7 ++++ 31 files changed, 534 insertions(+), 22 deletions(-) create mode 100644 agent/gpg-agent.w32-manifest.in create mode 100644 dirmngr/dirmngr-client-w32info.rc create mode 100644 dirmngr/dirmngr-client.w32-manifest.in create mode 100644 dirmngr/dirmngr-w32info.rc create mode 100644 dirmngr/dirmngr.w32-manifest.in create mode 100644 dirmngr/dirmngr_ldap-w32info.rc create mode 100644 dirmngr/dirmngr_ldap.w32-manifest.in create mode 100644 g10/gpgv-w32info.rc create mode 100644 g10/gpgv.w32-manifest.in create mode 100644 kbx/keyboxd.w32-manifest.in create mode 100644 scd/scdaemon.w32-manifest.in create mode 100644 sm/gpgsm.w32-manifest.in diff --git a/agent/Makefile.am b/agent/Makefile.am index 4da1ea9d8..b2a32b1fd 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -1,3 +1,4 @@ +# Makefile.am - agent # Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc. # # This file is part of GnuPG. @@ -23,8 +24,8 @@ libexec_PROGRAMS = gpg-protect-tool libexec_PROGRAMS += gpg-preset-passphrase noinst_PROGRAMS = $(TESTS) -EXTRA_DIST = ChangeLog-2011 gpg-agent-w32info.rc all-tests.scm - +EXTRA_DIST = ChangeLog-2011 all-tests.scm \ + gpg-agent-w32info.rc gpg-agent.w32-manifest.in AM_CPPFLAGS = @@ -32,6 +33,8 @@ include $(top_srcdir)/am/cmacros.am if HAVE_W32_SYSTEM resource_objs += gpg-agent-w32info.o + +gpg-agent-w32info.o : gpg-agent.w32-manifest ../common/w32info-rc.h endif AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) diff --git a/agent/gpg-agent-w32info.rc b/agent/gpg-agent-w32info.rc index d586cad0c..a0311b2cd 100644 --- a/agent/gpg-agent-w32info.rc +++ b/agent/gpg-agent-w32info.rc @@ -48,3 +48,5 @@ VALUE "Translation", 0x409, 0x4b0 END END + +1 RT_MANIFEST "gpg-agent.w32-manifest" diff --git a/agent/gpg-agent.w32-manifest.in b/agent/gpg-agent.w32-manifest.in new file mode 100644 index 000000000..87f09aa49 --- /dev/null +++ b/agent/gpg-agent.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (Private Key Daemon) + + + + + + + + + + + + + + + + + diff --git a/configure.ac b/configure.ac index 39cf5cbe0..fe7e82108 100644 --- a/configure.ac +++ b/configure.ac @@ -2102,6 +2102,14 @@ tests/tpm2dtests/Makefile tests/gpgme/Makefile tests/pkits/Makefile g10/gpg.w32-manifest +g10/gpgv.w32-manifest +sm/gpgsm.w32-manifest +kbx/keyboxd.w32-manifest +agent/gpg-agent.w32-manifest +scd/scdaemon.w32-manifest +dirmngr/dirmngr.w32-manifest +dirmngr/dirmngr_ldap.w32-manifest +dirmngr/dirmngr-client.w32-manifest tools/gpg-connect-agent.w32-manifest tools/gpgconf.w32-manifest tools/gpgtar.w32-manifest diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index feee2f5c8..3846fdf35 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -21,7 +21,14 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = OAUTHORS ONEWS ChangeLog-2011 tls-ca.pem +EXTRA_DIST = OAUTHORS ONEWS ChangeLog-2011 tls-ca.pem \ + dirmngr-w32info.rc dirmngr.w32-manifest.in \ + dirmngr_ldap-w32info.rc dirmngr_ldap.w32-manifest.in \ + dirmngr-client-w32info.rc dirmngr-client.w32-manifest.in + + + + dist_pkgdata_DATA = sks-keyservers.netCA.pem bin_PROGRAMS = dirmngr dirmngr-client @@ -43,6 +50,16 @@ AM_CPPFLAGS = include $(top_srcdir)/am/cmacros.am +if HAVE_W32_SYSTEM +dirmngr_rc_objs = dirmngr-w32info.o +dirmngr_ldap_rc_objs = dirmngr_ldap-w32info.o +dirmngr_client_rc_objs = dirmngr-client-w32info.o + +dirmngr-w32info.o : dirmngr.w32-manifest ../common/w32info-rc.h +dirmngr_ldap-w32info.o : dirmngr_ldap.w32-manifest ../common/w32info-rc.h +dirmngr-client-w32info.o : dirmngr-client.w32-manifest ../common/w32info-rc.h +endif + AM_CFLAGS = $(USE_C99_CFLAGS) \ $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) \ $(GPG_ERROR_CFLAGS) $(NPTH_CFLAGS) $(NTBTLS_CFLAGS) \ @@ -89,12 +106,13 @@ dirmngr_LDADD = $(libcommonpth) \ $(DNSLIBS) $(LIBASSUAN_LIBS) \ $(KSBA_LIBS) $(NPTH_LIBS) $(NTBTLS_LIBS) $(LIBGNUTLS_LIBS) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) \ - $(NETLIBS) + $(NETLIBS) $(dirmngr_rc_objs) if USE_LDAP dirmngr_LDADD += $(ldaplibs) $(LBER_LIBS) endif dirmngr_LDFLAGS = +dirmngr_DEPENDENCIES = $(dirmngr_rc_objs) if USE_LDAP dirmngr_ldap_SOURCES = dirmngr_ldap.c ldap-misc.c ldap-misc.h $(ldap_url) @@ -102,14 +120,18 @@ dirmngr_ldap_CFLAGS = $(GPG_ERROR_CFLAGS) $(LIBGCRYPT_CFLAGS) dirmngr_ldap_LDFLAGS = dirmngr_ldap_LDADD = $(libcommon) \ $(GPG_ERROR_LIBS) $(LIBGCRYPT_LIBS) $(LDAPLIBS) \ - $(LBER_LIBS) $(LIBINTL) $(LIBICONV) $(NETLIBS) + $(LBER_LIBS) $(LIBINTL) $(LIBICONV) $(NETLIBS) \ + $(dirmngr_ldap_rc_objs) +dirmngr_ldap_DEPENDENCIES = $(dirmngr_ldap_rc_objs) endif dirmngr_client_SOURCES = dirmngr-client.c dirmngr_client_LDADD = $(libcommon) \ $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ - $(LIBGCRYPT_LIBS) $(NETLIBS) $(LIBINTL) $(LIBICONV) + $(LIBGCRYPT_LIBS) $(NETLIBS) $(LIBINTL) $(LIBICONV) \ + $(dirmngr_client_rc_objs) dirmngr_client_LDFLAGS = +dirmngr_client_DEPENDENCIES = $(dirmngr_client_rc_objs) t_common_src = t-support.h t-support.c diff --git a/dirmngr/dirmngr-client-w32info.rc b/dirmngr/dirmngr-client-w32info.rc new file mode 100644 index 000000000..020447bca --- /dev/null +++ b/dirmngr/dirmngr-client-w32info.rc @@ -0,0 +1,52 @@ +/* dirmngr-client-w32info.rc -*- c -*- + * Copyright (C) 2023 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "afxres.h" +#include "../common/w32info-rc.h" + +1 ICON "../common/gnupg.ico" + +1 VERSIONINFO + FILEVERSION W32INFO_VI_FILEVERSION + PRODUCTVERSION W32INFO_VI_PRODUCTVERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x01L /* VS_FF_DEBUG (0x1)*/ +#else + FILEFLAGS 0x00L +#endif + FILEOS 0x40004L /* VOS_NT (0x40000) | VOS__WINDOWS32 (0x4) */ + FILETYPE 0x1L /* VFT_APP (0x1) */ + FILESUBTYPE 0x0L /* VFT2_UNKNOWN */ + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" /* US English (0409), Unicode (04b0) */ + BEGIN + VALUE "FileDescription", L"GnuPG\x2019s dirmngr client\0" + VALUE "InternalName", "dirmngr-client\0" + VALUE "OriginalFilename", "dirmngr-client.exe\0" + VALUE "ProductName", W32INFO_PRODUCTNAME + VALUE "ProductVersion", W32INFO_PRODUCTVERSION + VALUE "CompanyName", W32INFO_COMPANYNAME + VALUE "FileVersion", W32INFO_FILEVERSION + VALUE "LegalCopyright", W32INFO_LEGALCOPYRIGHT + VALUE "Comments", W32INFO_COMMENTS + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0x4b0 + END + END + +1 RT_MANIFEST "dirmngr-client.w32-manifest" diff --git a/dirmngr/dirmngr-client.w32-manifest.in b/dirmngr/dirmngr-client.w32-manifest.in new file mode 100644 index 000000000..1d46d19ff --- /dev/null +++ b/dirmngr/dirmngr-client.w32-manifest.in @@ -0,0 +1,25 @@ + + +GNU Privacy Guard (Dirmngr Client) + + + + + + + + + + + + + + + + + + diff --git a/dirmngr/dirmngr-w32info.rc b/dirmngr/dirmngr-w32info.rc new file mode 100644 index 000000000..cc1475b8e --- /dev/null +++ b/dirmngr/dirmngr-w32info.rc @@ -0,0 +1,52 @@ +/* dirmngr-w32info.rc -*- c -*- + * Copyright (C) 2023 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "afxres.h" +#include "../common/w32info-rc.h" + +1 ICON "../common/gnupg.ico" + +1 VERSIONINFO + FILEVERSION W32INFO_VI_FILEVERSION + PRODUCTVERSION W32INFO_VI_PRODUCTVERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x01L /* VS_FF_DEBUG (0x1)*/ +#else + FILEFLAGS 0x00L +#endif + FILEOS 0x40004L /* VOS_NT (0x40000) | VOS__WINDOWS32 (0x4) */ + FILETYPE 0x1L /* VFT_APP (0x1) */ + FILESUBTYPE 0x0L /* VFT2_UNKNOWN */ + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" /* US English (0409), Unicode (04b0) */ + BEGIN + VALUE "FileDescription", L"GnuPG\x2019s network access daemon\0" + VALUE "InternalName", "dirmngr\0" + VALUE "OriginalFilename", "dirmngr.exe\0" + VALUE "ProductName", W32INFO_PRODUCTNAME + VALUE "ProductVersion", W32INFO_PRODUCTVERSION + VALUE "CompanyName", W32INFO_COMPANYNAME + VALUE "FileVersion", W32INFO_FILEVERSION + VALUE "LegalCopyright", W32INFO_LEGALCOPYRIGHT + VALUE "Comments", W32INFO_COMMENTS + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0x4b0 + END + END + +1 RT_MANIFEST "dirmngr.w32-manifest" diff --git a/dirmngr/dirmngr.w32-manifest.in b/dirmngr/dirmngr.w32-manifest.in new file mode 100644 index 000000000..115548b5c --- /dev/null +++ b/dirmngr/dirmngr.w32-manifest.in @@ -0,0 +1,25 @@ + + +GNU Privacy Guard (Archive tool) + + + + + + + + + + + + + + + + + + diff --git a/dirmngr/dirmngr_ldap-w32info.rc b/dirmngr/dirmngr_ldap-w32info.rc new file mode 100644 index 000000000..779d85837 --- /dev/null +++ b/dirmngr/dirmngr_ldap-w32info.rc @@ -0,0 +1,52 @@ +/* dirmngr_ldap-w32info.rc -*- c -*- + * Copyright (C) 2023 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "afxres.h" +#include "../common/w32info-rc.h" + +1 ICON "../common/gnupg.ico" + +1 VERSIONINFO + FILEVERSION W32INFO_VI_FILEVERSION + PRODUCTVERSION W32INFO_VI_PRODUCTVERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x01L /* VS_FF_DEBUG (0x1)*/ +#else + FILEFLAGS 0x00L +#endif + FILEOS 0x40004L /* VOS_NT (0x40000) | VOS__WINDOWS32 (0x4) */ + FILETYPE 0x1L /* VFT_APP (0x1) */ + FILESUBTYPE 0x0L /* VFT2_UNKNOWN */ + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" /* US English (0409), Unicode (04b0) */ + BEGIN + VALUE "FileDescription", L"GnuPG\x2019s LDAP helper\0" + VALUE "InternalName", "dirmngr_ldap\0" + VALUE "OriginalFilename", "dirmngr_ldap.exe\0" + VALUE "ProductName", W32INFO_PRODUCTNAME + VALUE "ProductVersion", W32INFO_PRODUCTVERSION + VALUE "CompanyName", W32INFO_COMPANYNAME + VALUE "FileVersion", W32INFO_FILEVERSION + VALUE "LegalCopyright", W32INFO_LEGALCOPYRIGHT + VALUE "Comments", W32INFO_COMMENTS + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0x4b0 + END + END + +1 RT_MANIFEST "dirmngr_ldap.w32-manifest" diff --git a/dirmngr/dirmngr_ldap.w32-manifest.in b/dirmngr/dirmngr_ldap.w32-manifest.in new file mode 100644 index 000000000..67db0841c --- /dev/null +++ b/dirmngr/dirmngr_ldap.w32-manifest.in @@ -0,0 +1,25 @@ + + +GNU Privacy Guard (LDAP Helper) + + + + + + + + + + + + + + + + + + diff --git a/g10/Makefile.am b/g10/Makefile.am index 80b5b8919..c5691f551 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -1,3 +1,4 @@ +# Makefile.am - g10 # Copyright (C) 1998, 1999, 2000, 2001, 2002, # 2003, 2006, 2010 Free Software Foundation, Inc. # @@ -19,8 +20,9 @@ ## Process this file with automake to produce Makefile.in EXTRA_DIST = distsigkey.gpg \ - ChangeLog-2011 gpg-w32info.rc \ - gpg.w32-manifest.in test.c t-keydb-keyring.kbx \ + gpg-w32info.rc gpg.w32-manifest.in \ + gpgv-w32info.rc gpgv.w32-manifest.in \ + ChangeLog-2011 test.c t-keydb-keyring.kbx \ t-keydb-get-keyblock.gpg t-stutter-data.asc \ all-tests.scm @@ -83,10 +85,11 @@ endif if HAVE_W32_SYSTEM -resource_objs += gpg-w32info.o - -gpg-w32info.o : gpg.w32-manifest +gpg_rc_objs = gpg-w32info.o +gpgv_rc_objs = gpgv-w32info.o +gpg-w32info.o : gpg.w32-manifest ../common/w32info-rc.h +gpgv-w32info.o : gpgv.w32-manifest ../common/w32info-rc.h endif common_source = \ @@ -171,11 +174,11 @@ LDADD = $(needed_libs) ../common/libgpgrl.a \ $(ZLIBS) $(LIBINTL) $(CAPLIBS) gpg_LDADD = $(LDADD) $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) $(LIBREADLINE) \ $(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) $(NETLIBS) \ - $(LIBICONV) $(resource_objs) + $(LIBICONV) $(gpg_rc_objs) gpg_LDFLAGS = gpgv_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) \ $(LIBASSUAN_LIBS) $(NPTH_LIBS) $(GPG_ERROR_LIBS) $(NETLIBS) \ - $(LIBICONV) $(resource_objs) + $(LIBICONV) $(gpgv_rc_objs) gpgv_LDFLAGS = diff --git a/g10/gpg.w32-manifest.in b/g10/gpg.w32-manifest.in index 8c98dc5a7..bf7723925 100644 --- a/g10/gpg.w32-manifest.in +++ b/g10/gpg.w32-manifest.in @@ -14,4 +14,11 @@ + + + + + + + diff --git a/g10/gpgv-w32info.rc b/g10/gpgv-w32info.rc new file mode 100644 index 000000000..a6c1b6cd3 --- /dev/null +++ b/g10/gpgv-w32info.rc @@ -0,0 +1,52 @@ +/* gpgv-w32info.rc -*- c -*- + * Copyright (C) 2013 g10 Code GmbH + * + * This file is free software; as a special exception the author gives + * unlimited permission to copy and/or distribute it, with or without + * modifications, as long as this notice is preserved. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "afxres.h" +#include "../common/w32info-rc.h" + +1 ICON "../common/gnupg.ico" + +1 VERSIONINFO + FILEVERSION W32INFO_VI_FILEVERSION + PRODUCTVERSION W32INFO_VI_PRODUCTVERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x01L /* VS_FF_DEBUG (0x1)*/ +#else + FILEFLAGS 0x00L +#endif + FILEOS 0x40004L /* VOS_NT (0x40000) | VOS__WINDOWS32 (0x4) */ + FILETYPE 0x1L /* VFT_APP (0x1) */ + FILESUBTYPE 0x0L /* VFT2_UNKNOWN */ + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" /* US English (0409), Unicode (04b0) */ + BEGIN + VALUE "FileDescription", L"GnuPG\x2019s OpenPGP verify tool\0" + VALUE "InternalName", "gpgv\0" + VALUE "OriginalFilename", "gpgv.exe\0" + VALUE "ProductName", W32INFO_PRODUCTNAME + VALUE "ProductVersion", W32INFO_PRODUCTVERSION + VALUE "CompanyName", W32INFO_COMPANYNAME + VALUE "FileVersion", W32INFO_FILEVERSION + VALUE "LegalCopyright", W32INFO_LEGALCOPYRIGHT + VALUE "Comments", W32INFO_COMMENTS + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0x4b0 + END + END + +1 RT_MANIFEST "gpgv.w32-manifest" diff --git a/g10/gpgv.w32-manifest.in b/g10/gpgv.w32-manifest.in new file mode 100644 index 000000000..794ab15c3 --- /dev/null +++ b/g10/gpgv.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (OpenPGP verify tool) + + + + + + + + + + + + + + + + + diff --git a/kbx/Makefile.am b/kbx/Makefile.am index 66214fa5c..19bdb1061 100644 --- a/kbx/Makefile.am +++ b/kbx/Makefile.am @@ -18,13 +18,16 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = mkerrors keyboxd-w32info.rc +EXTRA_DIST = mkerrors keyboxd-w32info.rc keyboxd.w32-manifest.in AM_CPPFLAGS = include $(top_srcdir)/am/cmacros.am + if HAVE_W32_SYSTEM resource_objs += keyboxd-w32info.o + +keyboxd-w32info.o : keyboxd.w32-manifest ../common/w32info-rc.h endif AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) diff --git a/kbx/keyboxd-w32info.rc b/kbx/keyboxd-w32info.rc index 421747499..c38d9f366 100644 --- a/kbx/keyboxd-w32info.rc +++ b/kbx/keyboxd-w32info.rc @@ -48,3 +48,5 @@ VALUE "Translation", 0x409, 0x4b0 END END + +1 RT_MANIFEST "keyboxd.w32-manifest" diff --git a/kbx/keyboxd.w32-manifest.in b/kbx/keyboxd.w32-manifest.in new file mode 100644 index 000000000..f2e50fb4b --- /dev/null +++ b/kbx/keyboxd.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (Public Key Daemon) + + + + + + + + + + + + + + + + + diff --git a/scd/Makefile.am b/scd/Makefile.am index 0cc50dca8..8cbcd6e05 100644 --- a/scd/Makefile.am +++ b/scd/Makefile.am @@ -1,3 +1,4 @@ +# Makefile.am - scd # Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is part of GnuPG. @@ -17,7 +18,8 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = ChangeLog-2011 scdaemon-w32info.rc +EXTRA_DIST = ChangeLog-2011 \ + scdaemon-w32info.rc scdaemon.w32-manifest.in libexec_PROGRAMS = scdaemon @@ -27,6 +29,7 @@ include $(top_srcdir)/am/cmacros.am if HAVE_W32_SYSTEM resource_objs += scdaemon-w32info.o +scdaemon-w32info.o : scdaemon.w32-manifest ../common/w32info-rc.h endif AM_CFLAGS = $(LIBGCRYPT_CFLAGS) \ @@ -50,3 +53,5 @@ scdaemon_LDADD = $(libcommonpth) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \ $(LIBUSB_LIBS) $(GPG_ERROR_LIBS) \ $(LIBINTL) $(DL_LIBS) $(NETLIBS) $(LIBICONV) $(resource_objs) + +scdaemon_DEPENDENCIES = $(resource_objs) diff --git a/scd/scdaemon-w32info.rc b/scd/scdaemon-w32info.rc index aa0eba4e5..c1dae5421 100644 --- a/scd/scdaemon-w32info.rc +++ b/scd/scdaemon-w32info.rc @@ -48,3 +48,5 @@ VALUE "Translation", 0x409, 0x4b0 END END + +1 RT_MANIFEST "scdaemon.w32-manifest" diff --git a/scd/scdaemon.w32-manifest.in b/scd/scdaemon.w32-manifest.in new file mode 100644 index 000000000..aa0ccb206 --- /dev/null +++ b/scd/scdaemon.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (Smartcard Daemon) + + + + + + + + + + + + + + + + + diff --git a/sm/Makefile.am b/sm/Makefile.am index cfcc36c63..03de7026a 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -17,7 +17,8 @@ ## Process this file with automake to produce Makefile.in -EXTRA_DIST = ChangeLog-2011 gpgsm-w32info.rc +EXTRA_DIST = ChangeLog-2011 \ + gpgsm-w32info.rc gpgsm.w32-manifest.in bin_PROGRAMS = gpgsm noinst_PROGRAMS = $(module_tests) $(module_maint_tests) @@ -36,6 +37,7 @@ include $(top_srcdir)/am/cmacros.am if HAVE_W32_SYSTEM resource_objs += gpgsm-w32info.o +gpgsm-w32info.o : gpgsm.w32-manifest ../common/w32info-rc.h endif gpgsm_SOURCES = \ @@ -72,6 +74,7 @@ gpgsm_LDADD = $(common_libs) ../common/libgpgrl.a \ $(NPTH_LIBS) $(GPG_ERROR_LIBS) $(LIBREADLINE) $(LIBINTL) \ $(LIBICONV) $(resource_objs) $(NETLIBS) gpgsm_LDFLAGS = +gpgsm_DEPENDENCIES = $(resource_objs) module_tests = diff --git a/sm/gpgsm-w32info.rc b/sm/gpgsm-w32info.rc index d813b0dc8..537afdbc7 100644 --- a/sm/gpgsm-w32info.rc +++ b/sm/gpgsm-w32info.rc @@ -48,3 +48,5 @@ VALUE "Translation", 0x409, 0x4b0 END END + +1 RT_MANIFEST "gpgsm.w32-manifest" diff --git a/sm/gpgsm.w32-manifest.in b/sm/gpgsm.w32-manifest.in new file mode 100644 index 000000000..7764be394 --- /dev/null +++ b/sm/gpgsm.w32-manifest.in @@ -0,0 +1,24 @@ + + +GNU Privacy Guard (X.509/CMS Tool) + + + + + + + + + + + + + + + + + diff --git a/tools/Makefile.am b/tools/Makefile.am index 39374e42a..769a81a00 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -38,12 +38,17 @@ gpg_card_rc_objs = gpg-card-w32info.o gpgtar_rc_objs = gpgtar-w32info.o gpg_check_pattern_rc_objs = gpg-check-pattern-w32info.o gpg_wks_client_rc_objs = gpg-wks-client-w32info.o -resource_objs += $(gpg_connect_agent_rc_objs) -resource_objs += $(gpgconf_rc_objs) -resource_objs += $(gpg_card_tool_rc_objs) -resource_objs += $(gpgtar_rc_objs) -resource_objs += $(gpg_check_pattern_rc_objs) -resource_objs += $(gpg_wks_client_rc_objs) + +gpg-connect-agent-w32info.o : gpg-connect-agent.w32-manifest \ + ../common/w32info-rc.h +gpgconf-w32info.o : gpgconf.w32-manifest ../common/w32info-rc.h +gpg-card-w32info.o : gpg-card.w32-manifest ../common/w32info-rc.h +gpgtar-w32info.o : gpgtar.w32-manifest ../common/w32info-rc.h +gpg-check-pattern-w32info.o : gpg-check-pattern.w32-manifest \ + ../common/w32info-rc.h +gpg-wks-client-w32info.o : gpg-wks-client.w32-manifest \ + ../common/w32info-rc.h + endif AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS) diff --git a/tools/gpg-card.w32-manifest.in b/tools/gpg-card.w32-manifest.in index ab853f810..4630fce3e 100644 --- a/tools/gpg-card.w32-manifest.in +++ b/tools/gpg-card.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpg-check-pattern.w32-manifest.in b/tools/gpg-check-pattern.w32-manifest.in index 2a5f8ec72..acb7c914a 100644 --- a/tools/gpg-check-pattern.w32-manifest.in +++ b/tools/gpg-check-pattern.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpg-connect-agent.w32-manifest.in b/tools/gpg-connect-agent.w32-manifest.in index aba542052..c222a6794 100644 --- a/tools/gpg-connect-agent.w32-manifest.in +++ b/tools/gpg-connect-agent.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpg-wks-client.w32-manifest.in b/tools/gpg-wks-client.w32-manifest.in index ba2508e5f..c44620f0e 100644 --- a/tools/gpg-wks-client.w32-manifest.in +++ b/tools/gpg-wks-client.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpgconf.w32-manifest.in b/tools/gpgconf.w32-manifest.in index d7a1b01ec..ab5f17d04 100644 --- a/tools/gpgconf.w32-manifest.in +++ b/tools/gpgconf.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + diff --git a/tools/gpgtar.w32-manifest.in b/tools/gpgtar.w32-manifest.in index 62d5937fa..b949a6baa 100644 --- a/tools/gpgtar.w32-manifest.in +++ b/tools/gpgtar.w32-manifest.in @@ -15,4 +15,11 @@ + + + + + + + From 6657230f9ee40ca0cfcfd16c12b3288a975944b0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 May 2023 14:16:10 +0200 Subject: [PATCH 018/869] w32: Add missing supportedOS Ids for Windows-10 -- --- agent/gpg-agent.w32-manifest.in | 1 + dirmngr/dirmngr-client.w32-manifest.in | 2 +- dirmngr/dirmngr_ldap.w32-manifest.in | 2 +- g10/gpg.w32-manifest.in | 1 + g10/gpgv.w32-manifest.in | 1 + kbx/keyboxd.w32-manifest.in | 1 + scd/scdaemon.w32-manifest.in | 1 + sm/gpgsm.w32-manifest.in | 1 + 8 files changed, 8 insertions(+), 2 deletions(-) diff --git a/agent/gpg-agent.w32-manifest.in b/agent/gpg-agent.w32-manifest.in index 87f09aa49..7991a9699 100644 --- a/agent/gpg-agent.w32-manifest.in +++ b/agent/gpg-agent.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/dirmngr/dirmngr-client.w32-manifest.in b/dirmngr/dirmngr-client.w32-manifest.in index 1d46d19ff..670bb60f1 100644 --- a/dirmngr/dirmngr-client.w32-manifest.in +++ b/dirmngr/dirmngr-client.w32-manifest.in @@ -3,7 +3,7 @@ GNU Privacy Guard (Dirmngr Client) diff --git a/dirmngr/dirmngr_ldap.w32-manifest.in b/dirmngr/dirmngr_ldap.w32-manifest.in index 67db0841c..509b5e0d1 100644 --- a/dirmngr/dirmngr_ldap.w32-manifest.in +++ b/dirmngr/dirmngr_ldap.w32-manifest.in @@ -3,7 +3,7 @@ GNU Privacy Guard (LDAP Helper) diff --git a/g10/gpg.w32-manifest.in b/g10/gpg.w32-manifest.in index bf7723925..9a7752382 100644 --- a/g10/gpg.w32-manifest.in +++ b/g10/gpg.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/g10/gpgv.w32-manifest.in b/g10/gpgv.w32-manifest.in index 794ab15c3..66291a2bc 100644 --- a/g10/gpgv.w32-manifest.in +++ b/g10/gpgv.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/kbx/keyboxd.w32-manifest.in b/kbx/keyboxd.w32-manifest.in index f2e50fb4b..ff75ea504 100644 --- a/kbx/keyboxd.w32-manifest.in +++ b/kbx/keyboxd.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/scd/scdaemon.w32-manifest.in b/scd/scdaemon.w32-manifest.in index aa0ccb206..224646661 100644 --- a/scd/scdaemon.w32-manifest.in +++ b/scd/scdaemon.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/sm/gpgsm.w32-manifest.in b/sm/gpgsm.w32-manifest.in index 7764be394..d477cce32 100644 --- a/sm/gpgsm.w32-manifest.in +++ b/sm/gpgsm.w32-manifest.in @@ -12,6 +12,7 @@ + From 8295fb3f0b4fc33ba02456c7588cae4df2b490ed Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 May 2023 14:16:10 +0200 Subject: [PATCH 019/869] w32: Add missing supportedOS Ids for Windows-10 -- --- agent/gpg-agent.w32-manifest.in | 1 + dirmngr/dirmngr-client.w32-manifest.in | 2 +- dirmngr/dirmngr_ldap.w32-manifest.in | 2 +- g10/gpg.w32-manifest.in | 1 + g10/gpgv.w32-manifest.in | 1 + kbx/keyboxd.w32-manifest.in | 1 + scd/scdaemon.w32-manifest.in | 1 + sm/gpgsm.w32-manifest.in | 1 + 8 files changed, 8 insertions(+), 2 deletions(-) diff --git a/agent/gpg-agent.w32-manifest.in b/agent/gpg-agent.w32-manifest.in index 87f09aa49..7991a9699 100644 --- a/agent/gpg-agent.w32-manifest.in +++ b/agent/gpg-agent.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/dirmngr/dirmngr-client.w32-manifest.in b/dirmngr/dirmngr-client.w32-manifest.in index 1d46d19ff..670bb60f1 100644 --- a/dirmngr/dirmngr-client.w32-manifest.in +++ b/dirmngr/dirmngr-client.w32-manifest.in @@ -3,7 +3,7 @@ GNU Privacy Guard (Dirmngr Client) diff --git a/dirmngr/dirmngr_ldap.w32-manifest.in b/dirmngr/dirmngr_ldap.w32-manifest.in index 67db0841c..509b5e0d1 100644 --- a/dirmngr/dirmngr_ldap.w32-manifest.in +++ b/dirmngr/dirmngr_ldap.w32-manifest.in @@ -3,7 +3,7 @@ GNU Privacy Guard (LDAP Helper) diff --git a/g10/gpg.w32-manifest.in b/g10/gpg.w32-manifest.in index bf7723925..9a7752382 100644 --- a/g10/gpg.w32-manifest.in +++ b/g10/gpg.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/g10/gpgv.w32-manifest.in b/g10/gpgv.w32-manifest.in index 794ab15c3..66291a2bc 100644 --- a/g10/gpgv.w32-manifest.in +++ b/g10/gpgv.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/kbx/keyboxd.w32-manifest.in b/kbx/keyboxd.w32-manifest.in index f2e50fb4b..ff75ea504 100644 --- a/kbx/keyboxd.w32-manifest.in +++ b/kbx/keyboxd.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/scd/scdaemon.w32-manifest.in b/scd/scdaemon.w32-manifest.in index aa0ccb206..224646661 100644 --- a/scd/scdaemon.w32-manifest.in +++ b/scd/scdaemon.w32-manifest.in @@ -12,6 +12,7 @@ + diff --git a/sm/gpgsm.w32-manifest.in b/sm/gpgsm.w32-manifest.in index 7764be394..d477cce32 100644 --- a/sm/gpgsm.w32-manifest.in +++ b/sm/gpgsm.w32-manifest.in @@ -12,6 +12,7 @@ + From 80097bc78bf7bcc0bef9f125af3c545620cd5cc7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 May 2023 16:02:39 +0200 Subject: [PATCH 020/869] gpg: Return ERROR status for --quick-sign-key. * g10/keyedit.c (keyedit_quick_sign): Return an error status line. -- --- g10/keyedit.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/g10/keyedit.c b/g10/keyedit.c index 4b767aed6..e16a40ead 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -2810,7 +2810,7 @@ void keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids, strlist_t locusr, int local) { - gpg_error_t err; + gpg_error_t err = 0; kbnode_t keyblock = NULL; KEYDB_HANDLE kdbhd = NULL; int modified = 0; @@ -2848,6 +2848,7 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids, if (!opt.verbose) show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1); log_error ("%s%s", _("Key is revoked."), _(" Unable to sign.\n")); + err = gpg_error (GPG_ERR_CERT_REVOKED); goto leave; } @@ -2925,6 +2926,7 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids, sl->d, gpg_strerror (GPG_ERR_NOT_FOUND)); } log_error ("%s %s", _("No matching user IDs."), _("Nothing to sign.\n")); + err = gpg_error (GPG_ERR_NO_USER_ID); goto leave; } @@ -2947,8 +2949,9 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids, if (update_trust) revalidation_mark (ctrl); - leave: + if (err) + write_status_error ("keyedit.sign-key", err); release_kbnode (keyblock); keydb_release (kdbhd); } @@ -2964,7 +2967,7 @@ void keyedit_quick_revsig (ctrl_t ctrl, const char *username, const char *sigtorev, strlist_t affected_uids) { - gpg_error_t err; + gpg_error_t err = 0; int no_signing_key = 0; KEYDB_HANDLE kdbhd = NULL; kbnode_t keyblock = NULL; From 000b82ade7ad1a4b78c82c2c2caea607e42e66f0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 May 2023 16:02:39 +0200 Subject: [PATCH 021/869] gpg: Return ERROR status for --quick-sign-key. * g10/keyedit.c (keyedit_quick_sign): Return an error status line. -- --- g10/keyedit.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/g10/keyedit.c b/g10/keyedit.c index 4b767aed6..e16a40ead 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -2810,7 +2810,7 @@ void keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids, strlist_t locusr, int local) { - gpg_error_t err; + gpg_error_t err = 0; kbnode_t keyblock = NULL; KEYDB_HANDLE kdbhd = NULL; int modified = 0; @@ -2848,6 +2848,7 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids, if (!opt.verbose) show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1); log_error ("%s%s", _("Key is revoked."), _(" Unable to sign.\n")); + err = gpg_error (GPG_ERR_CERT_REVOKED); goto leave; } @@ -2925,6 +2926,7 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids, sl->d, gpg_strerror (GPG_ERR_NOT_FOUND)); } log_error ("%s %s", _("No matching user IDs."), _("Nothing to sign.\n")); + err = gpg_error (GPG_ERR_NO_USER_ID); goto leave; } @@ -2947,8 +2949,9 @@ keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids, if (update_trust) revalidation_mark (ctrl); - leave: + if (err) + write_status_error ("keyedit.sign-key", err); release_kbnode (keyblock); keydb_release (kdbhd); } @@ -2964,7 +2967,7 @@ void keyedit_quick_revsig (ctrl_t ctrl, const char *username, const char *sigtorev, strlist_t affected_uids) { - gpg_error_t err; + gpg_error_t err = 0; int no_signing_key = 0; KEYDB_HANDLE kdbhd = NULL; kbnode_t keyblock = NULL; From 6a2cb8cfd71457599fee4a63da6f649fdd07deb5 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 25 May 2023 11:07:51 +0900 Subject: [PATCH 022/869] agent,w32: Fix resource leak for a process. * agent/call-daemon.c (wait_child_thread): Call assuan_set_flag only for !HAVE_W32_SYSTEM. Signed-off-by: NIIBE Yutaka --- agent/call-daemon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/call-daemon.c b/agent/call-daemon.c index 0c3605274..e1c5669e9 100644 --- a/agent/call-daemon.c +++ b/agent/call-daemon.c @@ -153,6 +153,8 @@ wait_child_thread (void *arg) name, WSTOPSIG (wstatus)); goto again; } + + assuan_set_flag (g->primary_ctx, ASSUAN_NO_WAITPID, 1); } #endif /*!HAVE_W32_SYSTEM*/ @@ -166,8 +168,6 @@ wait_child_thread (void *arg) } else { - assuan_set_flag (g->primary_ctx, ASSUAN_NO_WAITPID, 1); - for (sl = g->local_list; sl; sl = sl->next_local) { sl->invalid = 1; From 0f8e5f1c1db03c88416eb5b21091251f4a7a8176 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 25 May 2023 11:13:07 +0900 Subject: [PATCH 023/869] po: Update Japanese Translation. -- Signed-off-by: NIIBE Yutaka --- po/ja.po | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/po/ja.po b/po/ja.po index 9d286148b..236d78ced 100644 --- a/po/ja.po +++ b/po/ja.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg 2.4.1\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-04-26 13:35+0900\n" +"PO-Revision-Date: 2023-05-25 11:12+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -226,8 +226,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"パスフレーズを入力してください。gpg-agentの鍵の保管で受信した秘密鍵%%0A %s" -"%%0A %s%%0Aを保護します。" +"パスフレーズを入力してください。gpg-agentの鍵の保管で受信した秘密鍵%%0A " +"%s%%0A %s%%0Aを保護します。" #, c-format msgid "failed to create stream from socket: %s\n" @@ -759,8 +759,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "本当にこの鍵: keygrip%%0A %s%%0A %%C%%0Aを削除しますか?" msgid "Delete key" @@ -3710,6 +3710,10 @@ msgstr "*警告*: あなたの暗号副鍵はもうすぐ期限切れとなり msgid "You may want to change its expiration date too.\n" msgstr "その有効期限も変更したいでしょう\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "*警告*: 有効な暗号副鍵がひとつも残っていません。\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" From 6984ddc6ebf5b95f7e78076abb798875805498e6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 25 May 2023 11:36:11 +0900 Subject: [PATCH 024/869] common,w32: Fix gnupg_process_release. * common/exechelp-w32.c: Close the handle of the process. Signed-off-by: NIIBE Yutaka --- common/exechelp-w32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 8057cc3b4..f63341e7c 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -1213,6 +1213,7 @@ gnupg_process_release (gnupg_process_t process) gnupg_process_wait (process, 1); } + CloseHandle (process->hProcess); xfree (process); } From 39a437378015661c765c906f1ed744fb2bf0fcfd Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 25 May 2023 11:13:07 +0900 Subject: [PATCH 025/869] po: Update Japanese Translation. -- Signed-off-by: NIIBE Yutaka --- po/ja.po | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/po/ja.po b/po/ja.po index 9d286148b..236d78ced 100644 --- a/po/ja.po +++ b/po/ja.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg 2.4.1\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-04-26 13:35+0900\n" +"PO-Revision-Date: 2023-05-25 11:12+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -226,8 +226,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"パスフレーズを入力してください。gpg-agentの鍵の保管で受信した秘密鍵%%0A %s" -"%%0A %s%%0Aを保護します。" +"パスフレーズを入力してください。gpg-agentの鍵の保管で受信した秘密鍵%%0A " +"%s%%0A %s%%0Aを保護します。" #, c-format msgid "failed to create stream from socket: %s\n" @@ -759,8 +759,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "本当にこの鍵: keygrip%%0A %s%%0A %%C%%0Aを削除しますか?" msgid "Delete key" @@ -3710,6 +3710,10 @@ msgstr "*警告*: あなたの暗号副鍵はもうすぐ期限切れとなり msgid "You may want to change its expiration date too.\n" msgstr "その有効期限も変更したいでしょう\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "*警告*: 有効な暗号副鍵がひとつも残っていません。\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" From 14828c75be10d61f35a46c58541aa39884b33bcd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 May 2023 11:57:04 +0200 Subject: [PATCH 026/869] gpg: Fix searching for the ADSK key when adding an ADSK. * g10/keyedit.c (menu_addadsk): Request an exact search. * g10/getkey.c (finish_lookup): Add an debug output. -- GnuPG-bug-id: 6504 --- g10/getkey.c | 3 +++ g10/keyedit.c | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/g10/getkey.c b/g10/getkey.c index 15905dc63..68d7ee61d 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3655,6 +3655,9 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, break; } } + if (DBG_LOOKUP) + log_debug ("finish_lookup: exact search requested: %sfound\n", + foundk? "":"not "); } /* Get the user id that matched that low-level search criteria. */ diff --git a/g10/keyedit.c b/g10/keyedit.c index e16a40ead..21c1ee8d8 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -4844,6 +4844,15 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr) continue; } + /* Force searching for that exact fingerprint and for any key + * which has a key with that fingerprint. */ + if (!strchr (answer, '!')) + { + char *tmpstr = xstrconcat (answer, "!", NULL); + xfree (answer); + answer = tmpstr; + } + free_public_key (adsk_pk); adsk_pk = xcalloc (1, sizeof *adsk_pk); adsk_pk->req_usage = PUBKEY_USAGE_ENC; From e9dd47d789e85d9cefcf77a4d37667c2f8bbcd69 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 May 2023 11:57:04 +0200 Subject: [PATCH 027/869] gpg: Fix searching for the ADSK key when adding an ADSK. * g10/keyedit.c (menu_addadsk): Request an exact search. * g10/getkey.c (finish_lookup): Add an debug output. -- GnuPG-bug-id: 6504 --- g10/getkey.c | 3 +++ g10/keyedit.c | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/g10/getkey.c b/g10/getkey.c index 15905dc63..68d7ee61d 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3655,6 +3655,9 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, break; } } + if (DBG_LOOKUP) + log_debug ("finish_lookup: exact search requested: %sfound\n", + foundk? "":"not "); } /* Get the user id that matched that low-level search criteria. */ diff --git a/g10/keyedit.c b/g10/keyedit.c index e16a40ead..21c1ee8d8 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -4844,6 +4844,15 @@ menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, const char *adskfpr) continue; } + /* Force searching for that exact fingerprint and for any key + * which has a key with that fingerprint. */ + if (!strchr (answer, '!')) + { + char *tmpstr = xstrconcat (answer, "!", NULL); + xfree (answer); + answer = tmpstr; + } + free_public_key (adsk_pk); adsk_pk = xcalloc (1, sizeof *adsk_pk); adsk_pk->req_usage = PUBKEY_USAGE_ENC; From 9f2f7a51b2430056168363828722afc6c7488946 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 May 2023 16:43:37 +0200 Subject: [PATCH 028/869] gpg: Skip keys found via ADSKs. * g10/encrypt.c (write_pubkey_enc): Indicate encryption to an ADSK. * g10/getkey.c (finish_lookup): Skip ADKS keys. -- If a key is searched by fingerprint or keyid and it happens that this is an ADSK (subkey with the RENC usage), we need to skip this key because it is not the key we actually want to encrypt to. The actual ADSK key is taken later by looking at all subkeys of the actual selected key. This is related to GnuPG-bug-id: 6504 --- g10/encrypt.c | 6 ++++++ g10/getkey.c | 37 ++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/g10/encrypt.c b/g10/encrypt.c index 687b4344e..ff1c6be85 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -1171,6 +1171,12 @@ write_pubkey_enc (ctrl_t ctrl, if ( opt.verbose ) { char *ustr = get_user_id_string_native (ctrl, enc->keyid); + if ((pk->pubkey_usage & PUBKEY_USAGE_RENC)) + { + char *tmpustr = xstrconcat (ustr, " [ADSK]", NULL); + xfree (ustr); + ustr = tmpustr; + } log_info (_("%s/%s.%s encrypted for: \"%s\"\n"), openpgp_pk_algo_name (enc->pubkey_algo), openpgp_cipher_algo_name (dek->algo), diff --git a/g10/getkey.c b/g10/getkey.c index 68d7ee61d..21ffd5cfa 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3640,24 +3640,31 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY); /* For an exact match mark the primary or subkey that matched the - low-level search criteria. */ - if (want_exact) + * low-level search criteria. Use this loop also to sort our keys + * found using an ADSK fingerprint. */ + for (k = keyblock; k; k = k->next) { - for (k = keyblock; k; k = k->next) - { - if ((k->flag & 1)) - { - log_assert (k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY); - foundk = k; + if ((k->flag & 1) && (k->pkt->pkttype == PKT_PUBLIC_KEY + || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)) + { + if (want_exact) + { + if (DBG_LOOKUP) + log_debug ("finish_lookup: exact search requested and found\n"); + foundk = k; pk = k->pkt->pkt.public_key; pk->flags.exact = 1; - break; - } - } - if (DBG_LOOKUP) - log_debug ("finish_lookup: exact search requested: %sfound\n", - foundk? "":"not "); + break; + } + else if ((k->pkt->pkt.public_key->pubkey_usage == PUBKEY_USAGE_RENC)) + { + if (DBG_LOOKUP) + log_debug ("finish_lookup: found via ADSK - not selected\n"); + if (r_flags) + *r_flags |= LOOKUP_NOT_SELECTED; + return NULL; /* Not found. */ + } + } } /* Get the user id that matched that low-level search criteria. */ From 09a96c9e1bea73bb80cbaf4c74381999421a1316 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 May 2023 16:43:37 +0200 Subject: [PATCH 029/869] gpg: Skip keys found via ADSKs. * g10/encrypt.c (write_pubkey_enc): Indicate encryption to an ADSK. * g10/getkey.c (finish_lookup): Skip ADKS keys. -- If a key is searched by fingerprint or keyid and it happens that this is an ADSK (subkey with the RENC usage), we need to skip this key because it is not the key we actually want to encrypt to. The actual ADSK key is taken later by looking at all subkeys of the actual selected key. This is related to GnuPG-bug-id: 6504 --- g10/encrypt.c | 6 ++++++ g10/getkey.c | 37 ++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/g10/encrypt.c b/g10/encrypt.c index a524326bb..00d9a0c44 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -1146,6 +1146,12 @@ write_pubkey_enc (ctrl_t ctrl, if ( opt.verbose ) { char *ustr = get_user_id_string_native (ctrl, enc->keyid); + if ((pk->pubkey_usage & PUBKEY_USAGE_RENC)) + { + char *tmpustr = xstrconcat (ustr, " [ADSK]", NULL); + xfree (ustr); + ustr = tmpustr; + } log_info (_("%s/%s.%s encrypted for: \"%s\"\n"), openpgp_pk_algo_name (enc->pubkey_algo), openpgp_cipher_algo_name (dek->algo), diff --git a/g10/getkey.c b/g10/getkey.c index 68d7ee61d..21ffd5cfa 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3640,24 +3640,31 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY); /* For an exact match mark the primary or subkey that matched the - low-level search criteria. */ - if (want_exact) + * low-level search criteria. Use this loop also to sort our keys + * found using an ADSK fingerprint. */ + for (k = keyblock; k; k = k->next) { - for (k = keyblock; k; k = k->next) - { - if ((k->flag & 1)) - { - log_assert (k->pkt->pkttype == PKT_PUBLIC_KEY - || k->pkt->pkttype == PKT_PUBLIC_SUBKEY); - foundk = k; + if ((k->flag & 1) && (k->pkt->pkttype == PKT_PUBLIC_KEY + || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)) + { + if (want_exact) + { + if (DBG_LOOKUP) + log_debug ("finish_lookup: exact search requested and found\n"); + foundk = k; pk = k->pkt->pkt.public_key; pk->flags.exact = 1; - break; - } - } - if (DBG_LOOKUP) - log_debug ("finish_lookup: exact search requested: %sfound\n", - foundk? "":"not "); + break; + } + else if ((k->pkt->pkt.public_key->pubkey_usage == PUBKEY_USAGE_RENC)) + { + if (DBG_LOOKUP) + log_debug ("finish_lookup: found via ADSK - not selected\n"); + if (r_flags) + *r_flags |= LOOKUP_NOT_SELECTED; + return NULL; /* Not found. */ + } + } } /* Get the user id that matched that low-level search criteria. */ From f15a643a2d45c5ac2fbd80568d031808d6058f41 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 26 May 2023 15:28:13 +0900 Subject: [PATCH 030/869] agent,dirmngr: Shutdown fix for supervised mode. * agent/gpg-agent.c (handle_connections): Break if supervised. * dirmngr/dirmngr.c (is_supervised): New. (handle_connections): Break if supervised. -- For supervised agent/dirmngr, 'systemctl stop' behaves just like 'gpgconf --kill', ignoring existing connections. Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 2 +- dirmngr/dirmngr.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 1db422737..e55cd0b7c 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -3115,7 +3115,7 @@ handle_connections (gnupg_fd_t listen_fd, /* Shutdown test. */ if (shutdown_pending) { - if (active_connections == 0) + if (active_connections == 0 || is_supervised) break; /* ready */ /* Do not accept new connections but keep on running the diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index bb54f4edd..50338f216 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -382,6 +382,9 @@ static enum } tor_mode; +/* Flag indicating that we are in supervised mode. */ +static int is_supervised; + /* Counter for the active connections. */ static int active_connections; @@ -1303,6 +1306,8 @@ main (int argc, char **argv) if (!opt.quiet) log_info(_("WARNING: \"%s\" is a deprecated option\n"), "--supervised"); + is_supervised = 1; + /* In supervised mode, we expect file descriptor 3 to be an already opened, listening socket. @@ -2362,7 +2367,7 @@ handle_connections (assuan_fd_t listen_fd) /* Shutdown test. */ if (shutdown_pending) { - if (!active_connections) + if (!active_connections || is_supervised) break; /* ready */ /* Do not accept new connections but keep on running the From a048a93ed2c3171cfc21b830762adada8965d92c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 May 2023 11:56:36 +0200 Subject: [PATCH 031/869] common: New function nve_set * common/name-value.c (nve_set): New. -- Taken from 2.2 commit 706adf669173ec604158e4a2f4337e3da6cb1e45 --- common/name-value.c | 24 ++++++++++++++++++++++++ common/name-value.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/common/name-value.c b/common/name-value.c index 67429e47f..6f3df5a8d 100644 --- a/common/name-value.c +++ b/common/name-value.c @@ -497,6 +497,30 @@ nvc_set (nvc_t pk, const char *name, const char *value) } +/* Update entry E to VALUE. */ +gpg_error_t +nve_set (nve_t e, const char *value) +{ + char *v; + + if (!e) + return GPG_ERR_INV_ARG; + + v = xtrystrdup (value? value:""); + if (!v) + return my_error_from_syserror (); + + free_strlist_wipe (e->raw_value); + e->raw_value = NULL; + if (e->value) + wipememory (e->value, strlen (e->value)); + xfree (e->value); + e->value = v; + + return 0; +} + + /* Delete the given entry from PK. */ void nvc_delete (nvc_t pk, nve_t entry) diff --git a/common/name-value.h b/common/name-value.h index 504b5d0f0..b3fc2f63c 100644 --- a/common/name-value.h +++ b/common/name-value.h @@ -92,6 +92,9 @@ gpg_error_t nvc_add (nvc_t pk, const char *name, const char *value); first entry is updated. */ gpg_error_t nvc_set (nvc_t pk, const char *name, const char *value); +/* Update entry E to VALUE. */ +gpg_error_t nve_set (nve_t e, const char *value); + /* Delete the given entry from PK. */ void nvc_delete (nvc_t pk, nve_t pke); From 13013ec1c0d308b5d22f176f3850840cbbf21f05 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 May 2023 11:59:46 +0200 Subject: [PATCH 032/869] agent: Create and use Token entries to track the display s/n. * agent/findkey.c (agent_write_private_key): Add arg dispserialno and update the token. (agent_write_shadow_key): Add arg dispserialno and adjust all callers. -- GnuPG-bug-id: 6135 Note that this has been forward ported from 2.2 --- agent/agent.h | 13 ++++++---- agent/command-ssh.c | 9 +++++-- agent/command.c | 15 ++++++++--- agent/cvt-openpgp.c | 4 +-- agent/divert-tpm2.c | 2 +- agent/findkey.c | 61 ++++++++++++++++++++++++++++++++++++-------- agent/genkey.c | 3 ++- agent/learncard.c | 10 +++++++- agent/pksign.c | 9 ++++++- agent/protect-tool.c | 5 ++-- 10 files changed, 102 insertions(+), 29 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 4e7452eee..531fad210 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -452,10 +452,12 @@ void start_command_handler_ssh (ctrl_t, gnupg_fd_t); /*-- findkey.c --*/ gpg_error_t agent_modify_description (const char *in, const char *comment, const gcry_sexp_t key, char **result); -int agent_write_private_key (const unsigned char *grip, - const void *buffer, size_t length, int force, - const char *serialno, const char *keyref, - time_t timestamp); +gpg_error_t agent_write_private_key (const unsigned char *grip, + const void *buffer, size_t length, + int force, + const char *serialno, const char *keyref, + const char *dispserialno, + time_t timestamp); gpg_error_t agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, @@ -587,7 +589,8 @@ gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo, unsigned char *key, size_t keylen); gpg_error_t agent_write_shadow_key (const unsigned char *grip, const char *serialno, const char *keyid, - const unsigned char *pkbuf, int force); + const unsigned char *pkbuf, int force, + const char *dispserialno); /*-- trustlist.c --*/ diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 51111a60d..ca3993321 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2432,9 +2432,14 @@ card_key_available (ctrl_t ctrl, const struct card_key_info_s *keyinfo, hex2bin (keyinfo->keygrip, grip, sizeof (grip)); if ( agent_key_available (grip) ) { + char *dispserialno; + /* (Shadow)-key is not available in our key storage. */ + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, + keyinfo->keygrip); err = agent_write_shadow_key (grip, keyinfo->serialno, - keyinfo->idstr, pkbuf, 0); + keyinfo->idstr, pkbuf, 0, dispserialno); + xfree (dispserialno); if (err) { xfree (pkbuf); @@ -3282,7 +3287,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, /* Store this key to our key storage. We do not store a creation * timestamp because we simply do not know. */ err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0, - NULL, NULL, 0); + NULL, NULL, NULL, 0); if (err) goto out; diff --git a/agent/command.c b/agent/command.c index dd7cb5e57..b7a71cbe5 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1359,7 +1359,14 @@ cmd_readkey (assuan_context_t ctx, char *line) if (agent_key_available (grip)) { /* (Shadow)-key is not available in our key storage. */ - rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0); + char *dispserialno; + char hexgrip[40+1]; + + bin2hex (grip, 20, hexgrip); + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, hexgrip); + rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0, + dispserialno); + xfree (dispserialno); if (rc) goto leave; } @@ -2916,11 +2923,11 @@ cmd_import_key (assuan_context_t ctx, char *line) ctrl->s2k_count); if (!err) err = agent_write_private_key (grip, finalkey, finalkeylen, force, - NULL, NULL, opt_timestamp); + NULL, NULL, NULL, opt_timestamp); } else - err = agent_write_private_key (grip, key, realkeylen, force, NULL, NULL, - opt_timestamp); + err = agent_write_private_key (grip, key, realkeylen, force, + NULL, NULL, NULL, opt_timestamp); leave: gcry_sexp_release (openpgp_sexp); diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 9bb815ff8..6aad35bff 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -1148,7 +1148,7 @@ convert_from_openpgp_native (ctrl_t ctrl, &protectedkey, &protectedkeylen, ctrl->s2k_count)) agent_write_private_key (grip, protectedkey, protectedkeylen, 1, - NULL, NULL, 0); + NULL, NULL, NULL, 0); xfree (protectedkey); } else @@ -1157,7 +1157,7 @@ convert_from_openpgp_native (ctrl_t ctrl, agent_write_private_key (grip, *r_key, gcry_sexp_canon_len (*r_key, 0, NULL,NULL), - 1, NULL, NULL, 0); + 1, NULL, NULL, NULL, 0); } } diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index 4cae66218..b2f884f93 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -50,7 +50,7 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); err = agent_write_private_key (grip, shdkey, len, 1 /*force*/, - NULL, NULL, 0); + NULL, NULL, NULL, 0); xfree (shdkey); if (err) log_error ("error writing key: %s\n", gpg_strerror (err)); diff --git a/agent/findkey.c b/agent/findkey.c index 098d5224f..a9cb96a0c 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -84,12 +84,13 @@ linefeed_to_percent0A (const char *string) * storage. With FORCE passed as true an existing key with the given * GRIP will get overwritten. If SERIALNO and KEYREF are given a * Token line is added to the key if the extended format is used. If - * TIMESTAMP is not zero and the key doies not yet exists it will be + * TIMESTAMP is not zero and the key does not yet exists it will be * recorded as creation date. */ -int +gpg_error_t agent_write_private_key (const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, + const char *dispserialno, time_t timestamp) { gpg_error_t err; @@ -100,7 +101,10 @@ agent_write_private_key (const unsigned char *grip, nvc_t pk = NULL; gcry_sexp_t key = NULL; int remove = 0; + char *token0 = NULL; char *token = NULL; + char *dispserialno_buffer = NULL; + char **tokenfields = NULL; bin2hex (grip, 20, hexgrip); strcpy (hexgrip+40, ".key"); @@ -225,19 +229,34 @@ agent_write_private_key (const unsigned char *grip, { nve_t item; const char *s; + size_t token0len; - token = strconcat (serialno, " ", keyref, NULL); - if (!token) + if (dispserialno) + { + /* Escape the DISPSERIALNO. */ + dispserialno_buffer = percent_plus_escape (dispserialno); + if (!dispserialno_buffer) + { + err = gpg_error_from_syserror (); + goto leave; + } + dispserialno = dispserialno_buffer; + } + + token0 = strconcat (serialno, " ", keyref, NULL); + if (token0) + token = strconcat (token0, " - ", dispserialno? dispserialno:"-", NULL); + if (!token0 || !token) { err = gpg_error_from_syserror (); goto leave; } - /* fixme: the strcmp should compare only the first two strings. */ + token0len = strlen (token0); for (item = nvc_lookup (pk, "Token:"); item; item = nve_next_value (item, "Token:")) - if ((s = nve_value (item)) && !strcmp (s, token)) + if ((s = nve_value (item)) && !strncmp (s, token0, token0len)) break; if (!item) { @@ -248,6 +267,23 @@ agent_write_private_key (const unsigned char *grip, if (err) goto leave; } + else + { + /* Token exists: Update the display s/n. It may have + * changed due to changes in a newer software version. */ + if (s && (tokenfields = strtokenize (s, " \t\n")) + && tokenfields[0] && tokenfields[1] && tokenfields[2] + && tokenfields[3] + && !strcmp (tokenfields[3], dispserialno)) + ; /* No need to update Token entry. */ + else + { + err = nve_set (item, token); + if (err) + goto leave; + } + } + } /* If a timestamp has been supplied and the key is new, write a @@ -300,12 +336,15 @@ agent_write_private_key (const unsigned char *grip, leave: es_fclose (fp); - if (remove) + if (remove && fname) gnupg_remove (fname); xfree (fname); + xfree (token); + xfree (token0); + xfree (dispserialno_buffer); + xfree (tokenfields); gcry_sexp_release (key); nvc_release (pk); - xfree (token); return err; } @@ -1794,7 +1833,8 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text, gpg_error_t agent_write_shadow_key (const unsigned char *grip, const char *serialno, const char *keyid, - const unsigned char *pkbuf, int force) + const unsigned char *pkbuf, int force, + const char *dispserialno) { gpg_error_t err; unsigned char *shadow_info; @@ -1821,7 +1861,8 @@ agent_write_shadow_key (const unsigned char *grip, } len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); - err = agent_write_private_key (grip, shdkey, len, force, serialno, keyid, 0); + err = agent_write_private_key (grip, shdkey, len, force, + serialno, keyid, dispserialno, 0); xfree (shdkey); if (err) log_error ("error writing key: %s\n", gpg_strerror (err)); diff --git a/agent/genkey.c b/agent/genkey.c index 7660443ca..741c05f4f 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -67,7 +67,8 @@ store_key (gcry_sexp_t private, const char *passphrase, int force, buf = p; } - rc = agent_write_private_key (grip, buf, len, force, NULL, NULL, timestamp); + rc = agent_write_private_key (grip, buf, len, force, + NULL, NULL, NULL, timestamp); xfree (buf); return rc; } diff --git a/agent/learncard.c b/agent/learncard.c index 678ff9b96..8d80b809d 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -408,7 +408,15 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force) goto leave; } - rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force); + { + char *dispserialno; + + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, + item->hexgrip); + rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force, + dispserialno); + xfree (dispserialno); + } xfree (pubkey); if (rc) goto leave; diff --git a/agent/pksign.c b/agent/pksign.c index dfed0e398..a7b5c579f 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -372,8 +372,15 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, } if (keyref) - agent_write_shadow_key (ctrl->keygrip, serialno, keyref, pkbuf, 0); + { + char *dispserialno; + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, + hexgrip); + agent_write_shadow_key (ctrl->keygrip, serialno, keyref, pkbuf, + 0, dispserialno); + xfree (dispserialno); + } algo = get_pk_algo_from_key (s_pkey); xfree (serialno); diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 87cf36814..17f6fd559 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -813,11 +813,11 @@ agent_askpin (ctrl_t ctrl, /* Replacement for the function in findkey.c. Here we write the key * to stdout. */ -int +gpg_error_t agent_write_private_key (const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, - time_t timestamp) + const char *dispserialno, time_t timestamp) { char hexgrip[40+4+1]; char *p; @@ -826,6 +826,7 @@ agent_write_private_key (const unsigned char *grip, (void)serialno; (void)keyref; (void)timestamp; + (void)dispserialno; bin2hex (grip, 20, hexgrip); strcpy (hexgrip+40, ".key"); From 05f29b5c7caa6cdac94218029153a2b5451c8281 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 May 2023 13:57:36 +0200 Subject: [PATCH 033/869] agent: Update key files by first writing to a temp file. * agent/findkey.c (fname_from_keygrip): New. (agent_write_private_key): Use here. Use temp file for updating. (agent_update_private_key): Use fname_from_keygrip and use gnupg rename function instead of a vanilla rename. --- agent/findkey.c | 169 ++++++++++++++++++++++++++++-------------------- 1 file changed, 100 insertions(+), 69 deletions(-) diff --git a/agent/findkey.c b/agent/findkey.c index a9cb96a0c..2d0636cd2 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -50,6 +50,22 @@ struct try_unprotect_arg_s }; +/* Return the file name for the 20 byte keygrip GRIP. With FOR_NEW + * create a file name for later renaming to the actual name. Return + * NULL on error. */ +static char * +fname_from_keygrip (const unsigned char *grip, int for_new) +{ + char hexgrip[40+4+4+1]; + + bin2hex (grip, 20, hexgrip); + strcpy (hexgrip+40, for_new? ".key.tmp" : ".key"); + + return make_filename_try (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, + hexgrip, NULL); +} + + /* Replace all linefeeds in STRING by "%0A" and return a new malloced * string. May return NULL on memory error. */ static char * @@ -94,26 +110,22 @@ agent_write_private_key (const unsigned char *grip, time_t timestamp) { gpg_error_t err; - char *fname; + char *fname = NULL; + char *tmpfname = NULL; estream_t fp; - char hexgrip[40+4+1]; int update, newkey; nvc_t pk = NULL; gcry_sexp_t key = NULL; - int remove = 0; + int removetmp = 0; char *token0 = NULL; char *token = NULL; char *dispserialno_buffer = NULL; char **tokenfields = NULL; + int blocksigs = 0; - bin2hex (grip, 20, hexgrip); - strcpy (hexgrip+40, ".key"); - - fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, - hexgrip, NULL); - - /* FIXME: Write to a temp file first so that write failures during - key updates won't lead to a key loss. */ + fname = fname_from_keygrip (grip, 0); + if (!fname) + return gpg_error_from_syserror (); if (!force && !gnupg_access (fname, F_OK)) { @@ -213,7 +225,8 @@ agent_write_private_key (const unsigned char *grip, goto leave; } } - es_clearerr (fp); + es_fclose (fp); + fp = NULL; /* Turn (BUFFER,LENGTH) into a gcrypt s-expression and set it into * our name value container. */ @@ -299,46 +312,55 @@ agent_write_private_key (const unsigned char *grip, goto leave; } - /* Back to start and write. */ - err = es_fseek (fp, 0, SEEK_SET); - if (err) - goto leave; - - err = nvc_write (pk, fp); - if (!err) - err = es_fflush (fp); - if (err) + /* Create a temporary file for writing. */ + tmpfname = fname_from_keygrip (grip, 1); + fp = tmpfname ? es_fopen (tmpfname, "wbx,mode=-rw") : NULL; + if (!fp) { - log_error ("error writing '%s': %s\n", fname, gpg_strerror (err)); - remove = 1; + err = gpg_error_from_syserror (); + log_error ("can't create '%s': %s\n", tmpfname, gpg_strerror (err)); goto leave; } - if (ftruncate (es_fileno (fp), es_ftello (fp))) + err = nvc_write (pk, fp); + if (!err && es_fflush (fp)) + err = gpg_error_from_syserror (); + if (err) { - err = gpg_error_from_syserror (); - log_error ("error truncating '%s': %s\n", fname, gpg_strerror (err)); - remove = 1; + log_error ("error writing '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; goto leave; } if (es_fclose (fp)) { err = gpg_error_from_syserror (); - log_error ("error closing '%s': %s\n", fname, gpg_strerror (err)); - remove = 1; + log_error ("error closing '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; goto leave; } else fp = NULL; + err = gnupg_rename_file (tmpfname, fname, &blocksigs); + if (err) + { + err = gpg_error_from_syserror (); + log_error ("error renaming '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } + bump_key_eventcounter (); leave: + if (blocksigs) + gnupg_unblock_all_signals (); es_fclose (fp); - if (remove && fname) + if (removetmp && fname) gnupg_remove (fname); xfree (fname); + xfree (tmpfname); xfree (token); xfree (token0); xfree (dispserialno_buffer); @@ -352,53 +374,63 @@ agent_write_private_key (const unsigned char *grip, gpg_error_t agent_update_private_key (const unsigned char *grip, nvc_t pk) { - char *fname, *fname0; - estream_t fp; - char hexgrip[40+8+1]; gpg_error_t err; + char *fname0 = NULL; /* The existing file name. */ + char *fname = NULL; /* The temporary new file name. */ + estream_t fp = NULL; + int removetmp = 0; + int blocksigs = 0; - bin2hex (grip, 20, hexgrip); - strcpy (hexgrip+40, ".key.tmp"); - - fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, - hexgrip, NULL); - fname0 = xstrdup (fname); - if (!fname0) + fname0 = fname_from_keygrip (grip, 0); + if (!fname) { err = gpg_error_from_syserror (); - xfree (fname); - return err; + goto leave; + } + fname = fname_from_keygrip (grip, 1); + if (!fname) + { + err = gpg_error_from_syserror (); + goto leave; } - fname0[strlen (fname)-4] = 0; fp = es_fopen (fname, "wbx,mode=-rw"); if (!fp) { err = gpg_error_from_syserror (); - log_error ("can't create '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - return err; + goto leave; } err = nvc_write (pk, fp); if (err) - log_error ("error writing '%s': %s\n", fname, gpg_strerror (err)); - - es_fclose (fp); - -#ifdef HAVE_W32_SYSTEM - /* No atomic mv on W32 systems. */ - gnupg_remove (fname0); -#endif - if (rename (fname, fname0)) { - err = gpg_error_from_errno (errno); - log_error (_("error renaming '%s' to '%s': %s\n"), - fname, fname0, strerror (errno)); + log_error ("error writing '%s': %s\n", fname, gpg_strerror (err)); + removetmp = 1; + goto leave; } + es_fclose (fp); + fp = NULL; + + err = gnupg_rename_file (fname, fname0, &blocksigs); + if (err) + { + err = gpg_error_from_syserror (); + log_error ("error renaming '%s': %s\n", fname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } + + + leave: + if (blocksigs) + gnupg_unblock_all_signals (); + es_fclose (fp); + if (removetmp && fname) + gnupg_remove (fname); xfree (fname); + xfree (fname0); return err; } @@ -885,18 +917,17 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta) unsigned char *buf; size_t buflen, erroff; gcry_sexp_t s_skey; - char hexgrip[40+4+1]; char first; *result = NULL; if (r_keymeta) *r_keymeta = NULL; - bin2hex (grip, 20, hexgrip); - strcpy (hexgrip+40, ".key"); - - fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, - hexgrip, NULL); + fname = fname_from_keygrip (grip, 0); + if (!fname) + { + return gpg_error_from_syserror (); + } fp = es_fopen (fname, "rb"); if (!fp) { @@ -1012,12 +1043,12 @@ remove_key_file (const unsigned char *grip) { gpg_error_t err = 0; char *fname; - char hexgrip[40+4+1]; - bin2hex (grip, 20, hexgrip); - strcpy (hexgrip+40, ".key"); - fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, - hexgrip, NULL); + fname = fname_from_keygrip (grip, 0); + if (!fname) + { + return gpg_error_from_syserror (); + } if (gnupg_remove (fname)) err = gpg_error_from_syserror (); xfree (fname); From a1015bf2fc07dabb1200eab5fa41f13e7bf98202 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 May 2023 14:24:55 +0200 Subject: [PATCH 034/869] agent: Do not overwrite a key file by a shadow key file. * agent/findkey.c (agent_write_private_key): Partly rewrite to align with 2.2 code and to make sure that we don't overwrite a real key. (is_shadowed_key): New. -- This change is now also needed in 2.4 due to the the former change "Create and use Token entries to track the display s/n". GnuPG-bug-id: 6386 --- agent/findkey.c | 154 ++++++++++++++++++++---------------------------- 1 file changed, 64 insertions(+), 90 deletions(-) diff --git a/agent/findkey.c b/agent/findkey.c index 2d0636cd2..41f911cf8 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -39,6 +39,12 @@ #define O_BINARY 0 #endif + +static gpg_error_t read_key_file (const unsigned char *grip, + gcry_sexp_t *result, nvc_t *r_keymeta); +static gpg_error_t is_shadowed_key (gcry_sexp_t s_skey); + + /* Helper to pass data to the check callback of the unprotect function. */ struct try_unprotect_arg_s { @@ -113,7 +119,7 @@ agent_write_private_key (const unsigned char *grip, char *fname = NULL; char *tmpfname = NULL; estream_t fp; - int update, newkey; + int newkey; nvc_t pk = NULL; gcry_sexp_t key = NULL; int removetmp = 0; @@ -121,103 +127,29 @@ agent_write_private_key (const unsigned char *grip, char *token = NULL; char *dispserialno_buffer = NULL; char **tokenfields = NULL; + int is_regular; int blocksigs = 0; fname = fname_from_keygrip (grip, 0); if (!fname) return gpg_error_from_syserror (); - if (!force && !gnupg_access (fname, F_OK)) + err = read_key_file (grip, &key, &pk); + if (err) { - log_error ("secret key file '%s' already exists\n", fname); - xfree (fname); - return gpg_error (GPG_ERR_EEXIST); - } - - fp = es_fopen (fname, force? "rb+,mode=-rw" : "wbx,mode=-rw"); - if (!fp) - { - gpg_error_t tmperr = gpg_error_from_syserror (); - - if (force && gpg_err_code (tmperr) == GPG_ERR_ENOENT) - { - fp = es_fopen (fname, "wbx,mode=-rw"); - if (!fp) - tmperr = gpg_error_from_syserror (); - } - if (!fp) - { - log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr)); - xfree (fname); - return tmperr; - } - update = 0; - newkey = 1; - } - else if (force) - { - gpg_error_t rc; - char first; - - /* See if an existing key is in extended format. */ - if (es_fread (&first, 1, 1, fp) != 1) - { - rc = gpg_error_from_syserror (); - log_error ("error reading first byte from '%s': %s\n", - fname, strerror (errno)); - xfree (fname); - es_fclose (fp); - return rc; - } - - rc = es_fseek (fp, 0, SEEK_SET); - if (rc) - { - log_error ("error seeking in '%s': %s\n", fname, strerror (errno)); - xfree (fname); - es_fclose (fp); - return rc; - } - - if (first == '(') - { - /* Key is still in the old format - force it into extended - * format. We do not request an update here because an - * existing key is not yet in extended key format and no - * extended infos are yet available. */ - update = 0; - newkey = 0; - } + if (gpg_err_code (err) == GPG_ERR_ENOENT) + newkey = 1; else { - /* Key is already in the extended format. */ - update = 1; - newkey = 0; - } - } - else - { - /* The key file did not exist: we assume this is a new key and - * write the Created: entry. */ - update = 0; - newkey = 1; - } - - - if (update) - { - int line; - - err = nvc_parse_private_key (&pk, &line, fp); - if (err && gpg_err_code (err) != GPG_ERR_ENOENT) - { - log_error ("error parsing '%s' line %d: %s\n", - fname, line, gpg_strerror (err)); + log_error ("can't open '%s': %s\n", fname, gpg_strerror (err)); goto leave; } } - else + + if (!pk) { + /* Key is still in the old format or does not exist - create a + * new container. */ pk = nvc_new_private_key (); if (!pk) { @@ -225,11 +157,13 @@ agent_write_private_key (const unsigned char *grip, goto leave; } } - es_fclose (fp); - fp = NULL; + + /* Check whether we already have a regular key. */ + is_regular = (key && gpg_err_code (is_shadowed_key (key)) != GPG_ERR_TRUE); /* Turn (BUFFER,LENGTH) into a gcrypt s-expression and set it into * our name value container. */ + gcry_sexp_release (key); err = gcry_sexp_sscan (&key, NULL, buffer, length); if (err) goto leave; @@ -237,6 +171,23 @@ agent_write_private_key (const unsigned char *grip, if (err) goto leave; + /* Check that we do not update a regular key with a shadow key. */ + if (is_regular && gpg_err_code (is_shadowed_key (key)) == GPG_ERR_TRUE) + { + log_info ("updating regular key file '%s'" + " by a shadow key inhibited\n", fname); + err = 0; /* Simply ignore the error. */ + goto leave; + } + + /* Check that we update a regular key only in force mode. */ + if (is_regular && !force) + { + log_error ("secret key file '%s' already exists\n", fname); + err = gpg_error (GPG_ERR_EEXIST); + goto leave; + } + /* If requested write a Token line. */ if (serialno && keyref) { @@ -357,8 +308,8 @@ agent_write_private_key (const unsigned char *grip, if (blocksigs) gnupg_unblock_all_signals (); es_fclose (fp); - if (removetmp && fname) - gnupg_remove (fname); + if (removetmp && tmpfname) + gnupg_remove (tmpfname); xfree (fname); xfree (tmpfname); xfree (token); @@ -903,7 +854,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, /* Read the key identified by GRIP from the private key directory and * return it as an gcrypt S-expression object in RESULT. If R_KEYMETA - * is not NULl and the extended key format is used, the meta data + * is not NULL and the extended key format is used, the meta data * items are stored there. However the "Key:" item is removed from * it. On failure returns an error code and stores NULL at RESULT and * R_KEYMETA. */ @@ -1447,6 +1398,29 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, } +/* This function returns GPG_ERR_TRUE if S_SKEY represents a shadowed + * key. 0 is return for other key types. Any other error may occur + * if S_SKEY is not valid. */ +static gpg_error_t +is_shadowed_key (gcry_sexp_t s_skey) +{ + gpg_error_t err; + unsigned char *buf; + size_t buflen; + + err = make_canon_sexp (s_skey, &buf, &buflen); + if (err) + return err; + + if (agent_private_key_type (buf) == PRIVATE_KEY_SHADOWED) + err = gpg_error (GPG_ERR_TRUE); + + wipememory (buf, buflen); + xfree (buf); + return err; +} + + /* Return the key for the keygrip GRIP. The result is stored at RESULT. This function extracts the key from the private key database and returns it as an S-expression object as it is. On From ec0c35d1b8be02e4d6c43b77e25c354741b27231 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 May 2023 11:56:36 +0200 Subject: [PATCH 035/869] common: New function nve_set * common/name-value.c (nve_set): New. -- Taken from 2.2 commit 706adf669173ec604158e4a2f4337e3da6cb1e45 --- common/name-value.c | 24 ++++++++++++++++++++++++ common/name-value.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/common/name-value.c b/common/name-value.c index 67429e47f..6f3df5a8d 100644 --- a/common/name-value.c +++ b/common/name-value.c @@ -497,6 +497,30 @@ nvc_set (nvc_t pk, const char *name, const char *value) } +/* Update entry E to VALUE. */ +gpg_error_t +nve_set (nve_t e, const char *value) +{ + char *v; + + if (!e) + return GPG_ERR_INV_ARG; + + v = xtrystrdup (value? value:""); + if (!v) + return my_error_from_syserror (); + + free_strlist_wipe (e->raw_value); + e->raw_value = NULL; + if (e->value) + wipememory (e->value, strlen (e->value)); + xfree (e->value); + e->value = v; + + return 0; +} + + /* Delete the given entry from PK. */ void nvc_delete (nvc_t pk, nve_t entry) diff --git a/common/name-value.h b/common/name-value.h index 504b5d0f0..b3fc2f63c 100644 --- a/common/name-value.h +++ b/common/name-value.h @@ -92,6 +92,9 @@ gpg_error_t nvc_add (nvc_t pk, const char *name, const char *value); first entry is updated. */ gpg_error_t nvc_set (nvc_t pk, const char *name, const char *value); +/* Update entry E to VALUE. */ +gpg_error_t nve_set (nve_t e, const char *value); + /* Delete the given entry from PK. */ void nvc_delete (nvc_t pk, nve_t pke); From 1d23dc9389a12600a1002600f97dcff659cede44 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 May 2023 11:59:46 +0200 Subject: [PATCH 036/869] agent: Create and use Token entries to track the display s/n. * agent/findkey.c (agent_write_private_key): Add arg dispserialno and update the token. (agent_write_shadow_key): Add arg dispserialno and adjust all callers. -- GnuPG-bug-id: 6135 Note that this has been forward ported from 2.2 --- agent/agent.h | 13 ++++++---- agent/command-ssh.c | 9 +++++-- agent/command.c | 15 ++++++++--- agent/cvt-openpgp.c | 4 +-- agent/divert-tpm2.c | 2 +- agent/findkey.c | 61 ++++++++++++++++++++++++++++++++++++-------- agent/genkey.c | 3 ++- agent/learncard.c | 10 +++++++- agent/pksign.c | 9 ++++++- agent/protect-tool.c | 5 ++-- 10 files changed, 102 insertions(+), 29 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 4e7452eee..531fad210 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -452,10 +452,12 @@ void start_command_handler_ssh (ctrl_t, gnupg_fd_t); /*-- findkey.c --*/ gpg_error_t agent_modify_description (const char *in, const char *comment, const gcry_sexp_t key, char **result); -int agent_write_private_key (const unsigned char *grip, - const void *buffer, size_t length, int force, - const char *serialno, const char *keyref, - time_t timestamp); +gpg_error_t agent_write_private_key (const unsigned char *grip, + const void *buffer, size_t length, + int force, + const char *serialno, const char *keyref, + const char *dispserialno, + time_t timestamp); gpg_error_t agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, @@ -587,7 +589,8 @@ gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo, unsigned char *key, size_t keylen); gpg_error_t agent_write_shadow_key (const unsigned char *grip, const char *serialno, const char *keyid, - const unsigned char *pkbuf, int force); + const unsigned char *pkbuf, int force, + const char *dispserialno); /*-- trustlist.c --*/ diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 51111a60d..ca3993321 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2432,9 +2432,14 @@ card_key_available (ctrl_t ctrl, const struct card_key_info_s *keyinfo, hex2bin (keyinfo->keygrip, grip, sizeof (grip)); if ( agent_key_available (grip) ) { + char *dispserialno; + /* (Shadow)-key is not available in our key storage. */ + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, + keyinfo->keygrip); err = agent_write_shadow_key (grip, keyinfo->serialno, - keyinfo->idstr, pkbuf, 0); + keyinfo->idstr, pkbuf, 0, dispserialno); + xfree (dispserialno); if (err) { xfree (pkbuf); @@ -3282,7 +3287,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, /* Store this key to our key storage. We do not store a creation * timestamp because we simply do not know. */ err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0, - NULL, NULL, 0); + NULL, NULL, NULL, 0); if (err) goto out; diff --git a/agent/command.c b/agent/command.c index dd7cb5e57..b7a71cbe5 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1359,7 +1359,14 @@ cmd_readkey (assuan_context_t ctx, char *line) if (agent_key_available (grip)) { /* (Shadow)-key is not available in our key storage. */ - rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0); + char *dispserialno; + char hexgrip[40+1]; + + bin2hex (grip, 20, hexgrip); + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, hexgrip); + rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0, + dispserialno); + xfree (dispserialno); if (rc) goto leave; } @@ -2916,11 +2923,11 @@ cmd_import_key (assuan_context_t ctx, char *line) ctrl->s2k_count); if (!err) err = agent_write_private_key (grip, finalkey, finalkeylen, force, - NULL, NULL, opt_timestamp); + NULL, NULL, NULL, opt_timestamp); } else - err = agent_write_private_key (grip, key, realkeylen, force, NULL, NULL, - opt_timestamp); + err = agent_write_private_key (grip, key, realkeylen, force, + NULL, NULL, NULL, opt_timestamp); leave: gcry_sexp_release (openpgp_sexp); diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 9bb815ff8..6aad35bff 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -1148,7 +1148,7 @@ convert_from_openpgp_native (ctrl_t ctrl, &protectedkey, &protectedkeylen, ctrl->s2k_count)) agent_write_private_key (grip, protectedkey, protectedkeylen, 1, - NULL, NULL, 0); + NULL, NULL, NULL, 0); xfree (protectedkey); } else @@ -1157,7 +1157,7 @@ convert_from_openpgp_native (ctrl_t ctrl, agent_write_private_key (grip, *r_key, gcry_sexp_canon_len (*r_key, 0, NULL,NULL), - 1, NULL, NULL, 0); + 1, NULL, NULL, NULL, 0); } } diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index 4cae66218..b2f884f93 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -50,7 +50,7 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); err = agent_write_private_key (grip, shdkey, len, 1 /*force*/, - NULL, NULL, 0); + NULL, NULL, NULL, 0); xfree (shdkey); if (err) log_error ("error writing key: %s\n", gpg_strerror (err)); diff --git a/agent/findkey.c b/agent/findkey.c index 098d5224f..a9cb96a0c 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -84,12 +84,13 @@ linefeed_to_percent0A (const char *string) * storage. With FORCE passed as true an existing key with the given * GRIP will get overwritten. If SERIALNO and KEYREF are given a * Token line is added to the key if the extended format is used. If - * TIMESTAMP is not zero and the key doies not yet exists it will be + * TIMESTAMP is not zero and the key does not yet exists it will be * recorded as creation date. */ -int +gpg_error_t agent_write_private_key (const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, + const char *dispserialno, time_t timestamp) { gpg_error_t err; @@ -100,7 +101,10 @@ agent_write_private_key (const unsigned char *grip, nvc_t pk = NULL; gcry_sexp_t key = NULL; int remove = 0; + char *token0 = NULL; char *token = NULL; + char *dispserialno_buffer = NULL; + char **tokenfields = NULL; bin2hex (grip, 20, hexgrip); strcpy (hexgrip+40, ".key"); @@ -225,19 +229,34 @@ agent_write_private_key (const unsigned char *grip, { nve_t item; const char *s; + size_t token0len; - token = strconcat (serialno, " ", keyref, NULL); - if (!token) + if (dispserialno) + { + /* Escape the DISPSERIALNO. */ + dispserialno_buffer = percent_plus_escape (dispserialno); + if (!dispserialno_buffer) + { + err = gpg_error_from_syserror (); + goto leave; + } + dispserialno = dispserialno_buffer; + } + + token0 = strconcat (serialno, " ", keyref, NULL); + if (token0) + token = strconcat (token0, " - ", dispserialno? dispserialno:"-", NULL); + if (!token0 || !token) { err = gpg_error_from_syserror (); goto leave; } - /* fixme: the strcmp should compare only the first two strings. */ + token0len = strlen (token0); for (item = nvc_lookup (pk, "Token:"); item; item = nve_next_value (item, "Token:")) - if ((s = nve_value (item)) && !strcmp (s, token)) + if ((s = nve_value (item)) && !strncmp (s, token0, token0len)) break; if (!item) { @@ -248,6 +267,23 @@ agent_write_private_key (const unsigned char *grip, if (err) goto leave; } + else + { + /* Token exists: Update the display s/n. It may have + * changed due to changes in a newer software version. */ + if (s && (tokenfields = strtokenize (s, " \t\n")) + && tokenfields[0] && tokenfields[1] && tokenfields[2] + && tokenfields[3] + && !strcmp (tokenfields[3], dispserialno)) + ; /* No need to update Token entry. */ + else + { + err = nve_set (item, token); + if (err) + goto leave; + } + } + } /* If a timestamp has been supplied and the key is new, write a @@ -300,12 +336,15 @@ agent_write_private_key (const unsigned char *grip, leave: es_fclose (fp); - if (remove) + if (remove && fname) gnupg_remove (fname); xfree (fname); + xfree (token); + xfree (token0); + xfree (dispserialno_buffer); + xfree (tokenfields); gcry_sexp_release (key); nvc_release (pk); - xfree (token); return err; } @@ -1794,7 +1833,8 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text, gpg_error_t agent_write_shadow_key (const unsigned char *grip, const char *serialno, const char *keyid, - const unsigned char *pkbuf, int force) + const unsigned char *pkbuf, int force, + const char *dispserialno) { gpg_error_t err; unsigned char *shadow_info; @@ -1821,7 +1861,8 @@ agent_write_shadow_key (const unsigned char *grip, } len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); - err = agent_write_private_key (grip, shdkey, len, force, serialno, keyid, 0); + err = agent_write_private_key (grip, shdkey, len, force, + serialno, keyid, dispserialno, 0); xfree (shdkey); if (err) log_error ("error writing key: %s\n", gpg_strerror (err)); diff --git a/agent/genkey.c b/agent/genkey.c index 563407253..cf37cdafc 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -67,7 +67,8 @@ store_key (gcry_sexp_t private, const char *passphrase, int force, buf = p; } - rc = agent_write_private_key (grip, buf, len, force, NULL, NULL, timestamp); + rc = agent_write_private_key (grip, buf, len, force, + NULL, NULL, NULL, timestamp); xfree (buf); return rc; } diff --git a/agent/learncard.c b/agent/learncard.c index 678ff9b96..8d80b809d 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -408,7 +408,15 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force) goto leave; } - rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force); + { + char *dispserialno; + + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, + item->hexgrip); + rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force, + dispserialno); + xfree (dispserialno); + } xfree (pubkey); if (rc) goto leave; diff --git a/agent/pksign.c b/agent/pksign.c index dfed0e398..a7b5c579f 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -372,8 +372,15 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, } if (keyref) - agent_write_shadow_key (ctrl->keygrip, serialno, keyref, pkbuf, 0); + { + char *dispserialno; + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, + hexgrip); + agent_write_shadow_key (ctrl->keygrip, serialno, keyref, pkbuf, + 0, dispserialno); + xfree (dispserialno); + } algo = get_pk_algo_from_key (s_pkey); xfree (serialno); diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 87cf36814..17f6fd559 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -813,11 +813,11 @@ agent_askpin (ctrl_t ctrl, /* Replacement for the function in findkey.c. Here we write the key * to stdout. */ -int +gpg_error_t agent_write_private_key (const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, - time_t timestamp) + const char *dispserialno, time_t timestamp) { char hexgrip[40+4+1]; char *p; @@ -826,6 +826,7 @@ agent_write_private_key (const unsigned char *grip, (void)serialno; (void)keyref; (void)timestamp; + (void)dispserialno; bin2hex (grip, 20, hexgrip); strcpy (hexgrip+40, ".key"); From a216e9c028ee389c4bf0250b822d567ffe9ad85e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 May 2023 13:57:36 +0200 Subject: [PATCH 037/869] agent: Update key files by first writing to a temp file. * agent/findkey.c (fname_from_keygrip): New. (agent_write_private_key): Use here. Use temp file for updating. (agent_update_private_key): Use fname_from_keygrip and use gnupg rename function instead of a vanilla rename. --- agent/findkey.c | 169 ++++++++++++++++++++++++++++-------------------- 1 file changed, 100 insertions(+), 69 deletions(-) diff --git a/agent/findkey.c b/agent/findkey.c index a9cb96a0c..2d0636cd2 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -50,6 +50,22 @@ struct try_unprotect_arg_s }; +/* Return the file name for the 20 byte keygrip GRIP. With FOR_NEW + * create a file name for later renaming to the actual name. Return + * NULL on error. */ +static char * +fname_from_keygrip (const unsigned char *grip, int for_new) +{ + char hexgrip[40+4+4+1]; + + bin2hex (grip, 20, hexgrip); + strcpy (hexgrip+40, for_new? ".key.tmp" : ".key"); + + return make_filename_try (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, + hexgrip, NULL); +} + + /* Replace all linefeeds in STRING by "%0A" and return a new malloced * string. May return NULL on memory error. */ static char * @@ -94,26 +110,22 @@ agent_write_private_key (const unsigned char *grip, time_t timestamp) { gpg_error_t err; - char *fname; + char *fname = NULL; + char *tmpfname = NULL; estream_t fp; - char hexgrip[40+4+1]; int update, newkey; nvc_t pk = NULL; gcry_sexp_t key = NULL; - int remove = 0; + int removetmp = 0; char *token0 = NULL; char *token = NULL; char *dispserialno_buffer = NULL; char **tokenfields = NULL; + int blocksigs = 0; - bin2hex (grip, 20, hexgrip); - strcpy (hexgrip+40, ".key"); - - fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, - hexgrip, NULL); - - /* FIXME: Write to a temp file first so that write failures during - key updates won't lead to a key loss. */ + fname = fname_from_keygrip (grip, 0); + if (!fname) + return gpg_error_from_syserror (); if (!force && !gnupg_access (fname, F_OK)) { @@ -213,7 +225,8 @@ agent_write_private_key (const unsigned char *grip, goto leave; } } - es_clearerr (fp); + es_fclose (fp); + fp = NULL; /* Turn (BUFFER,LENGTH) into a gcrypt s-expression and set it into * our name value container. */ @@ -299,46 +312,55 @@ agent_write_private_key (const unsigned char *grip, goto leave; } - /* Back to start and write. */ - err = es_fseek (fp, 0, SEEK_SET); - if (err) - goto leave; - - err = nvc_write (pk, fp); - if (!err) - err = es_fflush (fp); - if (err) + /* Create a temporary file for writing. */ + tmpfname = fname_from_keygrip (grip, 1); + fp = tmpfname ? es_fopen (tmpfname, "wbx,mode=-rw") : NULL; + if (!fp) { - log_error ("error writing '%s': %s\n", fname, gpg_strerror (err)); - remove = 1; + err = gpg_error_from_syserror (); + log_error ("can't create '%s': %s\n", tmpfname, gpg_strerror (err)); goto leave; } - if (ftruncate (es_fileno (fp), es_ftello (fp))) + err = nvc_write (pk, fp); + if (!err && es_fflush (fp)) + err = gpg_error_from_syserror (); + if (err) { - err = gpg_error_from_syserror (); - log_error ("error truncating '%s': %s\n", fname, gpg_strerror (err)); - remove = 1; + log_error ("error writing '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; goto leave; } if (es_fclose (fp)) { err = gpg_error_from_syserror (); - log_error ("error closing '%s': %s\n", fname, gpg_strerror (err)); - remove = 1; + log_error ("error closing '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; goto leave; } else fp = NULL; + err = gnupg_rename_file (tmpfname, fname, &blocksigs); + if (err) + { + err = gpg_error_from_syserror (); + log_error ("error renaming '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } + bump_key_eventcounter (); leave: + if (blocksigs) + gnupg_unblock_all_signals (); es_fclose (fp); - if (remove && fname) + if (removetmp && fname) gnupg_remove (fname); xfree (fname); + xfree (tmpfname); xfree (token); xfree (token0); xfree (dispserialno_buffer); @@ -352,53 +374,63 @@ agent_write_private_key (const unsigned char *grip, gpg_error_t agent_update_private_key (const unsigned char *grip, nvc_t pk) { - char *fname, *fname0; - estream_t fp; - char hexgrip[40+8+1]; gpg_error_t err; + char *fname0 = NULL; /* The existing file name. */ + char *fname = NULL; /* The temporary new file name. */ + estream_t fp = NULL; + int removetmp = 0; + int blocksigs = 0; - bin2hex (grip, 20, hexgrip); - strcpy (hexgrip+40, ".key.tmp"); - - fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, - hexgrip, NULL); - fname0 = xstrdup (fname); - if (!fname0) + fname0 = fname_from_keygrip (grip, 0); + if (!fname) { err = gpg_error_from_syserror (); - xfree (fname); - return err; + goto leave; + } + fname = fname_from_keygrip (grip, 1); + if (!fname) + { + err = gpg_error_from_syserror (); + goto leave; } - fname0[strlen (fname)-4] = 0; fp = es_fopen (fname, "wbx,mode=-rw"); if (!fp) { err = gpg_error_from_syserror (); - log_error ("can't create '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - return err; + goto leave; } err = nvc_write (pk, fp); if (err) - log_error ("error writing '%s': %s\n", fname, gpg_strerror (err)); - - es_fclose (fp); - -#ifdef HAVE_W32_SYSTEM - /* No atomic mv on W32 systems. */ - gnupg_remove (fname0); -#endif - if (rename (fname, fname0)) { - err = gpg_error_from_errno (errno); - log_error (_("error renaming '%s' to '%s': %s\n"), - fname, fname0, strerror (errno)); + log_error ("error writing '%s': %s\n", fname, gpg_strerror (err)); + removetmp = 1; + goto leave; } + es_fclose (fp); + fp = NULL; + + err = gnupg_rename_file (fname, fname0, &blocksigs); + if (err) + { + err = gpg_error_from_syserror (); + log_error ("error renaming '%s': %s\n", fname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } + + + leave: + if (blocksigs) + gnupg_unblock_all_signals (); + es_fclose (fp); + if (removetmp && fname) + gnupg_remove (fname); xfree (fname); + xfree (fname0); return err; } @@ -885,18 +917,17 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta) unsigned char *buf; size_t buflen, erroff; gcry_sexp_t s_skey; - char hexgrip[40+4+1]; char first; *result = NULL; if (r_keymeta) *r_keymeta = NULL; - bin2hex (grip, 20, hexgrip); - strcpy (hexgrip+40, ".key"); - - fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, - hexgrip, NULL); + fname = fname_from_keygrip (grip, 0); + if (!fname) + { + return gpg_error_from_syserror (); + } fp = es_fopen (fname, "rb"); if (!fp) { @@ -1012,12 +1043,12 @@ remove_key_file (const unsigned char *grip) { gpg_error_t err = 0; char *fname; - char hexgrip[40+4+1]; - bin2hex (grip, 20, hexgrip); - strcpy (hexgrip+40, ".key"); - fname = make_filename (gnupg_homedir (), GNUPG_PRIVATE_KEYS_DIR, - hexgrip, NULL); + fname = fname_from_keygrip (grip, 0); + if (!fname) + { + return gpg_error_from_syserror (); + } if (gnupg_remove (fname)) err = gpg_error_from_syserror (); xfree (fname); From 2783b786a9314894d76807b00789df09fe70d1d1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 May 2023 14:24:55 +0200 Subject: [PATCH 038/869] agent: Do not overwrite a key file by a shadow key file. * agent/findkey.c (agent_write_private_key): Partly rewrite to align with 2.2 code and to make sure that we don't overwrite a real key. (is_shadowed_key): New. -- This change is now also needed in 2.4 due to the the former change "Create and use Token entries to track the display s/n". GnuPG-bug-id: 6386 --- agent/findkey.c | 154 ++++++++++++++++++++---------------------------- 1 file changed, 64 insertions(+), 90 deletions(-) diff --git a/agent/findkey.c b/agent/findkey.c index 2d0636cd2..41f911cf8 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -39,6 +39,12 @@ #define O_BINARY 0 #endif + +static gpg_error_t read_key_file (const unsigned char *grip, + gcry_sexp_t *result, nvc_t *r_keymeta); +static gpg_error_t is_shadowed_key (gcry_sexp_t s_skey); + + /* Helper to pass data to the check callback of the unprotect function. */ struct try_unprotect_arg_s { @@ -113,7 +119,7 @@ agent_write_private_key (const unsigned char *grip, char *fname = NULL; char *tmpfname = NULL; estream_t fp; - int update, newkey; + int newkey; nvc_t pk = NULL; gcry_sexp_t key = NULL; int removetmp = 0; @@ -121,103 +127,29 @@ agent_write_private_key (const unsigned char *grip, char *token = NULL; char *dispserialno_buffer = NULL; char **tokenfields = NULL; + int is_regular; int blocksigs = 0; fname = fname_from_keygrip (grip, 0); if (!fname) return gpg_error_from_syserror (); - if (!force && !gnupg_access (fname, F_OK)) + err = read_key_file (grip, &key, &pk); + if (err) { - log_error ("secret key file '%s' already exists\n", fname); - xfree (fname); - return gpg_error (GPG_ERR_EEXIST); - } - - fp = es_fopen (fname, force? "rb+,mode=-rw" : "wbx,mode=-rw"); - if (!fp) - { - gpg_error_t tmperr = gpg_error_from_syserror (); - - if (force && gpg_err_code (tmperr) == GPG_ERR_ENOENT) - { - fp = es_fopen (fname, "wbx,mode=-rw"); - if (!fp) - tmperr = gpg_error_from_syserror (); - } - if (!fp) - { - log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr)); - xfree (fname); - return tmperr; - } - update = 0; - newkey = 1; - } - else if (force) - { - gpg_error_t rc; - char first; - - /* See if an existing key is in extended format. */ - if (es_fread (&first, 1, 1, fp) != 1) - { - rc = gpg_error_from_syserror (); - log_error ("error reading first byte from '%s': %s\n", - fname, strerror (errno)); - xfree (fname); - es_fclose (fp); - return rc; - } - - rc = es_fseek (fp, 0, SEEK_SET); - if (rc) - { - log_error ("error seeking in '%s': %s\n", fname, strerror (errno)); - xfree (fname); - es_fclose (fp); - return rc; - } - - if (first == '(') - { - /* Key is still in the old format - force it into extended - * format. We do not request an update here because an - * existing key is not yet in extended key format and no - * extended infos are yet available. */ - update = 0; - newkey = 0; - } + if (gpg_err_code (err) == GPG_ERR_ENOENT) + newkey = 1; else { - /* Key is already in the extended format. */ - update = 1; - newkey = 0; - } - } - else - { - /* The key file did not exist: we assume this is a new key and - * write the Created: entry. */ - update = 0; - newkey = 1; - } - - - if (update) - { - int line; - - err = nvc_parse_private_key (&pk, &line, fp); - if (err && gpg_err_code (err) != GPG_ERR_ENOENT) - { - log_error ("error parsing '%s' line %d: %s\n", - fname, line, gpg_strerror (err)); + log_error ("can't open '%s': %s\n", fname, gpg_strerror (err)); goto leave; } } - else + + if (!pk) { + /* Key is still in the old format or does not exist - create a + * new container. */ pk = nvc_new_private_key (); if (!pk) { @@ -225,11 +157,13 @@ agent_write_private_key (const unsigned char *grip, goto leave; } } - es_fclose (fp); - fp = NULL; + + /* Check whether we already have a regular key. */ + is_regular = (key && gpg_err_code (is_shadowed_key (key)) != GPG_ERR_TRUE); /* Turn (BUFFER,LENGTH) into a gcrypt s-expression and set it into * our name value container. */ + gcry_sexp_release (key); err = gcry_sexp_sscan (&key, NULL, buffer, length); if (err) goto leave; @@ -237,6 +171,23 @@ agent_write_private_key (const unsigned char *grip, if (err) goto leave; + /* Check that we do not update a regular key with a shadow key. */ + if (is_regular && gpg_err_code (is_shadowed_key (key)) == GPG_ERR_TRUE) + { + log_info ("updating regular key file '%s'" + " by a shadow key inhibited\n", fname); + err = 0; /* Simply ignore the error. */ + goto leave; + } + + /* Check that we update a regular key only in force mode. */ + if (is_regular && !force) + { + log_error ("secret key file '%s' already exists\n", fname); + err = gpg_error (GPG_ERR_EEXIST); + goto leave; + } + /* If requested write a Token line. */ if (serialno && keyref) { @@ -357,8 +308,8 @@ agent_write_private_key (const unsigned char *grip, if (blocksigs) gnupg_unblock_all_signals (); es_fclose (fp); - if (removetmp && fname) - gnupg_remove (fname); + if (removetmp && tmpfname) + gnupg_remove (tmpfname); xfree (fname); xfree (tmpfname); xfree (token); @@ -903,7 +854,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, /* Read the key identified by GRIP from the private key directory and * return it as an gcrypt S-expression object in RESULT. If R_KEYMETA - * is not NULl and the extended key format is used, the meta data + * is not NULL and the extended key format is used, the meta data * items are stored there. However the "Key:" item is removed from * it. On failure returns an error code and stores NULL at RESULT and * R_KEYMETA. */ @@ -1447,6 +1398,29 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, } +/* This function returns GPG_ERR_TRUE if S_SKEY represents a shadowed + * key. 0 is return for other key types. Any other error may occur + * if S_SKEY is not valid. */ +static gpg_error_t +is_shadowed_key (gcry_sexp_t s_skey) +{ + gpg_error_t err; + unsigned char *buf; + size_t buflen; + + err = make_canon_sexp (s_skey, &buf, &buflen); + if (err) + return err; + + if (agent_private_key_type (buf) == PRIVATE_KEY_SHADOWED) + err = gpg_error (GPG_ERR_TRUE); + + wipememory (buf, buflen); + xfree (buf); + return err; +} + + /* Return the key for the keygrip GRIP. The result is stored at RESULT. This function extracts the key from the private key database and returns it as an S-expression object as it is. On From f953d67446faaa5a4e3343900d933d8b0351d8f7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 May 2023 15:53:52 +0200 Subject: [PATCH 039/869] Prepare the NEWS for the next release -- --- NEWS | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/NEWS b/NEWS index af2064199..d58b0f3c1 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,28 @@ Noteworthy changes in version 2.4.2 (unreleased) ------------------------------------------------ + * gpg: Print a warning if no more encryption subkeys are left over + after chnaging the expiration date. [rGef2c3d50fa] + + * gpg: Fix searching for the ADSK key when adding an ADSK. [T6504] + + * gpgsm: Speed up key listings on Windows. [rG08ff55bd44] + + * gpgsm: Reduce the number of "failed to open policy file" + diagnostics. [rG68613a6a9d] + + * agent: Make updating of private key files more robust and track + display S/N. [T6135] + + * keyboxd: Avoid longish delays on Windows when listing keys. + [rG6944aefa3c] + + * gpgtar: Emit extra status lines to help GPGME. [T6497] + + * w32: Avoid using the VirtualStore. [T6403] + + Release-info: https://dev.gnupg.org/T6506 + Noteworthy changes in version 2.4.1 (2023-04-28) ------------------------------------------------ From 4cfa2efdc6f8b1bd1056cf4d2a25f51ff79a2249 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 30 May 2023 13:47:39 +0200 Subject: [PATCH 040/869] po: Translated one new string to German. -- --- po/de.po | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/po/de.po b/po/de.po index 64e444d01..bf4bda4a0 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.4.1\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-03-21 09:31+0100\n" +"PO-Revision-Date: 2023-05-30 13:46+0200\n" "Last-Translator: Werner Koch \n" "Language-Team: German\n" "Language: de\n" @@ -745,10 +745,6 @@ msgstr "Korrekt" msgid "Wrong" msgstr "Falsch" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "Fehler beim Umbenennen von `%s` nach `%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3834,6 +3830,10 @@ msgstr "WARNUNG: Ihr Unterschlüssel zum Verschlüsseln wird bald verfallen.\n" msgid "You may want to change its expiration date too.\n" msgstr "Bitte erwägen Sie, dessen Verfallsdatum auch zu ändern.\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "WARNUNG: Es sind keine Unterschlüssel zum Verschlüsseln mehr vorhanden.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7934,6 +7934,10 @@ msgstr "" "Die temporäre Zwischenspeicherverzeichnisdatei `%s' konnte nicht erzeugt " "werden: %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "Fehler beim Umbenennen von `%s` nach `%s': %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "Hashwert von `%s' kann nicht gebildet werden: %s\n" From 550bc15b006d6f2a6e7305a3e58be1dd6ed2295e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 30 May 2023 13:49:57 +0200 Subject: [PATCH 041/869] po: msgmerge done -- --- po/ca.po | 14 ++++++--- po/cs.po | 13 +++++--- po/da.po | 14 ++++++--- po/el.po | 14 ++++++--- po/eo.po | 14 ++++++--- po/es.po | 13 +++++--- po/et.po | 14 ++++++--- po/fi.po | 14 ++++++--- po/fr.po | 13 +++++--- po/gl.po | 14 ++++++--- po/hu.po | 14 ++++++--- po/id.po | 14 ++++++--- po/it.po | 13 +++++--- po/ja.po | 16 +++++----- po/nb.po | 13 +++++--- po/pl.po | 13 +++++--- po/pt.po | 14 ++++++--- po/ro.po | 14 ++++++--- po/ru.po | 13 +++++--- po/sk.po | 14 ++++++--- po/sv.po | 14 ++++++--- po/tr.po | 90 ++++++++++++++++++++++++----------------------------- po/uk.po | 13 +++++--- po/zh_CN.po | 13 +++++--- po/zh_TW.po | 13 +++++--- 25 files changed, 256 insertions(+), 162 deletions(-) diff --git a/po/ca.po b/po/ca.po index 3add69bb1..d6840dbc1 100644 --- a/po/ca.po +++ b/po/ca.po @@ -784,11 +784,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "error en la lectura de «%s»: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -4116,6 +4111,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "No podeu canviar la data de caducitat de les claus v3\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + # Photo ID com abans. ivb msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " @@ -8289,6 +8288,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "no es pot crear el directori «%s»: %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "error en la lectura de «%s»: %s\n" + # No em passe! ;) ivb #, fuzzy, c-format msgid "can't hash '%s': %s\n" diff --git a/po/cs.po b/po/cs.po index d72bd673f..c790c768b 100644 --- a/po/cs.po +++ b/po/cs.po @@ -761,10 +761,6 @@ msgstr "V pořádku" msgid "Wrong" msgstr "Špatně" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "chyba při přejmenování „%s“ na „%s“: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "Poznámka: Toto heslo nikdy nebylo změněno.%0AProsím, nyní jej změňte." @@ -3809,6 +3805,11 @@ msgstr "POZOR: Vašemu šifrovacímu podklíči brzy vyprší platnost.\n" msgid "You may want to change its expiration date too.\n" msgstr "Dobu platnosti také můžete změnit.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "POZOR: Vašemu šifrovacímu podklíči brzy vyprší platnost.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7831,6 +7832,10 @@ msgstr "prosím, zjistěte příčinu a soubor ručně smažte\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "vytvoření dočasného kešového dir souboru „%s“ selhalo: %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "chyba při přejmenování „%s“ na „%s“: %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "nelze vypočítat haš „%s“: %s\n" diff --git a/po/da.po b/po/da.po index 404d79eb4..011ea7d0d 100644 --- a/po/da.po +++ b/po/da.po @@ -835,11 +835,6 @@ msgstr "Korrekt" msgid "Wrong" msgstr "Forkert" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "fejl ved læsning af »%s«: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "Bemærk: Denne adgangsfrase er aldrig blevet ændret.%0AÆndr den nu." @@ -4129,6 +4124,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Du kan ikke ændre udløbsdatoen for en v3-nøgle\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8372,6 +8371,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "kunne ikke oprette midlertidig fil »%s«: %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "fejl ved læsning af »%s«: %s\n" + #, fuzzy, c-format #| msgid "can't access `%s': %s\n" msgid "can't hash '%s': %s\n" diff --git a/po/el.po b/po/el.po index a45232fd8..7d4e8e738 100644 --- a/po/el.po +++ b/po/el.po @@ -751,11 +751,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "σφάλμα κατά την ανάγνωση του `%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -4013,6 +4008,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Δεν μπορείτε να αλλάξετε την ημερομηνία λήξης σε ένα v3 κλειδί\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8127,6 +8126,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "αδυναμία δημιουργίας καταλόγου `%s': %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "σφάλμα κατά την ανάγνωση του `%s': %s\n" + #, fuzzy, c-format msgid "can't hash '%s': %s\n" msgstr "αδυναμία κλεισίματος του `%s': %s\n" diff --git a/po/eo.po b/po/eo.po index e9b007c41..a142ce1aa 100644 --- a/po/eo.po +++ b/po/eo.po @@ -750,11 +750,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "eraro dum legado de '%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3986,6 +3981,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Vi ne povas ŝanĝi la daton de eksvalidiĝo de v3-ŝlosilo\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8038,6 +8037,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "%s: ne povas krei dosierujon: %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "eraro dum legado de '%s': %s\n" + #, fuzzy, c-format msgid "can't hash '%s': %s\n" msgstr "ne povas fermi '%s': %s\n" diff --git a/po/es.po b/po/es.po index 03e50d3ca..4409ce443 100644 --- a/po/es.po +++ b/po/es.po @@ -788,10 +788,6 @@ msgstr "Correcto" msgid "Wrong" msgstr "Incorrecto" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "error al renombrar '%s' a '%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3886,6 +3882,11 @@ msgstr "AVISO: Tu subclave de cifrado caduca pronto.\n" msgid "You may want to change its expiration date too.\n" msgstr "Puede que también quieras cambiar su fecha de caducidad.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "AVISO: Tu subclave de cifrado caduca pronto.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7954,6 +7955,10 @@ msgstr "chequea el problema y borra este archivo manualmente\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "no se puede crear el fichero de cache '%s': %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "error al renombrar '%s' a '%s': %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "no se puede hacer el hash de '%s': %s\n" diff --git a/po/et.po b/po/et.po index 6c6f7bfbb..5e106d6f5 100644 --- a/po/et.po +++ b/po/et.po @@ -748,11 +748,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "viga `%s' lugemisel: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3985,6 +3980,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "v3 võtme aegumise aega ei saa muuta.\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8044,6 +8043,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "kataloogi `%s' ei õnnestu luua: %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "viga `%s' lugemisel: %s\n" + #, fuzzy, c-format msgid "can't hash '%s': %s\n" msgstr "`%s' ei õnnestu sulgeda: %s\n" diff --git a/po/fi.po b/po/fi.po index 15fd0471a..3af8e811e 100644 --- a/po/fi.po +++ b/po/fi.po @@ -765,11 +765,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "virhe luettaessa tiedostoa \"%s\": %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -4009,6 +4004,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Et voi muuttaa v3-avainten vanhentumispäivää\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8110,6 +8109,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "hakemiston \"%s\" luominen ei onnistu: %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "virhe luettaessa tiedostoa \"%s\": %s\n" + #, fuzzy, c-format msgid "can't hash '%s': %s\n" msgstr "tiedostoa \"%s\" ei voi sulkea: %s\n" diff --git a/po/fr.po b/po/fr.po index 239307ec4..6530e7768 100644 --- a/po/fr.po +++ b/po/fr.po @@ -789,10 +789,6 @@ msgstr "Exact" msgid "Wrong" msgstr "Faux" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "erreur en renommant « %s » en « %s » : %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -4015,6 +4011,11 @@ msgstr "Attention : votre sous-clef de chiffrement expire bientôt.\n" msgid "You may want to change its expiration date too.\n" msgstr "Vous pourriez modifier aussi sa date d’expiration.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "Attention : votre sous-clef de chiffrement expire bientôt.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8258,6 +8259,10 @@ msgstr "veuillez vérifier la raison et effacer vous-même ce fichier\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "impossible de créer le répertoire de cache temporaire « %s » : %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "erreur en renommant « %s » en « %s » : %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "impossible de hacher « %s » : %s\n" diff --git a/po/gl.po b/po/gl.po index af75e558c..d6972580a 100644 --- a/po/gl.po +++ b/po/gl.po @@ -753,11 +753,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "erro lendo `%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -4009,6 +4004,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Non pode cambia-la data de expiración dunha chave v3\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8118,6 +8117,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "non se pode crea-lo directorio `%s': %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "erro lendo `%s': %s\n" + #, fuzzy, c-format msgid "can't hash '%s': %s\n" msgstr "non se pode pechar `%s': %s\n" diff --git a/po/hu.po b/po/hu.po index b506d8a68..e875d074b 100644 --- a/po/hu.po +++ b/po/hu.po @@ -748,11 +748,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "Hiba \"%s\" olvasásakor: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3986,6 +3981,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Nem változtathatja meg egy v3 kulcs lejárati dátumát!\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8071,6 +8070,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "Nem tudom a \"%s\" könyvtárat létrehozni: %s.\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "Hiba \"%s\" olvasásakor: %s\n" + #, fuzzy, c-format msgid "can't hash '%s': %s\n" msgstr "Nem tudom bezárni a(z) \"%s\" állományt: %s.\n" diff --git a/po/id.po b/po/id.po index 5334da392..363bad315 100644 --- a/po/id.po +++ b/po/id.po @@ -753,11 +753,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "kesalahan membaca `%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3992,6 +3987,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Anda tidak dapat merubah batas waktu kunci v3\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8070,6 +8069,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "tidak dapat membuat direktori `%s': %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "kesalahan membaca `%s': %s\n" + #, fuzzy, c-format msgid "can't hash '%s': %s\n" msgstr "tidak dapat menutup `%s': %s\n" diff --git a/po/it.po b/po/it.po index 85f9b817c..8f04c7afa 100644 --- a/po/it.po +++ b/po/it.po @@ -737,10 +737,6 @@ msgstr "Corretto" msgid "Wrong" msgstr "Sbagliato" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "errore durante la ridenominazione di '%s' in '%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3826,6 +3822,11 @@ msgstr "AVVISO: la sottochiave di crittografia scade a breve.\n" msgid "You may want to change its expiration date too.\n" msgstr "Si consiglia di modificare anche la sua data di scadenza.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "AVVISO: la sottochiave di crittografia scade a breve.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7883,6 +7884,10 @@ msgstr "si prega di controllare il motivo ed eliminare manualmente quel file\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "impossibile creare il file dir della cache temporanea '%s': %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "errore durante la ridenominazione di '%s' in '%s': %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "impossibile eseguire l'hashing '%s': %s\n" diff --git a/po/ja.po b/po/ja.po index 236d78ced..d9a1dcd71 100644 --- a/po/ja.po +++ b/po/ja.po @@ -226,8 +226,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"パスフレーズを入力してください。gpg-agentの鍵の保管で受信した秘密鍵%%0A " -"%s%%0A %s%%0Aを保護します。" +"パスフレーズを入力してください。gpg-agentの鍵の保管で受信した秘密鍵%%0A %s" +"%%0A %s%%0Aを保護します。" #, c-format msgid "failed to create stream from socket: %s\n" @@ -727,10 +727,6 @@ msgstr "正しい" msgid "Wrong" msgstr "誤り" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "'%s'から'%s'へ名前変更のエラー: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "注意: パスフレーズは変更されていません。%0A今、変更してください。" @@ -759,8 +755,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A " -"%%C%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" +"%%0A?" msgstr "本当にこの鍵: keygrip%%0A %s%%0A %%C%%0Aを削除しますか?" msgid "Delete key" @@ -7588,6 +7584,10 @@ msgstr "理由を確認し、手動でそのファイルを削除してくださ msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "一時キャッシュ・ディレクトリ・ファイル'%s'が作成できません: %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "'%s'から'%s'へ名前変更のエラー: %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "'%s'をハッシュできません: %s\n" diff --git a/po/nb.po b/po/nb.po index 19c2a4d19..922cb4957 100644 --- a/po/nb.po +++ b/po/nb.po @@ -749,10 +749,6 @@ msgstr "Riktig" msgid "Wrong" msgstr "Feil" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "klarte ikke å gi «%s» det nye navnet «%s»: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3849,6 +3845,11 @@ msgstr "ADVARSEL: Undernøkkel for kryptering utløper snart.\n" msgid "You may want to change its expiration date too.\n" msgstr "Du bør vurdere å endre utløpsdato samtidig.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "ADVARSEL: Undernøkkel for kryptering utløper snart.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7873,6 +7874,10 @@ msgstr "kontroller årsaken og slett fila manuelt\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "klarte ikke å lage midlertidig hurtiglagermappe-fil «%s»: %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "klarte ikke å gi «%s» det nye navnet «%s»: %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "klarte ikke å summere «%s»: %s\n" diff --git a/po/pl.po b/po/pl.po index dd97fdbdc..555da9661 100644 --- a/po/pl.po +++ b/po/pl.po @@ -744,10 +744,6 @@ msgstr "Akceptuj" msgid "Wrong" msgstr "Odrzuć" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "błąd zmiany nazwy ,,%s'' na ,,%s'': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "Uwaga: To hasło nie było nigdy zmieniane.%0AProszę zmienić je teraz." @@ -3862,6 +3858,11 @@ msgstr "OSTRZEŻENIE: podklucz do szyfrowania wkrótce wygaśnie.\n" msgid "You may want to change its expiration date too.\n" msgstr "Może warto także zmienić jego datę ważności.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "OSTRZEŻENIE: podklucz do szyfrowania wkrótce wygaśnie.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7982,6 +7983,10 @@ msgstr "" "nie udało się utworzyć pliku tymczasowego katalogu pamięci podręcznej ,," "%s'': %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "błąd zmiany nazwy ,,%s'' na ,,%s'': %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "nie można policzyć skrótu ,,%s'': %s\n" diff --git a/po/pt.po b/po/pt.po index d20eb0138..e7ba4118c 100644 --- a/po/pt.po +++ b/po/pt.po @@ -752,11 +752,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3996,6 +3991,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Você não pode modificar a data de validade de uma chave v3\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8067,6 +8066,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "%s: impossível criar directoria: %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "erro na leitura de `%s': %s\n" + #, fuzzy, c-format msgid "can't hash '%s': %s\n" msgstr "impossível fechar `%s': %s\n" diff --git a/po/ro.po b/po/ro.po index e60784d33..b32a1dcd5 100644 --- a/po/ro.po +++ b/po/ro.po @@ -762,11 +762,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "eroare la citire `%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -4044,6 +4039,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Nu puteţi schimba data de expirare a unei chei v3\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8193,6 +8192,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "nu pot crea directorul `%s': %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "eroare la citire `%s': %s\n" + #, fuzzy, c-format #| msgid "can't access `%s': %s\n" msgid "can't hash '%s': %s\n" diff --git a/po/ru.po b/po/ru.po index 80e4e7aa6..a144acd53 100644 --- a/po/ru.po +++ b/po/ru.po @@ -754,10 +754,6 @@ msgstr "Подтверждаю" msgid "Wrong" msgstr "Неверно" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "ошибка переименования '%s' в '%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3866,6 +3862,11 @@ msgstr "Внимание: Срок действия Вашего подключ msgid "You may want to change its expiration date too.\n" msgstr "Возможно, надо поменять также срок действия.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "Внимание: Срок действия Вашего подключа для шифрования истекает.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7942,6 +7943,10 @@ msgstr "выясните причину и удалите этот файл вр msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "невозможно создание временного файла '%s': %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "ошибка переименования '%s' в '%s': %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "невозможно получить хеш '%s': %s\n" diff --git a/po/sk.po b/po/sk.po index 50e9070b8..743ce6b0a 100644 --- a/po/sk.po +++ b/po/sk.po @@ -753,11 +753,6 @@ msgstr "" msgid "Wrong" msgstr "" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "chyba pri čítaní `%s': %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -4012,6 +4007,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Nemôžete zmeniť dobu platnosti kľúča verzie 3\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8101,6 +8100,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "nemôžem vytvoriť adresár `%s': %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "chyba pri čítaní `%s': %s\n" + #, fuzzy, c-format msgid "can't hash '%s': %s\n" msgstr "nemôžem zavrieť `%s': %s\n" diff --git a/po/sv.po b/po/sv.po index c8405d50c..2a62fe1d7 100644 --- a/po/sv.po +++ b/po/sv.po @@ -851,11 +851,6 @@ msgstr "Korrekt" msgid "Wrong" msgstr "Fel" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" -msgid "error renaming '%s' to '%s': %s\n" -msgstr "fel vid läsning av \"%s\": %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -4194,6 +4189,10 @@ msgstr "" msgid "You may want to change its expiration date too.\n" msgstr "Du kan inte ändra giltighetsdatum för en v3-nyckel\n" +#, c-format +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8506,6 +8505,11 @@ msgstr "" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "misslyckades med att skapa temporärfilen \"%s\": %s\n" +#, fuzzy, c-format +#| msgid "error reading `%s': %s\n" +msgid "error renaming '%s' to '%s': %s\n" +msgstr "fel vid läsning av \"%s\": %s\n" + #, fuzzy, c-format #| msgid "can't access `%s': %s\n" msgid "can't hash '%s': %s\n" diff --git a/po/tr.po b/po/tr.po index 3f15ce679..b7730c7ae 100644 --- a/po/tr.po +++ b/po/tr.po @@ -1,12 +1,12 @@ # Turkish translations for GnuPG messages. # Nilgün Belma Bugüner , 2001-2008, -# Emir SARI , 2022 +# Emir SARI , 2022, 2023 # msgid "" msgstr "" -"Project-Id-Version: gnupg 2.3.4\n" +"Project-Id-Version: gnupg 2.4.0\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2022-04-23 15:00+0300\n" +"PO-Revision-Date: 2023-02-05 18:00+0300\n" "Last-Translator: Emir SARI \n" "Language-Team: Turkish\n" "Language: tr\n" @@ -14,7 +14,6 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: KBabel 1.11.4\n" #, c-format msgid "failed to acquire the pinentry lock: %s\n" @@ -325,7 +324,7 @@ msgstr "Yine de bunu kullan" #, c-format msgid "Please enter the passphrase to%0Aprotect your new key" -msgstr "Yeni anahtarınızı korumak için lütfen%0Aanahtar parolanızı girin" +msgstr "Yeni anahtarınızı korumak için lütfen anahtar%0Aparolanızı girin" msgid "Please enter the new passphrase" msgstr "Lütfen yeni anahtar parolasını girin" @@ -393,10 +392,8 @@ msgstr "|ALGO|ssh parmak izlerini göstermek için ALGO kullan" msgid "enable putty support" msgstr "putty desteğini etkinleştir" -#, fuzzy -#| msgid "enable putty support" msgid "enable Win32-OpenSSH support" -msgstr "putty desteğini etkinleştir" +msgstr "Win32-OpenSSH desteğini etkinleştir" msgid "Options controlling the security" msgstr "Güvenliği denetleyen seçenekler" @@ -736,10 +733,6 @@ msgstr "Doğru" msgid "Wrong" msgstr "Yanlış" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "'%s > '%s' olarak yeniden adlandırırken hata: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -763,22 +756,19 @@ msgid "Please insert the card with serial number" msgstr "Lütfen seri numarayı içeren kartı takın" # Check -#, fuzzy, c-format -#| msgid "" -#| "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want " -#| "to allow this?" +#, c-format msgid "Requested the use of key%%0A %s%%0A %s%%0ADo you want to allow this?" msgstr "" -"Bir ssh işlemi,%%0A %s%%A (%s)%%0Aanahtarının kullanımı için istekte " -"bulundu. Buna izin vermek istiyor musunuz?" +"%%0A %s%%0A %s%%0Aanahtarının kullanımı için istekte bulunuldu. Buna izin " +"vermek istiyor musunuz?" #, c-format msgid "" "Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" "%%0A?" msgstr "" -"Anahtar maşası tarafından tanımlanan şu anahtarı silmek istediğnizden emin " -"misiniz:%%0A %s%%0A %%C%%0A?" +"%%0A %s%%0A %%C%%0A anahtar maşası tarafından tanımlanan anahtarı silmek " +"istediğnizden emin misiniz?" msgid "Delete key" msgstr "Anahtarı sil" @@ -1516,7 +1506,7 @@ msgstr "%u bite yuvarlandı\n" #, c-format msgid "%s keysizes must be in the range %u-%u\n" -msgstr "%s anahtar uzunlukları %u-%u eriminde olmalı\n" +msgstr "%s anahtar uzunlukları %u-%u eriminde olmalıdır\n" msgid "Changing card key attribute for: " msgstr "Şunun için anahtar özniteliği değiştiriliyor: " @@ -1531,7 +1521,7 @@ msgid "Authentication key\n" msgstr "Kimlik doğrulama anahtarı\n" msgid "Please select what kind of key you want:\n" -msgstr "Lütfen istediğiniz anahtar türünü seçiniz:\n" +msgstr "Lütfen istediğiniz anahtar türünü seçin:\n" #, c-format msgid " (%d) RSA\n" @@ -1574,7 +1564,7 @@ msgid "Note: keys are already stored on the card!\n" msgstr "Not: Anahtarlar halihazırda kart üzerinde depolanıyor!\n" msgid "Replace existing keys? (y/N) " -msgstr "Mevcut anahtarlar başkalarıyla değiştirilsin mi? (e/H) " +msgstr "Var olan anahtarlar başkalarıyla değiştirilsin mi? (e/H) " #, c-format msgid "" @@ -1587,7 +1577,7 @@ msgstr "" "Bunları --change-pin komutunu kullanarak değiştirmelisiniz\n" msgid "Please select the type of key to generate:\n" -msgstr "Lütfen üretilecek anahtar türünü seçiniz:\n" +msgstr "Lütfen üretilecek anahtar türünü seçin:\n" msgid " (1) Signature key\n" msgstr " (1) İmzalama anahtarı\n" @@ -1599,7 +1589,7 @@ msgid " (3) Authentication key\n" msgstr " (3) Kimlik doğrulama anahtarı\n" msgid "Please select where to store the key:\n" -msgstr "Lütfen anahtarın depolanacağı yeri seçiniz:\n" +msgstr "Lütfen anahtarın depolanacağı yeri seçin:\n" #, c-format msgid "KEYTOCARD failed: %s\n" @@ -1803,10 +1793,9 @@ msgstr "UYARI: %s anahtarı, %s kipinde şifreleme için uygun değil\n" msgid "error creating passphrase: %s\n" msgstr "anahtar parolası oluşturulurken hata: %s\n" -#, fuzzy, c-format -#| msgid "can't use a symmetric ESK packet due to the S2K mode\n" +#, c-format msgid "can't use a SKESK packet due to the S2K mode\n" -msgstr "S2K kipi sayesinde bir simetrik ESK paketi kullanılamıyor\n" +msgstr "S2K kipi nedeniyle bir SKESK paketi kullanılamıyor\n" #, c-format msgid "using cipher %s.%s\n" @@ -1877,18 +1866,14 @@ msgstr "dışa aktarım sırasında anahtardan kullanışsız parçaları kaldı msgid "remove as much as possible from key during export" msgstr "dışa aktarım sırasında anahtardan olabildiğince çok şey kaldır" -#, fuzzy -#| msgid "generate a revocation certificate" msgid "export only revocation certificates" -msgstr "bir yürürlükten kaldırma sertifikası üret" +msgstr "yalnızca yürürlükten kaldırma sertifikalarını dışa aktar" msgid "use the GnuPG key backup format" msgstr "GnuPG yedekleme biçimini kullan" -#, fuzzy -#| msgid "exporting secret keys not allowed\n" msgid "export secret keys using the GnuPG format" -msgstr "gizli anahtarların dışa aktarımına izin verilmez\n" +msgstr "GnuPG biçimini kullanan gizli anahtarları dışa aktar" msgid " - skipped" msgstr " - atlandı" @@ -2330,10 +2315,8 @@ msgstr "anahtar zinciri adını anahtar listelerinde göster" msgid "show expiration dates during signature listings" msgstr "imza listelemesi sırasında zaman aşımı tarihleri göster" -#, fuzzy -#| msgid "list preferences (expert)" msgid "show preferences" -msgstr "tercihleri listele (uzman)" +msgstr "tercihleri göster" #, c-format msgid "unknown TOFU policy '%s'\n" @@ -2503,23 +2486,23 @@ msgstr "seçili sertifikalama özet algoritması geçersiz\n" #, c-format msgid "completes-needed must be greater than 0\n" -msgstr "\"completes-needed\" 0'dan büyük olmalı\n" +msgstr "\"completes-needed\" 0'dan büyük olmalıdır\n" #, c-format msgid "marginals-needed must be greater than 1\n" -msgstr "\"marginals-needed\" 1'den büyük olmalı\n" +msgstr "\"marginals-needed\" 1'den büyük olmalıdır\n" #, c-format msgid "max-cert-depth must be in the range from 1 to 255\n" -msgstr "\"max-cert-depth\" 1-255 arasında olmalı\n" +msgstr "\"max-cert-depth\" 1-255 arasında olmalıdır\n" #, c-format msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n" -msgstr "öntanımlı sertifika düzeyi geçersiz; 0, 1, 2 veya 3 olmalı\n" +msgstr "öntanımlı sertifika düzeyi geçersiz; 0, 1, 2 veya 3 olmalıdır\n" #, c-format msgid "invalid min-cert-level; must be 1, 2, or 3\n" -msgstr "asgari sertifika düzeyi geçersiz; 1, 2 veya 3 olmalı\n" +msgstr "en küçük sertifika düzeyi geçersiz; 1, 2 veya 3 olmalıdır\n" #, c-format msgid "Note: simple S2K mode (0) is strongly discouraged\n" @@ -2527,7 +2510,7 @@ msgstr "Not: Basit S2K kipi (0) kesinlikle tavsiye edilmez\n" #, c-format msgid "invalid S2K mode; must be 0, 1 or 3\n" -msgstr "geçersiz S2K kipi; 0, 1 veya 3 olmalı\n" +msgstr "geçersiz S2K kipi; 0, 1 veya 3 olmalıdır\n" #, c-format msgid "invalid default preferences\n" @@ -3800,6 +3783,11 @@ msgstr "UYARI: Şifreleme yardımcı anahtarının yakın zamanda süresi dolaca msgid "You may want to change its expiration date too.\n" msgstr "Son kullanma tarihini de değiştirmek isteyebilirsiniz.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "UYARI: Şifreleme yardımcı anahtarının yakın zamanda süresi dolacak.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -4249,7 +4237,7 @@ msgstr "%u bite yuvarlandı\n" #, c-format msgid "%s keys may be between %u and %u bits long.\n" -msgstr "%s anahtarları %u bit ile %u bit arasında olmalı.\n" +msgstr "%s anahtarları %u bit ile %u bit arasında olmalıdır.\n" #, c-format msgid "What keysize do you want for the subkey? (%u) " @@ -4303,10 +4291,10 @@ msgid "invalid value\n" msgstr "geçersiz değer\n" msgid "Key does not expire at all\n" -msgstr "Anahtar hep geçerli olacak\n" +msgstr "Anahtarın geçerliliği hiçbir zaman bitmeyecek\n" msgid "Signature does not expire at all\n" -msgstr "İmza hep geçerli olacak\n" +msgstr "İmzanın geçerliliği hiçbir zaman bitmeyecek\n" #, c-format msgid "Key expires at %s\n" @@ -5248,7 +5236,7 @@ msgid "" "The minimum trust level for this key is: %s\n" "\n" msgstr "" -"Bu anahtar için asgari güvence düzeyi: %s\n" +"Bu anahtar için en düşük güvence düzeyi: %s\n" "\n" msgid "Your decision? " @@ -6662,7 +6650,7 @@ msgstr "||Lütfen kart kilidini açın" #, c-format msgid "PIN for CHV%d is too short; minimum length is %d\n" -msgstr "CHV%d için PIN çok kısa; asgari uzunluk: %d\n" +msgstr "CHV%d için PIN çok kısa; gereken en kısa uzunluk %d\n" #, c-format msgid "verify CHV%d failed: %s\n" @@ -6693,7 +6681,7 @@ msgstr "||Lütfen kart için Sıfırlama Kodunu giriniz" #, c-format msgid "Reset Code is too short; minimum length is %d\n" -msgstr "Sıfırlama Kodu çok kısa; asgari uzunluk: %d\n" +msgstr "Sıfırlama Kodu çok kısa; gereken en kısa uzunluk %d\n" #. TRANSLATORS: Do not translate the "|*|" prefixes but #. keep it at the start of the string. We need this elsewhere @@ -7782,6 +7770,10 @@ msgstr "lütfen nedenini denetleyin ve o dosyayı el ile silin\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "geçici önbellek dizin dosyası '%s' oluşturulamadı: %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "'%s > '%s' olarak yeniden adlandırırken hata: %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "'%s' sağlaması yapılamıyor: %s\n" diff --git a/po/uk.po b/po/uk.po index d81fd7d64..730e9e135 100644 --- a/po/uk.po +++ b/po/uk.po @@ -754,10 +754,6 @@ msgstr "Підтверджую" msgid "Wrong" msgstr "Не підтверджую" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "помилка під час спроби перейменування «%s» на «%s»: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3905,6 +3901,11 @@ msgstr "УВАГА: строк дії вашого підключа імпорт msgid "You may want to change its expiration date too.\n" msgstr "Ймовірно, вам варто змінити також і його строк дії.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "УВАГА: строк дії вашого підключа імпортування невдовзі завершиться.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -8052,6 +8053,10 @@ msgstr "будь ласка, перевірте причину і вилучіт msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "не вдалося створити тимчасовий файл каталогу кешу «%s»: %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "помилка під час спроби перейменування «%s» на «%s»: %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "не вдалося хешувати «%s»: %s\n" diff --git a/po/zh_CN.po b/po/zh_CN.po index 1b6a221d9..ef737a37d 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -717,10 +717,6 @@ msgstr "正确" msgid "Wrong" msgstr "错误" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "将‘%s’重命名为‘%s’时出现错误:%s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "注意:此密码从未被修改过。%0A请立即修改。" @@ -3692,6 +3688,11 @@ msgstr "警告: 您的加密用子密钥将在不久后过期。\n" msgid "You may want to change its expiration date too.\n" msgstr "您可能也想要变更它的过期日期。\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "警告: 您的加密用子密钥将在不久后过期。\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7528,6 +7529,10 @@ msgstr "请检查理由并手动删除那个文件\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "创建临时缓存目录文件‘%s’时失败:%s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "将‘%s’重命名为‘%s’时出现错误:%s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "无法取‘%s’的散列:%s\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index 066dd0521..f14cce879 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -753,10 +753,6 @@ msgstr "正確" msgid "Wrong" msgstr "錯了" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "把 '%s' 重新命名成 '%s' 時出錯: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "請注意: 密語從未變更過.%0A請現在就變更." @@ -3882,6 +3878,11 @@ msgstr "警告: 你的加密子鑰很快將到期.\n" msgid "You may want to change its expiration date too.\n" msgstr "你可能也會想變更其使用期限.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "警告: 你的加密子鑰很快將到期.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7871,6 +7872,10 @@ msgstr "請檢查其原因並手動刪除該檔案\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "建立暫存快取目錄檔案 '%s' 失敗: %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "把 '%s' 重新命名成 '%s' 時出錯: %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "無法計算 '%s' 的雜湊: %s\n" From 9e86dac84f3704cb12fddc559b8604f5fe202f06 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 30 May 2023 13:53:01 +0200 Subject: [PATCH 042/869] Release 2.4.2 --- NEWS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index d58b0f3c1..08fb5bd9a 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,8 @@ -Noteworthy changes in version 2.4.2 (unreleased) +Noteworthy changes in version 2.4.2 (2023-05-30) ------------------------------------------------ * gpg: Print a warning if no more encryption subkeys are left over - after chnaging the expiration date. [rGef2c3d50fa] + after changing the expiration date. [rGef2c3d50fa] * gpg: Fix searching for the ADSK key when adding an ADSK. [T6504] @@ -21,6 +21,7 @@ Noteworthy changes in version 2.4.2 (unreleased) * w32: Avoid using the VirtualStore. [T6403] + See-also: gnupg-announce/2023q2/000479.html Release-info: https://dev.gnupg.org/T6506 From 3c97dc2714b613ed5340f2dfebd718ca141c84c7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 30 May 2023 16:44:00 +0200 Subject: [PATCH 043/869] Post release updates -- --- NEWS | 6 ++++++ configure.ac | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 08fb5bd9a..14c2251bf 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +Noteworthy changes in version 2.4.3 (unreleased) +------------------------------------------------ + + Release-info: https://dev.gnupg.org/T6506 + + Noteworthy changes in version 2.4.2 (2023-05-30) ------------------------------------------------ diff --git a/configure.ac b/configure.ac index a54740108..e68b779c5 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ min_automake_version="1.16.3" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [4]) -m4_define([mym4_micro], [2]) +m4_define([mym4_micro], [3]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release From c8f6fdcd359ac22466db880b5f13e272dcd65a8b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 30 May 2023 17:38:27 +0200 Subject: [PATCH 044/869] build: Always build the wixlib with a release -- Forgot it today again; better do it by default. Also disable sslsigncode verify due to missing certificate problem (for signing we use Scute). --- Makefile.am | 4 ++-- build-aux/speedo.mk | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 0f2075089..1cd009811 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,8 +18,8 @@ ## Process this file with automake to produce Makefile.in -# To include the wixlibs for building an MSI installer in a release use -# make release WITH_MSI=1 +# We want to also build the wixlib for use by GnuPG Desktop +WITH_MSI=1 # Location of the released tarball archives. This is prefixed by # the variable RELEASE_ARCHIVE in ~/.gnupg-autogen.rc. For example: diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index db78afa50..170c20b79 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -1543,10 +1543,8 @@ sign-installer: if [ -f "$${msifile}" ]; then \ $(call MKSWDB_commands,$${msifile},$${reldate},"wixlib_"); \ fi; \ - echo "speedo: /*" ;\ - echo "speedo: * Verification result" ;\ - echo "speedo: */" ;\ - osslsigncode verify $${exefile} \ + echo "speedo: /* (osslsigncode verify disabled) */" ;\ + echo osslsigncode verify $${exefile} \ ) From 6ed61d98a04f505aa12e132a98b368315642ac68 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 31 May 2023 09:38:17 +0200 Subject: [PATCH 045/869] Add release dates of 2.4 versions to NEWS -- --- NEWS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NEWS b/NEWS index d2f0da2ac..a4d4a5098 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,14 @@ Noteworthy changes in version 2.5.0 (unreleased) ------------------------------------------------ +Release dates of 2.4 versions +----------------------------- + +Version 2.4.2 (2023-05-30) https://dev.gnupg.org/T6506 +Version 2.4.1 (2023-04-28) https://dev.gnupg.org/T6454 +Version 2.4.0 (2022-12-16) https://dev.gnupg.org/T6302 + + Noteworthy changes in version 2.4.1 (2023-04-28) ------------------------------------------------ @@ -1595,6 +1603,7 @@ Noteworthy changes in version 2.3.0 (2021-04-07) Release dates of 2.2 versions ----------------------------- +Version 2.2.41 (2022-12-09) https://dev.gnupg.org/T6280 Version 2.2.40 (2022-10-10) https://dev.gnupg.org/T6181 Version 2.2.39 (2022-09-02) https://dev.gnupg.org/T6175 Version 2.2.38 (2022-09-01) https://dev.gnupg.org/T6159 From 0fba0bbc6215a425ecbaba6c3a051f3aa6125b1d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 1 Jun 2023 09:10:14 +0900 Subject: [PATCH 046/869] w32: Fix use of assuan_sendfd. * kbx/kbx-client-util.c (prepare_data_pipe): Use _get_osfhandle for pipe to be used for sentfd. [HAVE_W32_SYSTEM] (datastream_thread): Add the case of NREAD==0. * tools/gpg-connect-agent.c (do_sendfd): Use es_syshd instead of es_fileno. [HAVE_W32_SYSTEM] (do_open): Use %p for formating HANDLE. -- Signed-off-by: NIIBE Yutaka --- kbx/kbx-client-util.c | 15 +++++++++-- tools/gpg-connect-agent.c | 55 ++++++++++++++++++++++++++++----------- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/kbx/kbx-client-util.c b/kbx/kbx-client-util.c index f9d06fab8..79d512bb3 100644 --- a/kbx/kbx-client-util.c +++ b/kbx/kbx-client-util.c @@ -118,10 +118,14 @@ prepare_data_pipe (kbx_client_data_t kcd) return err; /* That should not happen. */ } - err = assuan_sendfd (kcd->ctx, INT2FD (inpipe[1])); +#ifdef HAVE_W32_SYSTEM + err = assuan_sendfd (kcd->ctx, INT2FD (_get_osfhandle (inpipe[1]))); +#else + err = assuan_sendfd (kcd->ctx, inpipe[1]); +#endif if (err) { - log_error ("sending sending fd %d to keyboxd: %s <%s>\n", + log_error ("sending fd %d to keyboxd: %s <%s>\n", inpipe[1], gpg_strerror (err), gpg_strsource (err)); es_fclose (infp); gnupg_close_pipe (inpipe[1]); @@ -193,6 +197,13 @@ datastream_thread (void *arg) gnupg_sleep (1); continue; } +#ifdef HAVE_W32_SYSTEM + if (nread == 0) + { + gnupg_sleep (1); + continue; + } +#endif if (nread != 4) { err = gpg_error (GPG_ERR_EIO); diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index eb897287c..4dfb57896 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -898,8 +898,10 @@ static void do_sendfd (assuan_context_t ctx, char *line) { estream_t fp; - char *name, *mode, *p; - int rc, fd; + char *name, *p; + int rc; + char mode[32]; + es_syshd_t hd; /* Get file name. */ name = line; @@ -911,17 +913,25 @@ do_sendfd (assuan_context_t ctx, char *line) p++; /* Get mode. */ - mode = p; - if (!*mode) - mode = "r"; + if (!*p) + { + mode[0] = 'r'; + mode[1] = 0; + p = &mode[1]; + } else { - for (p=mode; *p && !spacep (p); p++) - ; - if (*p) - *p++ = 0; + int i; + for (i = 0; *p && !spacep (p); p++) + mode[i++] = *p; + mode[i] = 0; + p = &mode[i]; } +#ifdef HAVE_W32_SYSTEM + strcpy (p, ",sysopen"); +#endif + /* Open and send. */ fp = es_fopen (name, mode); if (!fp) @@ -930,15 +940,30 @@ do_sendfd (assuan_context_t ctx, char *line) name, mode, strerror (errno)); return; } - fd = es_fileno (fp); + es_syshd (fp, &hd); + +#ifdef HAVE_W32_SYSTEM + if (opt.verbose) + log_error ("file '%s' opened in \"%s\" mode, fd=%p\n", + name, mode, hd.u.handle); +#else if (opt.verbose) log_error ("file '%s' opened in \"%s\" mode, fd=%d\n", - name, mode, fd); + name, mode, hd.u.fd); +#endif - rc = assuan_sendfd (ctx, INT2FD (fd) ); +#ifdef HAVE_W32_SYSTEM + rc = assuan_sendfd (ctx, hd.u.handle); if (rc) - log_error ("sending descriptor %d failed: %s\n", fd, gpg_strerror (rc)); + log_error ("sending descriptor %p failed: %s\n", hd.u.handle, + gpg_strerror (rc)); +#else + rc = assuan_sendfd (ctx, hd.u.fd); + if (rc) + log_error ("sending descriptor %d failed: %s\n", hd.u.fd, + gpg_strerror (rc)); +#endif es_fclose (fp); } @@ -1037,8 +1062,8 @@ do_open (char *line) open_fd_table[fd].handle = newhandle; } if (opt.verbose) - log_info ("file '%s' opened in \"%s\" mode, fd=%d (libc=%d)\n", - name, mode, (int)open_fd_table[fd].handle, fd); + log_info ("file '%s' opened in \"%s\" mode, fd=%p (libc=%d)\n", + name, mode, open_fd_table[fd].handle, fd); set_int_var (varname, (int)open_fd_table[fd].handle); #else /* Unix */ if (opt.verbose) From ef4f22b9d98b4021796a607fb98016ef62c4c559 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 1 Jun 2023 11:58:53 +0900 Subject: [PATCH 047/869] gpg: Graceful exit for signature checking with --batch. * g10/mainproc.c (check_sig_and_print): Don't abort computation in the function, but returns an error. (proc_tree): Break the loop, when check_sig_and_print returns an error. -- GnuPG-bug-id: 6512 Signed-off-by: NIIBE Yutaka --- g10/mainproc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/g10/mainproc.c b/g10/mainproc.c index ce0fdaaac..7dea49728 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -2542,8 +2542,6 @@ check_sig_and_print (CTX c, kbnode_t node) release_kbnode( keyblock ); if (rc) g10_errors_seen = 1; - if (opt.batch && rc) - g10_exit (1); } else /* Error checking the signature. (neither Good nor Bad). */ { @@ -2660,7 +2658,8 @@ proc_tree (CTX c, kbnode_t node) } for (n1 = node; (n1 = find_next_kbnode (n1, PKT_SIGNATURE));) - check_sig_and_print (c, n1); + if (check_sig_and_print (c, n1) && opt.batch) + break; } else if (node->pkt->pkttype == PKT_GPG_CONTROL @@ -2679,8 +2678,8 @@ proc_tree (CTX c, kbnode_t node) } for (n1 = node; (n1 = find_next_kbnode (n1, PKT_SIGNATURE));) - check_sig_and_print (c, n1); - + if (check_sig_and_print (c, n1) && opt.batch) + break; } else if (node->pkt->pkttype == PKT_SIGNATURE) { @@ -2807,7 +2806,8 @@ proc_tree (CTX c, kbnode_t node) if (multiple_ok) { for (n1 = node; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE))) - check_sig_and_print (c, n1); + if (check_sig_and_print (c, n1) && opt.batch) + break; } else check_sig_and_print (c, node); From 89da4a32ab77e47fc1d6893993b298f1acaf418e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 1 Jun 2023 12:42:51 +0200 Subject: [PATCH 048/869] doc: Replace remaining "gpg2" by "gpg". -- --- doc/gnupg7.texi | 17 ++++++++--------- doc/gpgsm.texi | 2 +- doc/scdaemon.texi | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/doc/gnupg7.texi b/doc/gnupg7.texi index c48dca96f..a77bf98f9 100644 --- a/doc/gnupg7.texi +++ b/doc/gnupg7.texi @@ -11,19 +11,18 @@ @ifset isman GnuPG is a set of programs for public key encryption and digital signatures. The program most users will want to use is the OpenPGP -command line tool, named @command{gpg2}. @command{gpgv}is a stripped -down version of @command{gpg2} with no encryption functionality, used +command line tool, named @command{gpg}. @command{gpgv}is a stripped +down version of @command{gpg} with no encryption functionality, used only to verify signatures against a trusted keyring. @command{gpgsm} is the X.509/CMS (for S/MIME) counterpart of -@command{gpg2}. @command{gpg-agent} is a passphrase and private key +@command{gpg}. @command{gpg-agent} is a passphrase and private key daemon which may also emulate the @command{ssh-agent}. @mansect see also -@command{gpg}(1), -@command{gpg2}(1), -@command{gpgv}(1), -@command{gpgsm}(1), -@command{gpg-agent}(1), -@command{dirmngr}(8), +@command{gpg}(1), +@command{gpgv}(1), +@command{gpgsm}(1), +@command{gpg-agent}(1), +@command{dirmngr}(8), @command{scdaemon}(1) @include see-also-note.texi @end ifset diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 364345741..11c5c1962 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -1725,7 +1725,7 @@ option @option{--disable-dirmngr}. @mansect see also @ifset isman -@command{gpg2}(1), +@command{gpg}(1), @command{gpg-agent}(1) @end ifset @include see-also-note.texi diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index a1d1cbc08..6f56585e6 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -757,6 +757,6 @@ length up to N bytes. If N is not given a default value is used @ifset isman @command{gpg-agent}(1), @command{gpgsm}(1), -@command{gpg2}(1) +@command{gpg}(1) @end ifset @include see-also-note.texi From 22350d0768d3e605a49e39f4f257585170d8080e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 1 Jun 2023 12:42:51 +0200 Subject: [PATCH 049/869] doc: Replace remaining "gpg2" by "gpg". -- --- doc/gnupg7.texi | 17 ++++++++--------- doc/gpgsm.texi | 2 +- doc/scdaemon.texi | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/doc/gnupg7.texi b/doc/gnupg7.texi index c48dca96f..a77bf98f9 100644 --- a/doc/gnupg7.texi +++ b/doc/gnupg7.texi @@ -11,19 +11,18 @@ @ifset isman GnuPG is a set of programs for public key encryption and digital signatures. The program most users will want to use is the OpenPGP -command line tool, named @command{gpg2}. @command{gpgv}is a stripped -down version of @command{gpg2} with no encryption functionality, used +command line tool, named @command{gpg}. @command{gpgv}is a stripped +down version of @command{gpg} with no encryption functionality, used only to verify signatures against a trusted keyring. @command{gpgsm} is the X.509/CMS (for S/MIME) counterpart of -@command{gpg2}. @command{gpg-agent} is a passphrase and private key +@command{gpg}. @command{gpg-agent} is a passphrase and private key daemon which may also emulate the @command{ssh-agent}. @mansect see also -@command{gpg}(1), -@command{gpg2}(1), -@command{gpgv}(1), -@command{gpgsm}(1), -@command{gpg-agent}(1), -@command{dirmngr}(8), +@command{gpg}(1), +@command{gpgv}(1), +@command{gpgsm}(1), +@command{gpg-agent}(1), +@command{dirmngr}(8), @command{scdaemon}(1) @include see-also-note.texi @end ifset diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 364345741..11c5c1962 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -1725,7 +1725,7 @@ option @option{--disable-dirmngr}. @mansect see also @ifset isman -@command{gpg2}(1), +@command{gpg}(1), @command{gpg-agent}(1) @end ifset @include see-also-note.texi diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index a1d1cbc08..6f56585e6 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -757,6 +757,6 @@ length up to N bytes. If N is not given a default value is used @ifset isman @command{gpg-agent}(1), @command{gpgsm}(1), -@command{gpg2}(1) +@command{gpg}(1) @end ifset @include see-also-note.texi From 2c1d5d5cd35c4896f55d7fe95cbd3a5fa8ec8f46 Mon Sep 17 00:00:00 2001 From: Petr Pisar Date: Mon, 5 Jun 2023 14:38:26 +0200 Subject: [PATCH 050/869] po: Update Czech translation -- --- po/cs.po | 164 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 112 insertions(+), 52 deletions(-) diff --git a/po/cs.po b/po/cs.po index c790c768b..a05a18e84 100644 --- a/po/cs.po +++ b/po/cs.po @@ -4,7 +4,7 @@ # Magda Procházková 2001, # Roman Pavlik 2001, 2002, 2003, 2004, 2005. # Petr Pisar , 2009, 2010, 2011, 2013, 2014, 2015, 2016. -# Petr Pisar , 2017, 2018, 2019, 2020, 2021, 2022. +# Petr Pisar , 2017, 2018, 2019, 2020, 2021, 2022, 2023. # # A "%%0A" is used by Pinentry to insert a line break. The double percent # sign is actually needed because it is also a printf format string. If you @@ -26,6 +26,7 @@ # kvalifikovaný certifikát/podpis # # action → způsob užití (klíče) +# additional decryption subkey → dodatečný dešifrovací klíč # administrator → správce # cache → keš # compliance rules → pravidla normy @@ -38,9 +39,9 @@ # msgid "" msgstr "" -"Project-Id-Version: gnupg2 2.3.8\n" +"Project-Id-Version: gnupg2 2.4.2\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2022-11-13 14:21+01:00\n" +"PO-Revision-Date: 2023-06-03 15:45+02:00\n" "Last-Translator: Petr Pisar \n" "Language-Team: Czech \n" "Language: cs\n" @@ -153,14 +154,13 @@ msgstr "Heslo:" msgid "does not match - try again" msgstr "neshodují se – zkuste to znovu" -#, fuzzy -#| msgid "Passphrase" msgid "Passphrases match." -msgstr "Heslo" +msgstr "Heslo se shoduje." #. TRANSLATORS: The string is appended to an error message in #. the pinentry. The %s is the actual error message, the #. two %d give the current and maximum number of tries. +# TODO: Pluralize #, c-format msgid "SETERROR %s (try %d of %d)" msgstr "SETERROR %s (pokus %d z %d)" @@ -423,7 +423,7 @@ msgid "enable putty support" msgstr "zapnout podporu pro PuTTY" msgid "enable Win32-OpenSSH support" -msgstr "zapnout podporu pro Win32-OpenSSH" +msgstr "zapnout podporu Win32-OpenSSH" msgid "Options controlling the security" msgstr "Volby ovlivňující bezpečnost" @@ -786,8 +786,8 @@ msgstr "Vyžádáno použití klíče%%0A %s%%0A %s%%0APřejete si to povolit? #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Opravdu chcete smazat klíč určený pomocí keygripu%%0A %s%%0A %%C%%0A?" @@ -1431,7 +1431,7 @@ msgstr "vyžadováno" #, c-format msgid "Please try command \"%s\" if the listing does not look correct\n" -msgstr "" +msgstr "Pokud výpis nevypadá v pořádku, zkuste příkaz „%s“\n" msgid "Error: Only plain ASCII is currently allowed.\n" msgstr "Chyba: V současné verzi je povolenou pouze plain ASCII.\n" @@ -1697,7 +1697,7 @@ msgid "change the User Interaction Flag" msgstr "změní příznak interakce uživatele (UIF)" msgid "switch to the OpenPGP app" -msgstr "" +msgstr "přepne do aplikace OpenPGP" msgid "gpg/card> " msgstr "gpg/karta> " @@ -1825,7 +1825,7 @@ msgstr "chyba při vytváření hesla: %s\n" #, c-format msgid "can't use a SKESK packet due to the S2K mode\n" -msgstr "v režimu S2K nelze použít symetrický ESK paket\n" +msgstr "v režimu S2K nelze použít SKESK paket\n" #, c-format msgid "using cipher %s.%s\n" @@ -1895,18 +1895,14 @@ msgstr "odstranit nepoužitelné části z klíče při exportu" msgid "remove as much as possible from key during export" msgstr "odstranit při exportu z klíče vše, co lze" -#, fuzzy -#| msgid "generate a revocation certificate" msgid "export only revocation certificates" -msgstr "vytvořit revokační certifikát" +msgstr "exportovat pouze revokační certifikáty" msgid "use the GnuPG key backup format" msgstr "použít záložní formát klíče GnuPG" -#, fuzzy -#| msgid "exporting secret keys not allowed\n" msgid "export secret keys using the GnuPG format" -msgstr "exportování tajného klíče není povoleno\n" +msgstr "exportovat tajné klíče do formátu GnuPG" msgid " - skipped" msgstr " – přeskočeno" @@ -2342,10 +2338,8 @@ msgstr "ukazovat odvolané a prošlé ID uživatelů při výpisu klíčů" msgid "show revoked and expired subkeys in key listings" msgstr "ukazovat odvolané a prošlé podklíče při výpisu klíčů" -#, fuzzy -#| msgid "show expiration dates during signature listings" msgid "show signatures with invalid algorithms during signature listings" -msgstr "ukazovat data expirace během výpisu podpisů" +msgstr "ukazovat podpisy s neplatnými algoritmy během výpisu podpisů" msgid "show the keyring name in key listings" msgstr "ukazovat název souboru s klíči při výpisu klíčů" @@ -2353,10 +2347,8 @@ msgstr "ukazovat název souboru s klíči při výpisu klíčů" msgid "show expiration dates during signature listings" msgstr "ukazovat data expirace během výpisu podpisů" -#, fuzzy -#| msgid "list preferences (expert)" msgid "show preferences" -msgstr "vypsat seznam předvoleb (pro experty)" +msgstr "vypsat předvolby" #, c-format msgid "unknown TOFU policy '%s'\n" @@ -2964,7 +2956,7 @@ msgstr "klíč %s: chyba při odesílání dat agentovi: %s\n" #, c-format msgid "key %s: card reference is overridden by key material\n" -msgstr "" +msgstr "klíč %s: odkaz na kartu je přebit hodnotou klíče\n" #. TRANSLATORS: For a smartcard, each private key on host has a #. * reference (stub) to a smartcard and actual private key data @@ -3481,10 +3473,8 @@ msgstr "smazat vybrané podklíče" msgid "add a revocation key" msgstr "přidat revokační klíč" -#, fuzzy -#| msgid "Data decryption succeeded" msgid "add an additional decryption subkey" -msgstr "Dešifrování dat uspělo" +msgstr "přidat dodatečný dešifrovací podklíč" msgid "delete signatures from the selected user IDs" msgstr "smazat podpisy z vybraných uživatelských ID" @@ -3547,11 +3537,10 @@ msgstr "Tajný klíč je dostupný.\n" msgid "Secret subkeys are available.\n" msgstr "Tajné podklíče jsou dostupné.\n" -#, fuzzy -#| msgid "Note: Only the secret part of the shown subkey will be deleted.\n" msgid "" "Note: the local copy of the secret key will only be deleted with \"save\".\n" -msgstr "Poznámka: Smazána bude pouze tajná část zobrazeného podklíče.\n" +msgstr "" +"Poznámka: Místní kopie tajného klíče bude smazána až s příkazem „save“.\n" msgid "Need the secret key to do this.\n" msgstr "Pro provedení této operace je potřeba tajný klíč.\n" @@ -3661,11 +3650,9 @@ msgstr "Uložit změny? (a/N) " msgid "Quit without saving? (y/N) " msgstr "Ukončit bez uložení? (a/N) " -# The first argument is a "key" or "subkey" -#, fuzzy, c-format -#| msgid "deleting secret %s failed: %s\n" +#, c-format msgid "deleting copy of secret key failed: %s\n" -msgstr "smazání tajného %s se nezdařilo: %s\n" +msgstr "smazání kopie tajného klíče se nezdařilo: %s\n" #, c-format msgid "Key not changed so no update needed.\n" @@ -3805,10 +3792,9 @@ msgstr "POZOR: Vašemu šifrovacímu podklíči brzy vyprší platnost.\n" msgid "You may want to change its expiration date too.\n" msgstr "Dobu platnosti také můžete změnit.\n" -#, fuzzy, c-format -#| msgid "WARNING: Your encryption subkey expires soon.\n" +#, c-format msgid "WARNING: No valid encryption subkey left over.\n" -msgstr "POZOR: Vašemu šifrovacímu podklíči brzy vyprší platnost.\n" +msgstr "POZOR: Nezbyl žádný platný šifrovací podklíč.\n" msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " @@ -3905,17 +3891,15 @@ msgid "" msgstr "Jste si jistí, že tento klíč chcete pověřit odvoláním? (a/N) " msgid "Enter the fingerprint of the additional decryption subkey: " -msgstr "" +msgstr "Zadejte otisk dodatečného dešifrovacího podklíče: " -#, fuzzy, c-format -#| msgid "(unless you specify the key by fingerprint)\n" +#, c-format msgid "Did you specify the fingerprint of a subkey?\n" -msgstr "(dokud neurčíte klíč jeho otiskem)\n" +msgstr "Zadali jste otisk podklíče?\n" -#, fuzzy, c-format -#| msgid "Subkey %s is already revoked.\n" +#, c-format msgid "key \"%s\" is already on this keyblock\n" -msgstr "Podklíč %s je již odvolán.\n" +msgstr "klíč „%s“ je již v tomto bloku klíče.\n" msgid "" "Are you sure you want to change the expiration time for multiple subkeys? (y/" @@ -8996,24 +8980,30 @@ msgstr "Příkazy pro správu Yubikey" msgid "manage the command history" msgstr "spravuje historii příkazů" -#~ msgid "continuing verification anyway due to option %s\n" -#~ msgstr "přesto se pokračuje v ověřování kvůli volbě %s\n" - +#, c-format #~ msgid "selected AEAD algorithm is invalid\n" #~ msgstr "vybraný algoritmus AEAD je neplatný\n" +#, c-format #~ msgid "invalid personal AEAD preferences\n" #~ msgstr "neplatné uživatelské předvolby pro AEAD\n" +#, c-format #~ msgid "AEAD algorithm '%s' may not be used in %s mode\n" #~ msgstr "AEAD algoritmus „%s“ se nesmí používat v režimu %s\n" +#, c-format +#~ msgid "continuing verification anyway due to option %s\n" +#~ msgstr "přesto se pokračuje v ověřování kvůli volbě %s\n" + +#, c-format #~ msgid "error writing to temporary file: %s\n" #~ msgstr "chyba při zápisu do dočasného souboru: %s\n" #~ msgid "run in supervised mode" #~ msgstr "poběží v režimu dohledu" +#, c-format #~ msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" #~ msgstr "vyžádaná symetrická šifra %s (%d) nevyhovuje předvolbám příjemce\n" @@ -9029,12 +9019,15 @@ msgstr "spravuje historii příkazů" #~ msgid "Configuration of LDAP servers to use" #~ msgstr "Nastavení používaných LDAP serverů" +#, c-format #~ msgid "selfsigned certificate has a BAD signature" #~ msgstr "sám sebou podepsaný certifikát má CHYBNÝ podpis" +#, c-format #~ msgid "detected card with S/N: %s\n" #~ msgstr "nalezena karta se sériovým číslem: %s\n" +#, c-format #~ msgid "no authentication key for ssh on card: %s\n" #~ msgstr "na kartě není autentizační klíč pro SSH: %s\n" @@ -9044,15 +9037,19 @@ msgstr "spravuje historii příkazů" #~ msgid "use a log file for the server" #~ msgstr "použít pro server soubor s protokolem" +#, c-format #~ msgid "Note: no default option file '%s'\n" #~ msgstr "Poznámka: neexistuje implicitní soubor s možnostmi „%s“\n" +#, c-format #~ msgid "option file '%s': %s\n" #~ msgstr "soubor s možnostmi „%s“: %s\n" +#, c-format #~ msgid "connection to %s established\n" #~ msgstr "spojení k programu %s ustanoveno\n" +#, c-format #~ msgid "no running gpg-agent - starting '%s'\n" #~ msgstr "gpg-agent neběží – spouští se „%s“\n" @@ -9083,33 +9080,43 @@ msgstr "spravuje historii příkazů" #~ msgid "invalid option" #~ msgstr "neplatný parametr" +#, c-format #~ msgid "missing argument for option \"%.50s\"\n" #~ msgstr "postrádám argument u volby „%.50s“\n" +#, c-format #~ msgid "option \"%.50s\" does not expect an argument\n" #~ msgstr "volba „%.50s“ nečeká argument\n" +#, c-format #~ msgid "invalid command \"%.50s\"\n" #~ msgstr "neplatný příkaz „%.50s“\n" +#, c-format #~ msgid "option \"%.50s\" is ambiguous\n" #~ msgstr "volba „%.50s“ není jednoznačná\n" +#, c-format #~ msgid "command \"%.50s\" is ambiguous\n" #~ msgstr "příkaz „%.50s“ není jednoznačný\n" +#, c-format #~ msgid "invalid option \"%.50s\"\n" #~ msgstr "neplatný parametr „%.50s“\n" +#, c-format #~ msgid "unable to execute program '%s': %s\n" #~ msgstr "nelze spustit program „%s“: %s\n" +#, c-format #~ msgid "unable to execute external program\n" #~ msgstr "nelze spustit externí program\n" +#, c-format #~ msgid "unable to read external program response: %s\n" #~ msgstr "nelze přečíst odpověď externího programu: %s\n" +#, c-format #~ msgid "Note: old default options file '%s' ignored\n" #~ msgstr "Poznámka: starý implicitní soubor s možnostmi „%s“ ignorován\n" @@ -9119,34 +9126,42 @@ msgstr "spravuje historii příkazů" #~ msgid "elevate the trust of signatures with valid PKA data" #~ msgstr "vyzvednout důvěru podpisů s platnými daty PKA" +#, c-format #~ msgid " (%d) ECC and ECC\n" #~ msgstr " (%d) ECC a ECC\n" #~ msgid "honor the PKA record set on a key when retrieving keys" #~ msgstr "respektovat PKA záznamy klíče při získávání klíčů" +#, c-format #~ msgid "requesting key %s from %s server %s\n" #~ msgstr "požaduji klíč %s z %s serveru %s\n" +#, c-format #~ msgid "Note: Verified signer's address is '%s'\n" #~ msgstr "Poznámka: Podepisovatelova ověřená adresa je „%s“\n" +#, c-format #~ msgid "Note: Signer's address '%s' does not match DNS entry\n" #~ msgstr "" #~ "Poznámka: Podepisovatelova adresa „%s“ se neshoduje s DNS záznamem\n" +#, c-format #~ msgid "trustlevel adjusted to FULL due to valid PKA info\n" #~ msgstr "úroveň důvěry opravena na PLNOU, kvůli platné PKA informaci\n" +#, c-format #~ msgid "trustlevel adjusted to NEVER due to bad PKA info\n" #~ msgstr "úroveň důvěry opravena na ŽÁDNOU, kvůli špatné PKA informaci\n" #~ msgid "|FILE|write a server mode log to FILE" #~ msgstr "|SOUBOR|zapisovat protokol režimu server do SOUBORU" +#, c-format #~ msgid "%s:%u: no hostname given\n" #~ msgstr "%s:%u: nebyl zadán název stroje\n" +#, c-format #~ msgid "could not parse keyserver\n" #~ msgstr "nelze rozebrat serveru klíčů\n" @@ -9195,66 +9210,87 @@ msgstr "spravuje historii příkazů" #~ "Vnitřní LDAP pomůcka pro pro Dirmngr.\n" #~ "Rozhraní a volby se mohou bez upozornění změnit.\n" +#, c-format #~ msgid "invalid port number %d\n" #~ msgstr "neplatné číslo portu %d\n" +#, c-format #~ msgid "scanning result for attribute '%s'\n" #~ msgstr "ve výsledku se hledá atribut „%s“\n" +#, c-format #~ msgid "error writing to stdout: %s\n" #~ msgstr "chyba při zápisu na standardní výstup: %s\n" +#, c-format #~ msgid " available attribute '%s'\n" #~ msgstr " dostupný atribut „%s“\n" +#, c-format #~ msgid "attribute '%s' not found\n" #~ msgstr "atribut „%s“ nenalezen\n" +#, c-format #~ msgid "found attribute '%s'\n" #~ msgstr "nalezen atribut „%s“\n" +#, c-format #~ msgid "processing url '%s'\n" #~ msgstr "zpracovává se URL „%s“\n" +#, c-format #~ msgid " user '%s'\n" #~ msgstr " uživatel „%s“\n" +#, c-format #~ msgid " pass '%s'\n" #~ msgstr " heslo „%s“\n" +#, c-format #~ msgid " host '%s'\n" #~ msgstr " stroj „%s“\n" +#, c-format #~ msgid " port %d\n" #~ msgstr " port %d\n" +#, c-format #~ msgid " DN '%s'\n" #~ msgstr " DN „%s“\n" +#, c-format #~ msgid " filter '%s'\n" #~ msgstr " filtr „%s“\n" +#, c-format #~ msgid " attr '%s'\n" #~ msgstr " atribut „%s“\n" +#, c-format #~ msgid "no host name in '%s'\n" #~ msgstr "v „%s“ chybí název stroje\n" +#, c-format #~ msgid "no attribute given for query '%s'\n" #~ msgstr "u dotazu „%s“ nezadán žádný atribut\n" +#, c-format #~ msgid "WARNING: using first attribute only\n" #~ msgstr "POZOR: použije se pouze první atribut\n" +#, c-format #~ msgid "LDAP init to '%s:%d' failed: %s\n" #~ msgstr "Inicializace LDAP u „%s:%d“ selhala: %s\n" +#, c-format #~ msgid "binding to '%s:%d' failed: %s\n" #~ msgstr "napojení k „%s:%d“ selhalo: %s\n" +#, c-format #~ msgid "searching '%s' failed: %s\n" #~ msgstr "hledávání „%s“ neuspělo: %s\n" +#, c-format #~ msgid "start_cert_fetch: invalid pattern '%s'\n" #~ msgstr "start_cert_fetch: chybný vzor „%s“\n" @@ -9311,72 +9347,95 @@ msgstr "spravuje historii příkazů" #~ "Syntaxe: symcryptrun --class TŘÍDA --program PROGRAM --keyfile SOUBOR " #~ "[VOLBY…] PŘÍKAZ [VSTUPNÍ_SOUBOR]\n" +#, c-format #~ msgid "%s on %s aborted with status %i\n" #~ msgstr "%s nad %s byl ukončen s kódem %i\n" +#, c-format #~ msgid "%s on %s failed with status %i\n" #~ msgstr "%s nad %s selhal s kódem %i\n" +#, c-format #~ msgid "can't create temporary directory '%s': %s\n" #~ msgstr "nelze vytvořit dočasný adresář „%s“: %s\n" +#, c-format #~ msgid "could not open %s for writing: %s\n" #~ msgstr "%s nelze otevřít pro zápis: %s\n" +#, c-format #~ msgid "error closing %s: %s\n" #~ msgstr "chyba při zavírání chyba %s: %s\n" +#, c-format #~ msgid "no --program option provided\n" #~ msgstr "nebyla zadána volba --program\n" +#, c-format #~ msgid "only --decrypt and --encrypt are supported\n" #~ msgstr "pouze --decrypt a --encrypt jsou podporovány\n" +#, c-format #~ msgid "no --keyfile option provided\n" #~ msgstr "nebyla zadána volba --keyfile\n" +#, c-format #~ msgid "cannot allocate args vector\n" #~ msgstr "nelze alokovat pole argumentů\n" +#, c-format #~ msgid "could not create pipe: %s\n" #~ msgstr "nelze vytvořit rouru: %s\n" +#, c-format #~ msgid "could not create pty: %s\n" #~ msgstr "nelze vytvořit PTY: %s\n" +#, c-format #~ msgid "could not fork: %s\n" #~ msgstr "nelze se rozdvojit (fork): %s\n" +#, c-format #~ msgid "execv failed: %s\n" #~ msgstr "execv selhalo: %s\n" +#, c-format #~ msgid "select failed: %s\n" #~ msgstr "služba select() selhala: %s\n" +#, c-format #~ msgid "read failed: %s\n" #~ msgstr "čtení selhalo: %s\n" +#, c-format #~ msgid "pty read failed: %s\n" #~ msgstr "čtení z PTY selhalo: %s\n" +#, c-format #~ msgid "waitpid failed: %s\n" #~ msgstr "služba waitpid() selhala: %s\n" +#, c-format #~ msgid "child aborted with status %i\n" #~ msgstr "potomek byl ukončen s kódem %i\n" +#, c-format #~ msgid "cannot allocate infile string: %s\n" #~ msgstr "nelze alokovat řetězec infile: %s\n" +#, c-format #~ msgid "cannot allocate outfile string: %s\n" #~ msgstr "nelze alokovat řetězec outfile: %s\n" +#, c-format #~ msgid "either %s or %s must be given\n" #~ msgstr "musí být zadáno buď %s, nebo %s\n" +#, c-format #~ msgid "no class provided\n" #~ msgstr "nezadána žádná třída\n" +#, c-format #~ msgid "class %s is not supported\n" #~ msgstr "třída %s není podporována\n" @@ -9392,6 +9451,7 @@ msgstr "spravuje historii příkazů" #~ msgid "Sex ((M)ale, (F)emale or space): " #~ msgstr "Zadejte pohlaví: M – mužské, F – ženské, nebo stiskněte mezerník: " +#, c-format #~ msgid " using certificate ID 0x%08lX\n" #~ msgstr " pomocí certifikátu s ID 0x%08lX\n" @@ -10584,8 +10644,8 @@ msgstr "spravuje historii příkazů" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -10632,8 +10692,8 @@ msgstr "spravuje historii příkazů" #~ "Answer \"yes\" if you really want to delete this user ID.\n" #~ "All certificates are then also lost!" #~ msgstr "" -#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte \"ano" -#~ "\".\n" +#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte " +#~ "\"ano\".\n" #~ "Všechny certifikáty budou také ztraceny!" #~ msgid "Answer \"yes\" if it is okay to delete the subkey" From baa88832153d99adbbbb70d6a420784cc1267e84 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 5 Jun 2023 15:07:22 +0200 Subject: [PATCH 051/869] gpg: Set default expiration date to 3 years. * g10/keygen.c (default_expiration_interval): Change. -- This is a revision of GnuPG-bug-id: 2701 --- g10/keygen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/keygen.c b/g10/keygen.c index 7f54f7da0..d5099dbb9 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -56,7 +56,7 @@ /* When generating keys using the streamlined key generation dialog, use this as a default expiration interval. */ -const char *default_expiration_interval = "2y"; +const char *default_expiration_interval = "3y"; /* Flag bits used during key generation. */ #define KEYGEN_FLAG_NO_PROTECTION 1 From 7b7fdf45e5d8b3b066c5efbf6ec872e1249f3a24 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 6 Jun 2023 18:19:37 +0200 Subject: [PATCH 052/869] common: New function substitute_vars. * common/stringhelp.c (substitute_envvars): Factor code out to (substitute_vars): new. (subst_getenv): New. -- This is a generalized version of substitute_envvars. --- common/stringhelp.c | 44 ++++++++++++++++++++++++++++++++++++++------ common/stringhelp.h | 5 ++++- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/common/stringhelp.c b/common/stringhelp.c index 6959299e4..1049c78e2 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -1689,10 +1689,16 @@ format_text (const char *text_in, int target_cols, int max_cols) } -/* Substitute environment variables in STRING and return a new string. - * On error the function returns NULL. */ +/* Substitute variables in STRING and return a new string. GETVAL is + * a function which maps NAME to its value; that value is a string + * which may not change during the execution time of this function. + * If GETVAL returns NULL substitute_vars returns NULL and the caller + * may inspect ERRNO for the reason. In all other error cases this + * function also returns NULL. Caller must free the returned string. */ char * -substitute_envvars (const char *string) +substitute_vars (const char *string, + const char *(*getval)(void *cookie, const char *name), + void *cookie) { char *line, *p, *pend; const char *value; @@ -1743,19 +1749,22 @@ substitute_envvars (const char *string) { int save = *pend; *pend = 0; - value = getenv (p+2); + value = getval (cookie, p+2); *pend++ = save; } else { int save = *pend; *pend = 0; - value = getenv (p+1); + value = getval (cookie, p+1); *pend = save; } if (!value) - value = ""; + { + xfree (result); + return NULL; + } valuelen = strlen (value); if (valuelen <= pend - p) { @@ -1791,3 +1800,26 @@ substitute_envvars (const char *string) leave: return result; } + + +/* Helper for substitute_envvars. */ +static const char * +subst_getenv (void *cookie, const char *name) +{ + const char *s; + + (void)cookie; + + s = getenv (name); + return s? s : ""; +} + + +/* Substitute environment variables in STRING and return a new string. + * On error the function returns NULL. */ +char * +substitute_envvars (const char *string) +{ + return substitute_vars (string, subst_getenv, NULL); + +} diff --git a/common/stringhelp.h b/common/stringhelp.h index 915b3aa72..cd185e49a 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -169,7 +169,10 @@ int compare_version_strings (const char *my_version, const char *req_version); /* Format a string so that it fits within about TARGET_COLS columns. */ char *format_text (const char *text, int target_cols, int max_cols); -/* Substitute environmen variabales in STRING. */ +/* Substitute variables in STRING. */ +char *substitute_vars (const char *string, + const char *(*getval)(void *cookie, const char *name), + void *cookie); char *substitute_envvars (const char *string); From 9433dfa5dd4ba1f90a9c09c41a695f55b6c1f9a8 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 7 Jun 2023 09:08:58 +0900 Subject: [PATCH 053/869] common: Add test case for IPC with spawned process. * common/Makefile.am (module_tests): Add t-exechelp. * common/t-exechelp.c [HAVE_W32_SYSTEM] (print_open_fds) (test_close_all_fds, main): Exclude the test_close_all_fds test. (run_server, test_pipe_stream): New. Signed-off-by: NIIBE Yutaka --- common/Makefile.am | 4 +- common/t-exechelp.c | 103 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 4 deletions(-) diff --git a/common/Makefile.am b/common/Makefile.am index d5ab038bf..0d5af3e5c 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -161,11 +161,11 @@ module_tests = t-stringhelp t-timestuff \ t-convert t-percent t-gettime t-sysutils t-sexputil \ t-session-env t-openpgp-oid t-ssh-utils \ t-mapstrings t-zb32 t-mbox-util t-iobuf t-strlist \ - t-name-value t-ccparray t-recsel t-w32-cmdline + t-name-value t-ccparray t-recsel t-w32-cmdline t-exechelp if HAVE_W32_SYSTEM module_tests += t-w32-reg else -module_tests += t-exechelp t-exectool +module_tests += t-exectool endif if MAINTAINER_MODE diff --git a/common/t-exechelp.c b/common/t-exechelp.c index 3bf082bbb..613beb82b 100644 --- a/common/t-exechelp.c +++ b/common/t-exechelp.c @@ -29,7 +29,7 @@ static int verbose; - +#ifndef HAVE_W32_SYSTEM static void print_open_fds (int *array) { @@ -169,20 +169,119 @@ test_close_all_fds (void) } } +#endif + +static char buff12k[1024*12]; + +static void +run_server (void) +{ + estream_t fp; + int i; + char *p; + unsigned int len; + int ret; + + fp = es_fdopen_nc (1, "w"); + if (fp == NULL) + { + fprintf (stderr, "es_fdopen failed\n"); + exit (1); + } + + /* Fill the buffer by ASCII chars. */ + p = buff12k; + for (i = 0; i < sizeof (buff12k); i++) + if ((i % 64) == 63) + *p++ = '\n'; + else + *p++ = (i % 64) + '@'; + + len = sizeof (buff12k); + + ret = es_write (fp, (void *)&len, sizeof (len), NULL); + if (ret) + { + fprintf (stderr, "es_write (1) failed\n"); + exit (1); + } + + ret = es_write (fp, buff12k, sizeof (buff12k), NULL); + if (ret) + { + fprintf (stderr, "es_write (2) failed\n"); + exit (1); + } + es_fclose (fp); + exit (0); +} + + +static void +test_pipe_stream (const char *pgmname) +{ + gpg_error_t err; + gnupg_process_t proc; + estream_t outfp; + const char *argv[2]; + unsigned int len; + size_t n; + int ret; + + argv[0] = "--server"; + argv[1] = NULL; + + err = gnupg_process_spawn (pgmname, argv, + (GNUPG_PROCESS_STDOUT_PIPE + |GNUPG_PROCESS_STDERR_KEEP), + NULL, NULL, &proc); + if (err) + { + fprintf (stderr, "gnupg_process_spawn failed\n"); + exit (1); + } + + gnupg_process_get_streams (proc, 0, NULL, &outfp, NULL); + + ret = es_read (outfp, (void *)&len, sizeof (len), NULL); + if (ret) + { + fprintf (stderr, "es_read (1) failed\n"); + exit (1); + } + ret = es_read (outfp, buff12k, sizeof (buff12k), &n); + if (ret || n != sizeof (buff12k)) + { + fprintf (stderr, "es_read (2) failed\n"); + exit (1); + } + es_fclose (outfp); + gnupg_process_release (proc); +} int main (int argc, char **argv) { + const char *myname = "no-pgm"; + if (argc) - { argc--; argv++; } + { + myname = argv[0]; + argc--; argv++; + } if (argc && !strcmp (argv[0], "--verbose")) { verbose = 1; argc--; argv++; } + if (argc && !strcmp (argv[0], "--server")) + run_server (); +#ifndef HAVE_W32_SYSTEM test_close_all_fds (); +#endif + test_pipe_stream (myname); return 0; } From f5656ff363a00c7649224d827b92c3e6031b6b77 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 7 Jun 2023 15:26:34 +0900 Subject: [PATCH 054/869] kbx: Fix datastream_thread and use the data pipe. * g10/call-keyboxd.c (gpg_keyboxd_deinit_session_data): Release the assuan connection before kbx_client_data_release. (open_context): Enable use of the data pipe. * sm/keydb.c (gpgsm_keydb_deinit_session_data): Release the assuan connection before kbx_client_data_release. (open_context): Enable use of the data pipe. * kbx/kbx-client-util.c (struct kbx_client_data_s): Add THD field. (prepare_data_pipe): Close the pipe output end as it's been sent already. Remember the KCD->THD, so that it can be joined later. (datastream_thread): Finish when reading no data from the pipe. (kbx_client_data_release): Join the thread. Then, we can safely call es_fclose on the FP. -- GnuPG-bug-id: 6512 Signed-off-by: NIIBE Yutaka --- g10/call-keyboxd.c | 13 ++++++++++--- kbx/kbx-client-util.c | 32 ++++++++++++-------------------- sm/keydb.c | 13 ++++++++++--- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/g10/call-keyboxd.c b/g10/call-keyboxd.c index 7f4d5f493..dc3d30a93 100644 --- a/g10/call-keyboxd.c +++ b/g10/call-keyboxd.c @@ -94,8 +94,6 @@ gpg_keyboxd_deinit_session_data (ctrl_t ctrl) log_error ("oops: trying to cleanup an active keyboxd context\n"); else { - kbx_client_data_release (kbl->kcd); - kbl->kcd = NULL; if (kbl->ctx && in_transaction) { /* This is our hack to commit the changes done during a @@ -112,6 +110,15 @@ gpg_keyboxd_deinit_session_data (ctrl_t ctrl) } assuan_release (kbl->ctx); kbl->ctx = NULL; + /* + * Since there may be pipe output FD sent to the server (so + * that it can receive data through the pipe), we should + * release the assuan connection before releasing KBL->KCD. + * This way, the data receiving thread can finish cleanly, + * and we can join the thread. + */ + kbx_client_data_release (kbl->kcd); + kbl->kcd = NULL; } xfree (kbl); } @@ -223,7 +230,7 @@ open_context (ctrl_t ctrl, keyboxd_local_t *r_kbl) return err; } - err = kbx_client_data_new (&kbl->kcd, kbl->ctx, 1); + err = kbx_client_data_new (&kbl->kcd, kbl->ctx, 0); if (err) { assuan_release (kbl->ctx); diff --git a/kbx/kbx-client-util.c b/kbx/kbx-client-util.c index 79d512bb3..ca791d4a3 100644 --- a/kbx/kbx-client-util.c +++ b/kbx/kbx-client-util.c @@ -53,6 +53,7 @@ struct kbx_client_data_s /* Condition variable to sync the datastream with the command. */ npth_mutex_t mutex; npth_cond_t cond; + npth_t thd; /* The data received from the keyboxd and an error code if there was * a problem (in which case DATA is also set to NULL. This is only @@ -103,7 +104,6 @@ prepare_data_pipe (kbx_client_data_t kcd) int rc; int inpipe[2]; estream_t infp; - npth_t thread; npth_attr_t tattr; kcd->fp = NULL; @@ -142,6 +142,7 @@ prepare_data_pipe (kbx_client_data_t kcd) return 0; } + close (inpipe[1]); kcd->fp = infp; @@ -154,8 +155,8 @@ prepare_data_pipe (kbx_client_data_t kcd) kcd->fp = NULL; return err; } - npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED); - rc = npth_create (&thread, &tattr, datastream_thread, kcd); + npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE); + rc = npth_create (&kcd->thd, &tattr, datastream_thread, kcd); if (rc) { err = gpg_error_from_errno (rc); @@ -197,20 +198,8 @@ datastream_thread (void *arg) gnupg_sleep (1); continue; } -#ifdef HAVE_W32_SYSTEM - if (nread == 0) - { - gnupg_sleep (1); - continue; - } -#endif - if (nread != 4) - { - err = gpg_error (GPG_ERR_EIO); - log_error ("error reading data length from keyboxd: %s\n", - "short read"); - continue; - } + if (nread < 4) + break; datalen = buf32_to_size_t (lenbuf); /* log_debug ("keyboxd announced %zu bytes\n", datalen); */ @@ -340,11 +329,14 @@ kbx_client_data_release (kbx_client_data_t kcd) if (!kcd) return; + + if (npth_join (kcd->thd, NULL)) + log_error ("kbx_client_data_release failed on npth_join"); + fp = kcd->fp; kcd->fp = NULL; - es_fclose (fp); /* That close should let the thread run into an error. */ - /* FIXME: Make thread killing explicit. Otherwise we run in a - * log_fatal due to the destroyed mutex. */ + es_fclose (fp); + npth_cond_destroy (&kcd->cond); npth_mutex_destroy (&kcd->mutex); xfree (kcd); diff --git a/sm/keydb.c b/sm/keydb.c index 38737c96a..9b3c7c8ba 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -161,10 +161,17 @@ gpgsm_keydb_deinit_session_data (ctrl_t ctrl) log_error ("oops: trying to cleanup an active keydb context\n"); else { - kbx_client_data_release (kbl->kcd); - kbl->kcd = NULL; assuan_release (kbl->ctx); kbl->ctx = NULL; + /* + * Since there may be pipe output FD sent to the server (so + * that it can receive data through the pipe), we should + * release the assuan connection before releasing KBL->KCD. + * This way, the data receiving thread can finish cleanly, + * and we can join the thread. + */ + kbx_client_data_release (kbl->kcd); + kbl->kcd = NULL; } xfree (kbl); } @@ -580,7 +587,7 @@ open_context (ctrl_t ctrl, keydb_local_t *r_kbl) return err; } - err = kbx_client_data_new (&kbl->kcd, kbl->ctx, 1); + err = kbx_client_data_new (&kbl->kcd, kbl->ctx, 0); if (err) { assuan_release (kbl->ctx); From 207c99567ced260aab04c471c77f179943d492f4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 7 Jun 2023 10:03:48 +0200 Subject: [PATCH 055/869] dirmngr: Extend the AD_QUERY command. * dirmngr/server.c (cmd_ad_query): Add options --help and --subst. (cmd_getinfo): Add sub-command "sid". * dirmngr/ks-engine.h (KS_GET_FLAG_SUBST): New. * dirmngr/ks-engine-ldap.c (ks_ldap_help_variables): New. (getval_for_filter): New. (map_rid_to_dn): New. (ks_ldap_query): Support variables. -- The new variables features makes it easier to write AD queries without requiring domain specific expressions. --- common/name-value.c | 2 +- dirmngr/ks-engine-ldap.c | 191 +++++++++++++++++++++++++++++++++++++++ dirmngr/ks-engine.h | 2 + dirmngr/server.c | 66 ++++++++++++-- 4 files changed, 252 insertions(+), 9 deletions(-) diff --git a/common/name-value.c b/common/name-value.c index 6f3df5a8d..0dffc63b4 100644 --- a/common/name-value.c +++ b/common/name-value.c @@ -616,7 +616,7 @@ nve_next_value (nve_t entry, const char *name) /* Return the string for the first entry in NVC with NAME. If an * entry with NAME is missing in NVC or its value is the empty string - * NULL is returned. Note that the The returned string is a pointer + * NULL is returned. Note that the the returned string is a pointer * into NVC. */ const char * nvc_get_string (nvc_t nvc, const char *name) diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index 1ffd30ecb..c2a210542 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -26,6 +26,13 @@ #include #include #include +#ifdef HAVE_W32_SYSTEM +# ifndef WINVER +# define WINVER 0x0500 /* Same as in common/sysutils.c */ +# endif +# include +# include +#endif #include "dirmngr.h" @@ -73,6 +80,9 @@ struct ks_engine_ldap_local_s int more_pages; /* More pages announced by server. */ }; +/*-- prototypes --*/ +static char *map_rid_to_dn (ctrl_t ctrl, const char *rid); +static char *basedn_from_rootdse (ctrl_t ctrl, parsed_uri_t uri); @@ -150,6 +160,114 @@ my_ldap_value_free (char **vals) } +/* Print a description of supported variables. */ +void +ks_ldap_help_variables (ctrl_t ctrl) +{ + const char data[] = + "Supported variables in LDAP filter expressions:\n" + "\n" + "domain - The defaultNamingContext.\n" + "domain_admins - Group of domain admins.\n" + "domain_users - Group with all user accounts.\n" + "domain_guests - Group with the builtin gues account.\n" + "domain_computers - Group with all clients and servers.\n" + "cert_publishers - Group with all cert issuing computers.\n" + "protected_users - Group of users with extra protection.\n" + "key_admins - Group for delegated access to msdsKeyCredentialLink.\n" + "enterprise_key_admins - Similar to key_admins.\n" + "domain_domain_controllers - Group with all domain controllers.\n" + "sid_domain - SubAuthority numbers.\n"; + + ks_print_help (ctrl, data); +} + + +/* Helper function for substitute_vars. */ +static const char * +getval_for_filter (void *cookie, const char *name) +{ + ctrl_t ctrl = cookie; + const char *result = NULL; + + if (!strcmp (name, "sid_domain")) + { +#ifdef HAVE_W32_SYSTEM + PSID mysid; + static char *sidstr; + char *s, *s0; + int i; + + if (!sidstr) + { + mysid = w32_get_user_sid (); + if (!mysid) + { + gpg_err_set_errno (ENOENT); + goto leave; + } + + if (!ConvertSidToStringSid (mysid, &sidstr)) + { + gpg_err_set_errno (EINVAL); + goto leave; + } + /* Example for SIDSTR: + * S-1-5-21-3636969917-2569447256-918939550-1127 */ + for (s0=NULL,s=sidstr,i=0; (s=strchr (s, '-')); i++) + { + s++; + if (i == 3) + s0 = s; + else if (i==6) + { + s[-1] = 0; + break; + } + } + if (!s0) + { + log_error ("oops: invalid SID received from OS"); + gpg_err_set_errno (EINVAL); + LocalFree (sidstr); + goto leave; + } + sidstr = s0; /* (We never release SIDSTR thus no memmove.) */ + } + result = sidstr; +#else + gpg_err_set_errno (ENOSYS); + goto leave; +#endif + } + else if (!strcmp (name, "domain")) + result = basedn_from_rootdse (ctrl, NULL); + else if (!strcmp (name, "domain_admins")) + result = map_rid_to_dn (ctrl, "512"); + else if (!strcmp (name, "domain_users")) + result = map_rid_to_dn (ctrl, "513"); + else if (!strcmp (name, "domain_guests")) + result = map_rid_to_dn (ctrl, "514"); + else if (!strcmp (name, "domain_computers")) + result = map_rid_to_dn (ctrl, "515"); + else if (!strcmp (name, "domain_domain_controllers")) + result = map_rid_to_dn (ctrl, "516"); + else if (!strcmp (name, "cert_publishers")) + result = map_rid_to_dn (ctrl, "517"); + else if (!strcmp (name, "protected_users")) + result = map_rid_to_dn (ctrl, "525"); + else if (!strcmp (name, "key_admins")) + result = map_rid_to_dn (ctrl, "526"); + else if (!strcmp (name, "enterprise_key_admins")) + result = map_rid_to_dn (ctrl, "527"); + else + result = ""; /* Unknown variables are empty. */ + + leave: + return result; +} + + /* Print a help output for the schemata supported by this module. */ gpg_error_t @@ -1396,6 +1514,63 @@ fetch_rootdse (ctrl_t ctrl, parsed_uri_t uri) } +/* Return the DN for the given RID. This is used with the Active + * Directory. */ +static char * +map_rid_to_dn (ctrl_t ctrl, const char *rid) +{ + gpg_error_t err; + char *result = NULL; + estream_t infp = NULL; + uri_item_t puri; /* The broken down URI. */ + nvc_t nvc = NULL; + char *filter = NULL; + const char *s; + char *attr[2] = {"dn", NULL}; + + err = ks_action_parse_uri ("ldap:///", &puri); + if (err) + return NULL; + + filter = strconcat ("(objectSid=S-1-5-21-$sid_domain-", rid, ")", NULL); + if (!filter) + goto leave; + + err = ks_ldap_query (ctrl, puri->parsed_uri, KS_GET_FLAG_SUBST, + filter, attr, NULL, &infp); + if (err) + { + log_error ("ldap: AD query '%s' failed: %s\n", filter,gpg_strerror (err)); + goto leave; + } + if ((err = nvc_parse (&nvc, NULL, infp))) + { + log_error ("ldap: parsing the result failed: %s\n",gpg_strerror (err)); + goto leave; + } + if (!(s = nvc_get_string (nvc, "Dn:"))) + { + err = gpg_error (GPG_ERR_NOT_FOUND); + log_error ("ldap: mapping rid '%s'failed: %s\n", rid, gpg_strerror (err)); + goto leave; + } + result = xtrystrdup (s); + if (!result) + { + err = gpg_error_from_syserror (); + log_error ("ldap: strdup failed: %s\n", gpg_strerror (err)); + goto leave; + } + + leave: + es_fclose (infp); + release_uri_item_list (puri); + xfree (filter); + nvc_release (nvc); + return result; +} + + /* Return the baseDN for URI which might have already been cached for * this session. */ static char * @@ -2824,6 +2999,7 @@ ks_ldap_query (ctrl_t ctrl, parsed_uri_t uri, unsigned int ks_get_flags, LDAP *ldap_conn = NULL; char *basedn = NULL; estream_t fp = NULL; + char *filter_arg_buffer = NULL; char *filter = NULL; int scope = LDAP_SCOPE_SUBTREE; LDAPMessage *message = NULL; @@ -2839,6 +3015,20 @@ ks_ldap_query (ctrl_t ctrl, parsed_uri_t uri, unsigned int ks_get_flags, if ((!filter_arg || !*filter_arg) && (ks_get_flags & KS_GET_FLAG_ROOTDSE)) filter_arg = "^&base&(objectclass=*)"; + if ((ks_get_flags & KS_GET_FLAG_SUBST) + && filter_arg && strchr (filter_arg, '$')) + { + filter_arg_buffer = substitute_vars (filter_arg, getval_for_filter, ctrl); + if (!filter_arg_buffer) + { + err = gpg_error_from_syserror (); + log_error ("substituting filter variables failed: %s\n", + gpg_strerror (err)); + goto leave; + } + filter_arg = filter_arg_buffer; + } + err = ks_ldap_prepare_my_state (ctrl, ks_get_flags, &first_mode, &next_mode); if (err) goto leave; @@ -3048,6 +3238,7 @@ ks_ldap_query (ctrl_t ctrl, parsed_uri_t uri, unsigned int ks_get_flags, ldap_unbind (ldap_conn); xfree (filter); + xfree (filter_arg_buffer); return err; } diff --git a/dirmngr/ks-engine.h b/dirmngr/ks-engine.h index 03588a4d3..6de77ccb2 100644 --- a/dirmngr/ks-engine.h +++ b/dirmngr/ks-engine.h @@ -29,6 +29,7 @@ #define KS_GET_FLAG_NEXT 4 #define KS_GET_FLAG_ONLY_AD 8 /* Do this only if we have an AD. */ #define KS_GET_FLAG_ROOTDSE 16 /* Get the rootDSE. */ +#define KS_GET_FLAG_SUBST 32 /* Substiture variables. */ /*-- ks-action.c --*/ @@ -70,6 +71,7 @@ gpg_error_t ks_kdns_help (ctrl_t ctrl, parsed_uri_t uri); gpg_error_t ks_kdns_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp); /*-- ks-engine-ldap.c --*/ +void ks_ldap_help_variables (ctrl_t ctrl); gpg_error_t ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri); void ks_ldap_free_state (struct ks_engine_ldap_local_s *state); gpg_error_t ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, diff --git a/dirmngr/server.c b/dirmngr/server.c index 2c5a41b07..51a149cb2 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -32,6 +32,13 @@ #include #include #include +#ifdef HAVE_W32_SYSTEM +# ifndef WINVER +# define WINVER 0x0500 /* Same as in common/sysutils.c */ +# endif +# include +# include +#endif #include "dirmngr.h" #include @@ -2701,15 +2708,21 @@ cmd_ks_put (assuan_context_t ctx, char *line) static const char hlp_ad_query[] = - "AD_QUERY [--first|--next] [--] \n" + "AD_QUERY [--first|--next] [--] \n" "\n" "Query properties from a Windows Active Directory.\n" - "Our extended filter syntax may be used for the filter\n" - "expression; see gnupg/dirmngr/ldap-misc.c. There are\n" - "a couple of other options available:\n\n" - " --rootdse - Query the root using serverless binding,\n" + "Options:\n" + "\n" + " --rootdse - Query the root using serverless binding,\n" + " --subst - Substitute variables in the filter\n" " --attr= - Comma delimited list of attributes\n" " to return.\n" + " --help - List supported variables\n" + "\n" + "Extended filter syntax is allowed:\n" + " ^[][&]&[]\n" + "Usual escaping rules apply. An ampersand in must\n" + "doubled. may be \"base\", \"one\", or \"sub\"." ; static gpg_error_t cmd_ad_query (assuan_context_t ctx, char *line) @@ -2723,6 +2736,7 @@ cmd_ad_query (assuan_context_t ctx, char *line) char **opt_attr = NULL; const char *s; gnupg_isotime_t opt_newer; + int opt_help = 0; *opt_newer = 0; @@ -2733,6 +2747,10 @@ cmd_ad_query (assuan_context_t ctx, char *line) flags |= KS_GET_FLAG_NEXT; if (has_option (line, "--rootdse")) flags |= KS_GET_FLAG_ROOTDSE; + if (has_option (line, "--subst")) + flags |= KS_GET_FLAG_SUBST; + if (has_option (line, "--help")) + opt_help = 1; if ((s = option_value (line, "--newer")) && !string2isotime (opt_newer, s)) { @@ -2756,6 +2774,13 @@ cmd_ad_query (assuan_context_t ctx, char *line) line = skip_options (line); filter = line; + if (opt_help) + { + ks_ldap_help_variables (ctrl); + err = 0; + goto leave; + } + if ((flags & KS_GET_FLAG_NEXT)) { if (*filter || (flags & ~KS_GET_FLAG_NEXT)) @@ -2907,14 +2932,39 @@ cmd_getinfo (assuan_context_t ctx, char *line) { const char *s = getenv (line); if (!s) - err = set_error (GPG_ERR_NOT_FOUND, "No such envvar"); - else - err = assuan_send_data (ctx, s, strlen (s)); + { + err = set_error (GPG_ERR_NOT_FOUND, "No such envvar"); + goto leave; + } + err = assuan_send_data (ctx, s, strlen (s)); } } +#ifdef HAVE_W32_SYSTEM + else if (!strcmp (line, "sid")) + { + PSID mysid; + char *sidstr; + + mysid = w32_get_user_sid (); + if (!mysid) + { + err = set_error (GPG_ERR_NOT_FOUND, "Error getting my SID"); + goto leave; + } + + if (!ConvertSidToStringSid (mysid, &sidstr)) + { + err = set_error (GPG_ERR_BUG, "Error converting SID to a string"); + goto leave; + } + err = assuan_send_data (ctx, sidstr, strlen (sidstr)); + LocalFree (sidstr); + } +#endif /*HAVE_W32_SYSTEM*/ else err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); + leave: return leave_cmd (ctx, err); } From 1b0ce9918c321a5060fb7c59a234ab683187e8c1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 8 Jun 2023 14:39:50 +0900 Subject: [PATCH 056/869] tests: Fix call-with-io deadlock. * tests/gpgscm/ffi.c (es_wrap): Ifdef-out. [HAVE_W32_SYSTEM] (read_from_pipe): New. (do_process_spawn_io): Rename from do_process_spawn. Do I/O with no deadlock. * tests/gpgscm/tests.scm (call-with-io): Use process-spawn-io. (es-read-all): Remove. -- GnuPG-bug-id: 6523 Signed-off-by: NIIBE Yutaka --- tests/gpgscm/ffi.c | 310 ++++++++++++++++++++++++++++++++++++++--- tests/gpgscm/tests.scm | 35 ++--- 2 files changed, 299 insertions(+), 46 deletions(-) diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index b46d5cb61..cac052138 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -647,6 +647,7 @@ static struct foreign_object_vtable es_object_vtable = es_object_to_string, }; +#if 0 static pointer es_wrap (scheme *sc, estream_t stream) { @@ -658,6 +659,7 @@ es_wrap (scheme *sc, estream_t stream) box->closed = 0; return sc->vptr->mk_foreign_object (sc, &es_object_vtable, box); } +#endif static struct es_object_box * es_unwrap (scheme *sc, pointer object) @@ -818,24 +820,104 @@ proc_unwrap (scheme *sc, pointer object) #define IS_A_proc(SC, X) proc_unwrap (SC, X) +#define SPAWN_IO_BUFSIZE 4096 + +#ifdef HAVE_W32_SYSTEM +struct rfp { + HANDLE hd; + char *buf; + size_t len; + off_t off; +}; + +static DWORD __attribute__((stdcall)) +read_from_pipe (void *arg) +{ + struct rfp *rfp = arg; + DWORD bytes_read; + + if (rfp->hd == INVALID_HANDLE_VALUE) + goto errout; + + while (1) + { + if (!ReadFile (rfp->hd, rfp->buf + rfp->off, rfp->len - rfp->off, + &bytes_read, NULL)) + { + DWORD ec = GetLastError (); + + if (ec == ERROR_BROKEN_PIPE) + { + CloseHandle (rfp->hd); + rfp->hd = INVALID_HANDLE_VALUE; + break; + } + + goto errout; + } + + if (bytes_read == 0) + /* It may occur, when it writes WriteFile with zero-byte on + the other end of the pipe. */ + continue; + else + { + rfp->off += bytes_read; + if (rfp->off == rfp->len) + { + rfp->len += SPAWN_IO_BUFSIZE; + rfp->buf = xtryrealloc (rfp->buf, rfp->len); + if (rfp->buf == NULL) + goto errout; + } + } + } + + return 0; + + errout: + if (rfp->hd != INVALID_HANDLE_VALUE) + { + CloseHandle (rfp->hd); + rfp->hd = INVALID_HANDLE_VALUE; + } + xfree (rfp->buf); + rfp->buf = NULL; + return 1; +} +#endif + + static pointer -do_process_spawn (scheme *sc, pointer args) +do_process_spawn_io (scheme *sc, pointer args) { FFI_PROLOG (); pointer arguments; + char *a_input; char **argv; size_t len; unsigned int flags; gnupg_process_t proc = NULL; estream_t infp; - estream_t outfp; - estream_t errfp; +#ifdef HAVE_W32_SYSTEM + HANDLE out_hd, err_hd; +#else + int out_fd, err_fd; +#endif + char *out_string = NULL; + char *err_string = NULL; + size_t out_len = SPAWN_IO_BUFSIZE; + size_t err_len = SPAWN_IO_BUFSIZE; + off_t out_off = 0; + off_t err_off = 0; + int retcode = -1; + pointer p0, p1, p2; FFI_ARG_OR_RETURN (sc, pointer, arguments, list, args); - FFI_ARG_OR_RETURN (sc, unsigned int, flags, number, args); - flags |= (GNUPG_PROCESS_STDIN_PIPE - | GNUPG_PROCESS_STDOUT_PIPE - | GNUPG_PROCESS_STDERR_PIPE); + FFI_ARG_OR_RETURN (sc, char *, a_input, string, args); + flags = (GNUPG_PROCESS_STDIN_PIPE + | GNUPG_PROCESS_STDOUT_PIPE + | GNUPG_PROCESS_STDERR_PIPE); FFI_ARGS_DONE_OR_RETURN (sc, args); err = ffi_list2argv (sc, arguments, &argv, &len); @@ -857,18 +939,208 @@ do_process_spawn (scheme *sc, pointer args) err = gnupg_process_spawn (argv[0], (const char **) &argv[1], flags, NULL, NULL, &proc); - err = gnupg_process_get_streams (proc, 0, &infp, &outfp, &errfp); + err = gnupg_process_get_streams (proc, 0, &infp, NULL, NULL); + + err = es_write (infp, a_input, strlen (a_input), NULL); + es_fclose (infp); + if (err) + { + gnupg_process_release (proc); + xfree (argv); + FFI_RETURN_ERR (sc, err); + } + +#ifdef HAVE_W32_SYSTEM + err = gnupg_process_ctl (proc, GNUPG_PROCESS_GET_HANDLES, + NULL, &out_hd, &err_hd); +#else + err = gnupg_process_get_fds (proc, 0, NULL, &out_fd, &err_fd); +#endif + if (err) + { + gnupg_process_release (proc); + xfree (argv); + FFI_RETURN_ERR (sc, err); + } + + out_string = xtrymalloc (out_len); + if (out_string == NULL) + goto errout; + + err_string = xtrymalloc (err_len); + if (err_string == NULL) + goto errout; + +#ifdef HAVE_W32_SYSTEM + { + HANDLE h_thread_rfp_err; + struct rfp rfp_out; + struct rfp rfp_err; + DWORD thread_exit_code; + + rfp_err.hd = err_hd; + rfp_err.buf = err_string; + rfp_err.len = err_len; + rfp_err.off = 0; + err_hd = INVALID_HANDLE_VALUE; + err_string = NULL; + + h_thread_rfp_err = CreateThread (NULL, 0, read_from_pipe, (void *)&rfp_err, + 0, NULL); + if (h_thread_rfp_err == NULL) + { + xfree (rfp_err.buf); + CloseHandle (rfp_err.hd); + goto errout; + } + + rfp_out.hd = out_hd; + rfp_out.buf = out_string; + rfp_out.len = out_len; + rfp_out.off = 0; + out_hd = INVALID_HANDLE_VALUE; + out_string = NULL; + + if (read_from_pipe (&rfp_out)) + { + CloseHandle (h_thread_rfp_err); + xfree (rfp_err.buf); + goto errout; + } + + out_string = rfp_out.buf; + out_off = rfp_out.off; + + WaitForSingleObject (h_thread_rfp_err, INFINITE); + GetExitCodeThread (h_thread_rfp_err, &thread_exit_code); + CloseHandle (h_thread_rfp_err); + if (thread_exit_code) + goto errout; + + err_string = rfp_err.buf; + err_off = rfp_err.off; + } +#else + { + fd_set read_fdset; + ssize_t bytes_read; + + if (out_fd < 0) + goto errout; + + if (err_fd < 0) + goto errout; + + FD_ZERO (&read_fdset); + + while (1) + { + int nfd; + int ret; + + if (out_fd >= 0) + FD_SET (out_fd, &read_fdset); + + if (err_fd >= 0) + FD_SET (err_fd, &read_fdset); + + if (out_fd > err_fd) + nfd = out_fd; + else + nfd = err_fd; + + if (nfd == -1) + break; + + ret = select (nfd+1, &read_fdset, NULL, NULL, NULL); + if (ret < 0) + break; + + if (FD_ISSET (out_fd, &read_fdset)) + { + bytes_read = read (out_fd, out_string + out_off, + out_len - out_off); + if (bytes_read == 0) + { + close (out_fd); + out_fd = -1; + } + else if (bytes_read < 0) + goto errout; + else + { + out_off += bytes_read; + if (out_off == out_len) + { + out_len += SPAWN_IO_BUFSIZE; + out_string = xtryrealloc (out_string, out_len); + if (out_string == NULL) + goto errout; + } + } + } + + if (FD_ISSET (err_fd, &read_fdset)) + { + bytes_read = read (err_fd, err_string + err_off, + err_len - err_off); + if (bytes_read == 0) + { + close (err_fd); + err_fd = -1; + } + else if (bytes_read < 0) + goto errout; + else + { + err_off += bytes_read; + if (err_off == err_len) + { + err_len += SPAWN_IO_BUFSIZE; + err_string = xtryrealloc (err_string, err_len); + if (err_string == NULL) + goto errout; + } + } + } + } + } +#endif + + err = gnupg_process_wait (proc, 1); + if (!err) + err = gnupg_process_ctl (proc, GNUPG_PROCESS_GET_EXIT_ID, &retcode); + + gnupg_process_release (proc); xfree (argv); -#define IMP(A, B) \ - _cons (sc, proc_wrap (sc, (A)), (B), 1) -#define IMS(A, B) \ - _cons (sc, es_wrap (sc, (A)), (B), 1) - FFI_RETURN_POINTER (sc, IMS (infp, - IMS (outfp, - IMS (errfp, - IMP (proc, sc->NIL))))); -#undef IMS -#undef IMC + + p0 = sc->vptr->mk_integer (sc, (unsigned long)retcode); + p1 = sc->vptr->mk_counted_string (sc, out_string, out_off); + p2 = sc->vptr->mk_counted_string (sc, err_string, err_off); + + xfree (out_string); + xfree (err_string); + + FFI_RETURN_POINTER (sc, _cons (sc, p0, + _cons (sc, p1, + _cons (sc, p2, sc->NIL, 1), 1), 1)); + errout: + xfree (out_string); + xfree (err_string); +#ifdef HAVE_W32_SYSTEM + if (out_hd != INVALID_HANDLE_VALUE) + CloseHandle (out_hd); + if (err_hd != INVALID_HANDLE_VALUE) + CloseHandle (err_hd); +#else + if (out_fd >= 0) + close (out_fd); + if (err_fd >= 0) + close (err_fd); +#endif + gnupg_process_release (proc); + xfree (argv); + FFI_RETURN_ERR (sc, err); } static void @@ -1410,7 +1682,7 @@ ffi_init (scheme *sc, const char *argv0, const char *scriptname, ffi_define_function (sc, pipe); ffi_define_function (sc, inbound_pipe); ffi_define_function (sc, outbound_pipe); - ffi_define_function (sc, process_spawn); + ffi_define_function (sc, process_spawn_io); ffi_define_function (sc, process_spawn_fd); ffi_define_function (sc, process_wait); diff --git a/tests/gpgscm/tests.scm b/tests/gpgscm/tests.scm index 6a11e55f1..1e6d7fea0 100644 --- a/tests/gpgscm/tests.scm +++ b/tests/gpgscm/tests.scm @@ -92,24 +92,16 @@ (define :stdin car) (define :stdout cadr) (define :stderr caddr) -(define :proc cadddr) (define (call-with-io what in) - (let ((h (process-spawn what 0))) - (es-write (:stdin h) in) - (es-fclose (:stdin h)) - (let* ((out (es-read-all (:stdout h))) - (err (es-read-all (:stderr h))) - (result (process-wait (:proc h) #t))) - (es-fclose (:stdout h)) - (es-fclose (:stderr h)) - (if (> (*verbose*) 2) - (info "Child" (:proc h) "returned:" - `((command ,(stringify what)) - (status ,result) - (stdout ,out) - (stderr ,err)))) - (list result out err)))) + (let ((proc-result (process-spawn-io what in))) + (if (> (*verbose*) 2) + (info "Child #proc returned:" + `((command ,(stringify what)) + (status ,(car proc-result)) + (stdout ,(cadr proc-result)) + (stderr ,(caddr proc-result))))) + proc-result)) ;; Accessor function for the results of 'call-with-io'. ':stdout' and ;; ':stderr' can also be used. @@ -128,17 +120,6 @@ (:stdout result) (throw (:stderr result))))) -;; -;; estream helpers. -;; - -(define (es-read-all stream) - (let loop - ((acc "")) - (if (es-feof stream) - acc - (loop (string-append acc (es-read stream 4096)))))) - ;; ;; File management. ;; From 5170c366eec22f164bbb19b999acf5d830f9e2ef Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 9 Jun 2023 11:25:17 +0900 Subject: [PATCH 057/869] common: Update t-exechelp to write/read smaller chunks. * common/t-exechelp.c (run_server): Use syshd. Write with 4K buffer. (test_pipe_stream): Read with 4K buffer. Signed-off-by: NIIBE Yutaka --- common/t-exechelp.c | 65 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/common/t-exechelp.c b/common/t-exechelp.c index 613beb82b..2179ef2a0 100644 --- a/common/t-exechelp.c +++ b/common/t-exechelp.c @@ -172,6 +172,7 @@ test_close_all_fds (void) #endif static char buff12k[1024*12]; +static char buff4k[1024*4]; static void run_server (void) @@ -181,8 +182,19 @@ run_server (void) char *p; unsigned int len; int ret; + es_syshd_t syshd; + size_t n; + off_t o; - fp = es_fdopen_nc (1, "w"); +#ifdef HAVE_W32_SYSTEM + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = (HANDLE)_get_osfhandle (1); +#else + syshd.type = ES_SYSHD_FD; + syshd.u.fd = 1; +#endif + + fp = es_sysopen_nc (&syshd, "w"); if (fp == NULL) { fprintf (stderr, "es_fdopen failed\n"); @@ -206,12 +218,31 @@ run_server (void) exit (1); } - ret = es_write (fp, buff12k, sizeof (buff12k), NULL); - if (ret) + es_fflush (fp); + + o = 0; + n = len; + + while (1) { - fprintf (stderr, "es_write (2) failed\n"); - exit (1); + size_t n0, n1; + + n0 = n > 4096 ? 4096 : n; + memcpy (buff4k, buff12k + o, n0); + + ret = es_write (fp, buff4k, n0, &n1); + if (ret || n0 != n1) + { + fprintf (stderr, "es_write (2) failed\n"); + exit (1); + } + + o += n0; + n -= n0; + if (n == 0) + break; } + es_fclose (fp); exit (0); } @@ -226,6 +257,7 @@ test_pipe_stream (const char *pgmname) const char *argv[2]; unsigned int len; size_t n; + off_t o; int ret; argv[0] = "--server"; @@ -249,10 +281,27 @@ test_pipe_stream (const char *pgmname) fprintf (stderr, "es_read (1) failed\n"); exit (1); } - ret = es_read (outfp, buff12k, sizeof (buff12k), &n); - if (ret || n != sizeof (buff12k)) + + o = 0; + while (1) { - fprintf (stderr, "es_read (2) failed\n"); + if (es_feof (outfp)) + break; + + ret = es_read (outfp, buff4k, sizeof (buff4k), &n); + if (ret) + { + fprintf (stderr, "es_read (2) failed\n"); + exit (1); + } + + memcpy (buff12k + o, buff4k, n); + o += n; + } + + if (o != sizeof (buff12k)) + { + fprintf (stderr, "received data with wrong length %d\n", (int)o); exit (1); } es_fclose (outfp); From 3c57aee2632bc6d686c91901c9247677b68e7c6d Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Wed, 7 Jun 2023 14:43:41 +0200 Subject: [PATCH 058/869] speedo,w32: Call gpgconf --kill all * build-aux/speedo/w32/inst.nsi: Use kill all instead of explicitly killing processes. --- build-aux/speedo/w32/inst.nsi | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build-aux/speedo/w32/inst.nsi b/build-aux/speedo/w32/inst.nsi index 283166835..6c4b84969 100644 --- a/build-aux/speedo/w32/inst.nsi +++ b/build-aux/speedo/w32/inst.nsi @@ -1067,9 +1067,7 @@ Section "-un.gnupglast" nsExec::ExecToLog '"$INSTDIR\bin\launch-gpa" "--stop-server"' no_uiserver: ifFileExists "$INSTDIR\bin\gpgconf.exe" 0 no_gpgconf - nsExec::ExecToLog '"$INSTDIR\bin\gpgconf" "--kill" "gpg-agent"' - nsExec::ExecToLog '"$INSTDIR\bin\gpgconf" "--kill" "dirmngr"' - nsExec::ExecToLog '"$INSTDIR\bin\gpgconf" "--kill" "keyboxd"' + nsExec::ExecToLog '"$INSTDIR\bin\gpgconf" "--kill" "all"' no_gpgconf: SectionEnd From e16fc3e19c3fbef1e22099b40a92dafd832ff05c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 9 Jun 2023 13:46:11 +0200 Subject: [PATCH 059/869] w32: Map ERROR_FILE_INVALID to EIO. * common/sysutils.c (map_w32_to_errno): Add mapping. -- We see this error sometimes when writing to an USB connected disk. --- common/sysutils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/sysutils.c b/common/sysutils.c index ff75b698e..b59d2a961 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -252,6 +252,9 @@ map_w32_to_errno (DWORD w32_err) case ERROR_ALREADY_EXISTS: return EEXIST; + case ERROR_FILE_INVALID: + return EIO; + /* This mapping has been taken from reactOS. */ case ERROR_TOO_MANY_OPEN_FILES: return EMFILE; case ERROR_ARENA_TRASHED: return ENOMEM; From c68dd22872375ab02223e2900ffa3bfe99e8b841 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 9 Jun 2023 16:16:56 +0200 Subject: [PATCH 060/869] gpg: Add --list-filter properties key_expires and key_expires_d. * g10/import.c (impex_filter_getval): Support new filter properties. -- Here is how to list all subkeys expiring in the year 2061: gpg --list-keys --list-filter 'select= sub/key_expires_d -gt 2061-01-01 \ && sub/key_expires_d -lt 2061-12-31' To list all primary key expirations, use the "pub/" prefix and to list all expiration dates use no prefix. GnuPG-bug-id: 6509 --- doc/gpg.texi | 6 ++++++ g10/import.c | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/doc/gpg.texi b/doc/gpg.texi index 6b584a913..61f047cc7 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2671,6 +2671,12 @@ The available properties are: created. The second is the same but given as an ISO string, e.g. "2016-08-17". (drop-subkey) + @item key_expires + @itemx key_expires_d + The expiration time of a public key or subkey or 0 if it does not + expire. The second is the same but given as an ISO date string or + an empty string e.g. "2038-01-19". + @item fpr The hexified fingerprint of the current subkey or primary key. (drop-subkey) diff --git a/g10/import.c b/g10/import.c index 987fef3cd..d84a083cc 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1564,6 +1564,20 @@ impex_filter_getval (void *cookie, const char *propname) { result = dateonlystr_from_pk (pk); } + else if (!strcmp (propname, "key_expires")) + { + snprintf (numbuf, sizeof numbuf, "%lu", (ulong)pk->expiredate); + result = numbuf; + } + else if (!strcmp (propname, "key_expires_d")) + { + static char exdatestr[MK_DATESTR_SIZE]; + + if (pk->expiredate) + result = mk_datestr (exdatestr, sizeof exdatestr, pk->expiredate); + else + result = ""; + } else if (!strcmp (propname, "expired")) { result = pk->has_expired? "1":"0"; From ca3f0e66bcf669181ec0bf50c83130eee2648acc Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 9 Jun 2023 13:46:11 +0200 Subject: [PATCH 061/869] w32: Map ERROR_FILE_INVALID to EIO. * common/sysutils.c (map_w32_to_errno): Add mapping. -- We see this error sometimes when writing to an USB connected disk. --- common/sysutils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/sysutils.c b/common/sysutils.c index 01510ddb0..231565177 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -252,6 +252,9 @@ map_w32_to_errno (DWORD w32_err) case ERROR_ALREADY_EXISTS: return EEXIST; + case ERROR_FILE_INVALID: + return EIO; + /* This mapping has been taken from reactOS. */ case ERROR_TOO_MANY_OPEN_FILES: return EMFILE; case ERROR_ARENA_TRASHED: return ENOMEM; From 64509134d47a13c87481e39895cd58ea77eec61a Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Wed, 7 Jun 2023 14:43:41 +0200 Subject: [PATCH 062/869] speedo,w32: Call gpgconf --kill all * build-aux/speedo/w32/inst.nsi: Use kill all instead of explicitly killing processes. --- build-aux/speedo/w32/inst.nsi | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build-aux/speedo/w32/inst.nsi b/build-aux/speedo/w32/inst.nsi index 283166835..6c4b84969 100644 --- a/build-aux/speedo/w32/inst.nsi +++ b/build-aux/speedo/w32/inst.nsi @@ -1067,9 +1067,7 @@ Section "-un.gnupglast" nsExec::ExecToLog '"$INSTDIR\bin\launch-gpa" "--stop-server"' no_uiserver: ifFileExists "$INSTDIR\bin\gpgconf.exe" 0 no_gpgconf - nsExec::ExecToLog '"$INSTDIR\bin\gpgconf" "--kill" "gpg-agent"' - nsExec::ExecToLog '"$INSTDIR\bin\gpgconf" "--kill" "dirmngr"' - nsExec::ExecToLog '"$INSTDIR\bin\gpgconf" "--kill" "keyboxd"' + nsExec::ExecToLog '"$INSTDIR\bin\gpgconf" "--kill" "all"' no_gpgconf: SectionEnd From 695cb04af5218cd7b42c7eaaefc186472b99a995 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 9 Jun 2023 17:40:53 +0200 Subject: [PATCH 063/869] gpg: Print status line and proper diagnostics for write errors. * common/iobuf.c (file_filter): Improve diagnostics. * g10/build-packet.c (do_plaintext): Make sure to cache all error cases. -- GnuPG-bug-id: 6528 --- common/iobuf.c | 9 ++++++--- g10/build-packet.c | 14 +++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index 825b97704..dee3b46b1 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -503,7 +503,8 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, if (ec != ERROR_BROKEN_PIPE) { rc = gpg_error_from_errno (ec); - log_error ("%s: read error: ec=%d\n", a->fname, ec); + log_error ("%s: read error: %s (ec=%d)\n", + a->fname, gpg_strerror (rc), ec); } } else if (!nread) @@ -573,7 +574,8 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, { int ec = (int) GetLastError (); rc = gpg_error_from_errno (ec); - log_error ("%s: write error: ec=%d\n", a->fname, ec); + log_error ("%s: write error: %s (ec=%d)\n", + a->fname, gpg_strerror (rc), ec); break; } p += n; @@ -632,7 +634,8 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, if (ec != ERROR_BROKEN_PIPE) { rc = gpg_error_from_errno (ec); - log_error ("%s: read error: ec=%d\n", a->fname, ec); + log_error ("%s: read error: %s (ec=%d)\n", + a->fname, gpg_strerror (rc), ec); } a->npeeked = 0; } diff --git a/g10/build-packet.c b/g10/build-packet.c index 192dfaef5..67d4a6eef 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -991,12 +991,20 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) if (nbytes == (size_t)(-1) && (iobuf_error (out) || iobuf_error (pt->buf))) return iobuf_error (out)? iobuf_error (out):iobuf_error (pt->buf); + /* Always get the error to catch write errors because + * iobuf_copy does not reliable return (-1) in that case. */ + rc = iobuf_error (out); if(ctb_new_format_p (ctb) && !pt->len) /* Turn off partial body length mode. */ iobuf_set_partial_body_length_mode (out, 0); - if( pt->len && nbytes != pt->len ) - log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n", - (ulong)nbytes, (ulong)pt->len ); + if (pt->len && nbytes != pt->len) + { + log_error ("do_plaintext(): wrote %lu bytes" + " but expected %lu bytes\n", + (ulong)nbytes, (ulong)pt->len ); + if (!rc) /* Just in case no error was set */ + rc = gpg_error (GPG_ERR_EIO); + } } return rc; From 808494b48577c2efb894a0877f59d9c4ed664f56 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 13 Jun 2023 10:07:07 +0200 Subject: [PATCH 064/869] gpg: Make progress work for large files on Windows. * common/iobuf.c (iobuf_get_filelength): Change return type to uint64_t and remove the overflow args. For Windows always use GetFileSizeEx which is available since the long EOL-ed Windows XP. * g10/sign.c (write_plaintext_packet): Adjust for changed iobuf_get_filelength. * g10/encrypt.c (encrypt_simple, encrypt_crypt): Ditto. * g10/photoid.c (generate_photo_id): Ditto. Also add an upper limit. * g10/filter.h (progress_filter_context_t): Change amount values to use uint64_t. * g10/progress.c (write_status_progress): Change accordingly. -- GnuPG-bug-id: 6534 --- common/iobuf.c | 61 +++++++++----------------------------------------- common/iobuf.h | 8 ++----- g10/encrypt.c | 15 ++++++------- g10/filter.h | 6 ++--- g10/gpg.c | 8 ++++++- g10/photoid.c | 18 ++++++++++----- g10/progress.c | 15 +++++++------ g10/sign.c | 7 +++--- 8 files changed, 52 insertions(+), 86 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index dee3b46b1..627d33900 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2608,13 +2608,10 @@ iobuf_set_limit (iobuf_t a, off_t nlimit) } - -off_t -iobuf_get_filelength (iobuf_t a, int *overflow) +/* Return the length of the file behind A. If there is no file, return 0. */ +uint64_t +iobuf_get_filelength (iobuf_t a) { - if (overflow) - *overflow = 0; - /* Hmmm: file_filter may have already been removed */ for ( ; a->chain; a = a->chain ) ; @@ -2627,56 +2624,18 @@ iobuf_get_filelength (iobuf_t a, int *overflow) gnupg_fd_t fp = b->fp; #if defined(HAVE_W32_SYSTEM) - ulong size; - static int (* __stdcall get_file_size_ex) (void *handle, - LARGE_INTEGER *r_size); - static int get_file_size_ex_initialized; + LARGE_INTEGER exsize; - if (!get_file_size_ex_initialized) - { - void *handle; - - handle = dlopen ("kernel32.dll", RTLD_LAZY); - if (handle) - { - get_file_size_ex = dlsym (handle, "GetFileSizeEx"); - if (!get_file_size_ex) - dlclose (handle); - } - get_file_size_ex_initialized = 1; - } - - if (get_file_size_ex) - { - /* This is a newer system with GetFileSizeEx; we use this - then because it seem that GetFileSize won't return a - proper error in case a file is larger than 4GB. */ - LARGE_INTEGER exsize; - - if (get_file_size_ex (fp, &exsize)) - { - if (!exsize.u.HighPart) - return exsize.u.LowPart; - if (overflow) - *overflow = 1; - return 0; - } - } - else - { - if ((size=GetFileSize (fp, NULL)) != 0xffffffff) - return size; - } + if (GetFileSizeEx (fp, &exsize)) + return exsize.QuadPart; log_error ("GetFileSize for handle %p failed: %s\n", fp, w32_strerror (-1)); #else /*!HAVE_W32_SYSTEM*/ - { - struct stat st; + struct stat st; - if ( !fstat (fp, &st) ) - return st.st_size; - log_error("fstat() failed: %s\n", strerror(errno) ); - } + if ( !fstat (fp, &st) ) + return st.st_size; + log_error("fstat() failed: %s\n", strerror(errno) ); #endif /*!HAVE_W32_SYSTEM*/ } diff --git a/common/iobuf.h b/common/iobuf.h index c132c2f3c..751ae73c3 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -584,12 +584,8 @@ size_t iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen); size_t iobuf_copy (iobuf_t dest, iobuf_t source); /* Return the size of any underlying file. This only works with - file_filter based pipelines. - - On Win32, it is sometimes not possible to determine the size of - files larger than 4GB. In this case, *OVERFLOW (if not NULL) is - set to 1. Otherwise, *OVERFLOW is set to 0. */ -off_t iobuf_get_filelength (iobuf_t a, int *overflow); + file_filter based pipelines. */ +uint64_t iobuf_get_filelength (iobuf_t a); #define IOBUF_FILELENGTH_LIMIT 0xffffffff /* Return the file descriptor designating the underlying file. This diff --git a/g10/encrypt.c b/g10/encrypt.c index ff1c6be85..9aeafa292 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -580,12 +580,12 @@ encrypt_simple (const char *filename, int mode, int use_seskey) if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) { - off_t tmpsize; - int overflow; + uint64_t tmpsize; - if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow && opt.verbose) + tmpsize = iobuf_get_filelength(inp); + if (!tmpsize && opt.verbose) log_info(_("WARNING: '%s' is an empty file\n"), filename ); + /* We can't encode the length of very large files because OpenPGP uses only 32 bit for file sizes. So if the size of a file is larger than 2^32 minus some bytes for @@ -942,11 +942,10 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, if (filename && *filename && !iobuf_is_pipe_filename (filename) && !opt.textmode ) { - off_t tmpsize; - int overflow; + uint64_t tmpsize; - if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) - && !overflow && opt.verbose) + tmpsize = iobuf_get_filelength (inp); + if (!tmpsize && opt.verbose) log_info(_("WARNING: '%s' is an empty file\n"), filename ); /* We can't encode the length of very large files because OpenPGP uses only 32 bit for file sizes. So if the size diff --git a/g10/filter.h b/g10/filter.h index 46342d2ad..4b4fc55ff 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -155,9 +155,9 @@ typedef struct { typedef struct { char *what; /* description */ u32 last_time; /* last time reported */ - unsigned long last; /* last amount reported */ - unsigned long offset; /* current amount */ - unsigned long total; /* total amount */ + uint64_t last; /* last amount reported */ + uint64_t offset; /* current amount */ + uint64_t total; /* total amount */ int refcount; } progress_filter_context_t; diff --git a/g10/gpg.c b/g10/gpg.c index 6e54aa763..39776c3d1 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3499,7 +3499,13 @@ main (int argc, char **argv) case oAllowFreeformUID: opt.allow_freeform_uid = 1; break; case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break; case oNoLiteral: opt.no_literal = 1; break; - case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break; + + case oSetFilesize: + /* There are restricts on the value (e.g. < 2^32); you + * need to check the entire code to understand this. */ + opt.set_filesize = pargs.r.ret_ulong; + break; + case oFastListMode: opt.fast_list_mode = 1; break; case oFixedListMode: /* Dummy */ break; case oLegacyListMode: opt.legacy_list_mode = 1; break; diff --git a/g10/photoid.c b/g10/photoid.c index 72e6acf7d..fc8866121 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -160,12 +160,11 @@ generate_photo_id (ctrl_t ctrl, PKT_public_key *pk,const char *photo_name) { PKT_user_id *uid; int error=1,i; - unsigned int len; + uint64_t len; char *filename; byte *photo=NULL; byte header[16]; IOBUF file; - int overflow; header[0]=0x10; /* little side of photo header length */ header[1]=0; /* big side of photo header length */ @@ -233,11 +232,18 @@ generate_photo_id (ctrl_t ctrl, PKT_public_key *pk,const char *photo_name) } - len=iobuf_get_filelength(file, &overflow); - if(len>6144 || overflow) + len = iobuf_get_filelength(file); + if(len>6144) { - tty_printf( _("This JPEG is really large (%d bytes) !\n"),len); - if(!cpr_get_answer_is_yes("photoid.jpeg.size", + /* We silently skip JPEGs larger than 1MiB because we have a + * 2MiB limit on the user ID packets and we need some limit + * anyway because the returned u64 is larger than the u32 or + * OpenPGP. Note that the diagnostic may print a wrong + * value if the value is really large; we don't fix this to + * avoid a string change. */ + tty_printf( _("This JPEG is really large (%d bytes) !\n"), (int)len); + if(len > 1024*1024 + || !cpr_get_answer_is_yes("photoid.jpeg.size", _("Are you sure you want to use it? (y/N) "))) { iobuf_close(file); diff --git a/g10/progress.c b/g10/progress.c index 7e777d4ab..7ee8b1e04 100644 --- a/g10/progress.c +++ b/g10/progress.c @@ -72,13 +72,11 @@ release_progress_context (progress_filter_context_t *pfx) static void -write_status_progress (const char *what, - unsigned long current, unsigned long total_arg) +write_status_progress (const char *what, uint64_t current, uint64_t total) { char buffer[60]; char units[] = "BKMGTPEZY?"; int unitidx = 0; - uint64_t total = total_arg; /* Although we use an unsigned long for the values, 32 bit * applications using GPGME will use an "int" and thus are limited @@ -91,7 +89,10 @@ write_status_progress (const char *what, * to display how many percent of the operation has been done and * thus scaling CURRENT and TOTAL down before they get to large, * should not have a noticeable effect except for rounding - * imprecision. */ + * imprecision. + * Update 2023-06-13: We now use uint64_t but to keep the API stable + * we still do the scaling. + */ if (!total && opt.input_size_hint) total = opt.input_size_hint; @@ -121,7 +122,7 @@ write_status_progress (const char *what, unitidx = 9; snprintf (buffer, sizeof buffer, "%.20s ? %lu %lu %c%s", - what? what : "?", current, (unsigned long)total, + what? what : "?", (unsigned long)current, (unsigned long)total, units[unitidx], unitidx? "iB" : ""); write_status_text (STATUS_PROGRESS, buffer); @@ -181,7 +182,7 @@ progress_filter (void *opaque, int control, void handle_progress (progress_filter_context_t *pfx, IOBUF inp, const char *name) { - off_t filesize = 0; + uint64_t filesize = 0; if (!pfx) return; @@ -190,7 +191,7 @@ handle_progress (progress_filter_context_t *pfx, IOBUF inp, const char *name) log_assert (is_status_enabled ()); if ( !iobuf_is_pipe_filename (name) && *name ) - filesize = iobuf_get_filelength (inp, NULL); + filesize = iobuf_get_filelength (inp); else if (opt.set_filesize) filesize = opt.set_filesize; diff --git a/g10/sign.c b/g10/sign.c index b5e9d422d..f9984f811 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -823,11 +823,10 @@ write_plaintext_packet (iobuf_t out, iobuf_t inp, /* Try to calculate the length of the data. */ if ( !iobuf_is_pipe_filename (fname) && *fname) { - off_t tmpsize; - int overflow; + uint64_t tmpsize; - if (!(tmpsize = iobuf_get_filelength (inp, &overflow)) - && !overflow && opt.verbose) + tmpsize = iobuf_get_filelength (inp); + if (!tmpsize && opt.verbose) log_info (_("WARNING: '%s' is an empty file\n"), fname); /* We can't encode the length of very large files because From c58067415fe93fbd5d3de2594ccca4761ad25103 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Jun 2023 10:37:07 +0200 Subject: [PATCH 065/869] gpgsm: Print PROGRESS status lines. * common/ksba-io-support.c (struct writer_cb_parm_s): Add field progress. (struct gnupg_ksba_io_s): Add field is_writer. (update_write_progress): New. (base64_writer_cb, plain_writer_cb): Call update_write_progress. (base64_finish_write): Ditto. (gnupg_ksba_create_writer): Set is_writer. (gnupg_ksba_set_progress_cb): New. (gnupg_ksba_set_total): New. * common/ksba-io-support.h (gnupg_ksba_progress_cb_t): New type. * sm/server.c (gpgsm_status2): Return error from statusfp writes. (gpgsm_progress_cb): New. * sm/decrypt.c (gpgsm_decrypt): Set progress handler. * sm/encrypt.c (gpgsm_encrypt): Ditto. * sm/sign.c (gpgsm_sign): Ditto. * sm/verify.c (gpgsm_verify): Ditto. -- GnuPG-bug-id: 6534 --- common/ksba-io-support.c | 98 +++++++++++++++++++++++++++++++++++++--- common/ksba-io-support.h | 10 +++- sm/decrypt.c | 2 + sm/encrypt.c | 4 +- sm/gpgsm.h | 1 + sm/server.c | 56 ++++++++++++++++++++++- sm/sign.c | 4 +- sm/verify.c | 2 + 8 files changed, 167 insertions(+), 10 deletions(-) diff --git a/common/ksba-io-support.c b/common/ksba-io-support.c index a279b67ad..352485ffa 100644 --- a/common/ksba-io-support.c +++ b/common/ksba-io-support.c @@ -1,6 +1,6 @@ /* kska-io-support.c - Supporting functions for ksba reader and writer * Copyright (C) 2001-2005, 2007, 2010-2011, 2017 Werner Koch - * Copyright (C) 2006 g10 Code GmbH + * Copyright (C) 2006, 2023 g10 Code GmbH * * This file is part of GnuPG. * @@ -26,6 +26,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . + * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later) */ #include @@ -96,6 +97,15 @@ struct writer_cb_parm_s char *pem_name; /* Malloced. */ + struct { + gnupg_ksba_progress_cb_t cb; + ctrl_t ctrl; + u32 last_time; /* last time reported */ + uint64_t last; /* last amount reported */ + uint64_t current; /* current amount */ + uint64_t total; /* total amount */ + } progress; + int wrote_begin; int did_finish; @@ -110,6 +120,7 @@ struct writer_cb_parm_s /* Context for this module's functions. */ struct gnupg_ksba_io_s { + int is_writer; /* True if this context refers a writer object. */ union { struct reader_cb_parm_s rparm; struct writer_cb_parm_s wparm; @@ -527,6 +538,33 @@ simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) +/* Call the progress callback if its time. We do this very 2 seconds + * or if FORCE is set. However, we also require that at least 64KiB + * have been written to avoid unnecessary progress lines for small + * files. */ +static gpg_error_t +update_write_progress (struct writer_cb_parm_s *parm, size_t count, int force) +{ + gpg_error_t err = 0; + u32 timestamp; + + parm->progress.current += count; + if (parm->progress.current >= (64*1024)) + { + timestamp = make_timestamp (); + if (force || (timestamp - parm->progress.last_time > 1)) + { + parm->progress.last = parm->progress.current; + parm->progress.last_time = timestamp; + err = parm->progress.cb (parm->progress.ctrl, + parm->progress.current, + parm->progress.total); + } + } + return err; +} + + static int base64_writer_cb (void *cb_value, const void *buffer, size_t count) { @@ -535,6 +573,8 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count) int i, c, idx, quad_count; const unsigned char *p; estream_t stream = parm->stream; + int rc; + size_t nleft; if (!count) return 0; @@ -557,7 +597,7 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count) for (i=0; i < idx; i++) radbuf[i] = parm->base64.radbuf[i]; - for (p=buffer; count; p++, count--) + for (p=buffer, nleft = count; nleft; p++, nleft--) { radbuf[idx++] = *p; if (idx > 2) @@ -583,7 +623,11 @@ base64_writer_cb (void *cb_value, const void *buffer, size_t count) parm->base64.idx = idx; parm->base64.quad_count = quad_count; - return es_ferror (stream)? gpg_error_from_syserror () : 0; + rc = es_ferror (stream)? gpg_error_from_syserror () : 0; + /* Note that we use the unencoded count for the progress. */ + if (!rc && parm->progress.cb) + rc = update_write_progress (parm, count, 0); + return rc; } @@ -594,13 +638,16 @@ plain_writer_cb (void *cb_value, const void *buffer, size_t count) { struct writer_cb_parm_s *parm = cb_value; estream_t stream = parm->stream; + int rc; if (!count) return 0; es_write (stream, buffer, count, NULL); - - return es_ferror (stream)? gpg_error_from_syserror () : 0; + rc = es_ferror (stream)? gpg_error_from_syserror () : 0; + if (!rc && parm->progress.cb) + rc = update_write_progress (parm, count, 0); + return rc; } @@ -610,6 +657,7 @@ base64_finish_write (struct writer_cb_parm_s *parm) unsigned char *radbuf; int c, idx, quad_count; estream_t stream = parm->stream; + int rc; if (!parm->wrote_begin) return 0; /* Nothing written or we are not called in base-64 mode. */ @@ -656,7 +704,10 @@ base64_finish_write (struct writer_cb_parm_s *parm) es_fputs ("-----\n", stream); } - return es_ferror (stream)? gpg_error_from_syserror () : 0; + rc = es_ferror (stream)? gpg_error_from_syserror () : 0; + if (!rc && parm->progress.cb) + rc = update_write_progress (parm, 0, 1); + return rc; } @@ -788,6 +839,7 @@ gnupg_ksba_create_writer (gnupg_ksba_io_t *ctx, unsigned int flags, *ctx = xtrycalloc (1, sizeof **ctx); if (!*ctx) return gpg_error_from_syserror (); + (*ctx)->is_writer = 1; rc = ksba_writer_new (&w); if (rc) @@ -865,3 +917,37 @@ gnupg_ksba_destroy_writer (gnupg_ksba_io_t ctx) xfree (ctx->u.wparm.pem_name); xfree (ctx); } + + +/* Set a callback to the writer object. CTRL will be bassed to the + * callback. */ +void +gnupg_ksba_set_progress_cb (gnupg_ksba_io_t ctx, + gnupg_ksba_progress_cb_t cb, ctrl_t ctrl) +{ + struct writer_cb_parm_s *parm; + + if (!ctx || !ctx->is_writer) + return; /* Currently only supported for writer objects. */ + parm = &ctx->u.wparm; + + parm->progress.cb = cb; + parm->progress.ctrl = ctrl; + parm->progress.last_time = 0; + parm->progress.last = 0; + parm->progress.current = 0; + parm->progress.total = 0; +} + + +/* Update the total count for the progress thingy. */ +void +gnupg_ksba_set_total (gnupg_ksba_io_t ctx, uint64_t total) +{ + struct writer_cb_parm_s *parm; + + if (!ctx || !ctx->is_writer) + return; /* Currently only supported for writer objects. */ + parm = &ctx->u.wparm; + parm->progress.total = total; +} diff --git a/common/ksba-io-support.h b/common/ksba-io-support.h index 02e541b16..1dbc303c8 100644 --- a/common/ksba-io-support.h +++ b/common/ksba-io-support.h @@ -25,6 +25,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . + * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later) */ #ifndef GNUPG_KSBA_IO_SUPPORT_H @@ -42,6 +43,10 @@ /* Context object. */ typedef struct gnupg_ksba_io_s *gnupg_ksba_io_t; +/* Progress callback type. */ +typedef gpg_error_t (*gnupg_ksba_progress_cb_t)(ctrl_t ctrl, + uint64_t current, + uint64_t total); gpg_error_t gnupg_ksba_create_reader (gnupg_ksba_io_t *ctx, @@ -57,10 +62,13 @@ gpg_error_t gnupg_ksba_create_writer (gnupg_ksba_io_t *ctx, const char *pem_name, estream_t stream, ksba_writer_t *r_writer); - gpg_error_t gnupg_ksba_finish_writer (gnupg_ksba_io_t ctx); void gnupg_ksba_destroy_writer (gnupg_ksba_io_t ctx); +void gnupg_ksba_set_progress_cb (gnupg_ksba_io_t ctx, + gnupg_ksba_progress_cb_t cb, ctrl_t ctrl); +void gnupg_ksba_set_total (gnupg_ksba_io_t ctx, uint64_t total); + diff --git a/sm/decrypt.c b/sm/decrypt.c index 68b362b45..abc1f2602 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -1107,6 +1107,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) goto leave; } + gnupg_ksba_set_progress_cb (b64writer, gpgsm_progress_cb, ctrl); + rc = ksba_cms_new (&cms); if (rc) goto leave; diff --git a/sm/encrypt.c b/sm/encrypt.c index 4fd4f93b9..b0e59f73e 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -653,6 +653,8 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) goto leave; } + gnupg_ksba_set_progress_cb (b64writer, gpgsm_progress_cb, ctrl); + err = ksba_cms_new (&cms); if (err) { @@ -828,7 +830,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) err = ksba_cms_build (cms, &stopreason); if (err) { - log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err)); + log_error ("creating CMS object failed: %s\n", gpg_strerror (err)); rc = err; goto leave; } diff --git a/sm/gpgsm.h b/sm/gpgsm.h index cef39ff2a..46c77803d 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -316,6 +316,7 @@ gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, gpg_err_code_t ec); gpg_error_t gpgsm_status_with_error (ctrl_t ctrl, int no, const char *text, gpg_error_t err); +gpg_error_t gpgsm_progress_cb (ctrl_t ctrl, uint64_t current, uint64_t total); gpg_error_t gpgsm_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line); diff --git a/sm/server.c b/sm/server.c index 3ec1c0c4b..455f5707a 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1506,7 +1506,14 @@ gpgsm_status2 (ctrl_t ctrl, int no, ...) } } putc ('\n', statusfp); - fflush (statusfp); + if (ferror (statusfp)) + err = gpg_error_from_syserror (); + else + { + fflush (statusfp); + if (ferror (statusfp)) + err = gpg_error_from_syserror (); + } } else { @@ -1551,6 +1558,53 @@ gpgsm_status_with_error (ctrl_t ctrl, int no, const char *text, } +/* This callback is used to emit progress status lines. */ +gpg_error_t +gpgsm_progress_cb (ctrl_t ctrl, uint64_t current, uint64_t total) +{ + char buffer[60]; + char units[] = "BKMGTPEZY?"; + int unitidx = 0; + + if (current > 1024*1024*20) + { + static int closed; + if (closed) + close (5); + closed = 1; + } + + if (total) + { + if (total > current) + current = total; + + while (total > 1024*1024) + { + total /= 1024; + current /= 1024; + unitidx++; + } + } + else + { + while (current > 1024*1024) + { + current /= 1024; + unitidx++; + } + } + + if (unitidx > 9) + unitidx = 9; + + snprintf (buffer, sizeof buffer, "? %lu %lu %c%s", + (unsigned long)current, (unsigned long)total, + units[unitidx], unitidx? "iB" : ""); + return gpgsm_status2 (ctrl, STATUS_PROGRESS, "?", buffer, NULL); +} + + /* Helper to notify the client about Pinentry events. Because that might disturb some older clients, this is only done when enabled via an option. Returns an gpg error code. */ diff --git a/sm/sign.c b/sm/sign.c index b3b7e1883..4f5e8e3a0 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -687,6 +687,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, goto leave; } + gnupg_ksba_set_progress_cb (b64writer, gpgsm_progress_cb, ctrl); + err = ksba_cms_new (&cms); if (err) { @@ -1027,7 +1029,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, err = ksba_cms_build (cms, &stopreason); if (err) { - log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err)); + log_error ("creating CMS object failed: %s\n", gpg_strerror (err)); rc = err; goto leave; } diff --git a/sm/verify.c b/sm/verify.c index a07d1c9c7..9125b2b06 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -158,6 +158,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) } } + gnupg_ksba_set_progress_cb (b64writer, gpgsm_progress_cb, ctrl); + rc = ksba_cms_new (&cms); if (rc) goto leave; From a88aeee12990478c218abff7f38728e47ee824bc Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Jun 2023 12:20:11 +0200 Subject: [PATCH 066/869] gpgsm: Fix last commit -- There was some test code left over and a check reversed. --- sm/server.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/sm/server.c b/sm/server.c index 455f5707a..1510590a7 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1566,17 +1566,9 @@ gpgsm_progress_cb (ctrl_t ctrl, uint64_t current, uint64_t total) char units[] = "BKMGTPEZY?"; int unitidx = 0; - if (current > 1024*1024*20) - { - static int closed; - if (closed) - close (5); - closed = 1; - } - if (total) { - if (total > current) + if (current > total) current = total; while (total > 1024*1024) From e9c337c0b94b0db4c1bf8ce668477ff7675c0199 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Jun 2023 12:28:55 +0200 Subject: [PATCH 067/869] gpgsm: New option --input-size-hint. * sm/gpgsm.c (oInputSizeHint): New. (opts): Add "--input-size-hint". (main): Set option. * sm/server.c (option_handler): Add option "input-size-hint". * sm/gpgsm.h (struct server_control_s): Add field input_size_hint. * sm/encrypt.c (gpgsm_encrypt): Set the toatl file size. * sm/decrypt.c (gpgsm_decrypt): Ditto. * sm/sign.c (gpgsm_sign): Ditto. * sm/verify.c (gpgsm_verify): Ditto. -- This option allows to set a value for the progress output line. Note that as of now there is no other way to set the file size. GnuPG-bug-id: 6534 --- doc/gpgsm.texi | 10 ++++++++++ sm/decrypt.c | 2 ++ sm/encrypt.c | 2 ++ sm/gpgsm.c | 6 ++++++ sm/gpgsm.h | 5 +++++ sm/server.c | 4 ++++ sm/sign.c | 2 ++ sm/verify.c | 2 ++ 8 files changed, 33 insertions(+) diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 11c5c1962..e976767f6 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -554,6 +554,13 @@ Assume the input data is plain base-64 encoded. @opindex assume-binary Assume the input data is binary encoded. +@item --input-size-hint @var{n} +@opindex input-size-hint +This option can be used to tell GPGSM the size of the input data in +bytes. @var{n} must be a positive base-10 number. It is used by the +@option{--status-fd} line ``PROGRESS'' to provide a value for +``total'' if that is not available by other means. + @anchor{option --p12-charset} @item --p12-charset @var{name} @opindex p12-charset @@ -1721,6 +1728,9 @@ If @var{value} is true or @var{value} is not given all network access is disabled for this session. This is the same as the command line option @option{--disable-dirmngr}. +@item input-size-hint +This is the same as the @option{--input-size-hint} command line option. + @end table @mansect see also diff --git a/sm/decrypt.c b/sm/decrypt.c index abc1f2602..62983fe9c 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -1108,6 +1108,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) } gnupg_ksba_set_progress_cb (b64writer, gpgsm_progress_cb, ctrl); + if (ctrl->input_size_hint) + gnupg_ksba_set_total (b64writer, ctrl->input_size_hint); rc = ksba_cms_new (&cms); if (rc) diff --git a/sm/encrypt.c b/sm/encrypt.c index b0e59f73e..6e78a0620 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -654,6 +654,8 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) } gnupg_ksba_set_progress_cb (b64writer, gpgsm_progress_cb, ctrl); + if (ctrl->input_size_hint) + gnupg_ksba_set_total (b64writer, ctrl->input_size_hint); err = ksba_cms_new (&cms); if (err) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 07c3ff480..ad7652c7d 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -139,6 +139,7 @@ enum cmd_and_opt_values { oAssumeArmor, oAssumeBase64, oAssumeBinary, + oInputSizeHint, oBase64, oNoArmor, @@ -326,6 +327,7 @@ static gpgrt_opt_t opts[] = { N_("assume input is in base-64 format")), ARGPARSE_s_n (oAssumeBinary, "assume-binary", N_("assume input is in binary format")), + ARGPARSE_s_s (oInputSizeHint, "input-size-hint", "@"), ARGPARSE_header ("Output", N_("Options controlling the output")), @@ -1188,6 +1190,10 @@ main ( int argc, char **argv) ctrl.is_base64 = 0; break; + case oInputSizeHint: + ctrl.input_size_hint = string_to_u64 (pargs.r.ret_str); + break; + case oDisableCRLChecks: opt.no_crl_check = 1; break; diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 46c77803d..e1aca8bb7 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -250,6 +250,11 @@ struct server_control_s int is_pem; /* Is in PEM format */ int is_base64; /* is in plain base-64 format */ + /* If > 0 a hint with the expected number of input data bytes. This + * is not necessary an exact number but intended to be used for + * progress info and to decide on how to allocate buffers. */ + uint64_t input_size_hint; + int create_base64; /* Create base64 encoded output */ int create_pem; /* create PEM output */ const char *pem_name; /* PEM name to use */ diff --git a/sm/server.c b/sm/server.c index 1510590a7..b545c1bfb 100644 --- a/sm/server.c +++ b/sm/server.c @@ -298,6 +298,10 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) opt.request_origin = i; } } + else if (!strcmp (key, "input-size-hint")) + { + ctrl->input_size_hint = string_to_u64 (value); + } else err = gpg_error (GPG_ERR_UNKNOWN_OPTION); diff --git a/sm/sign.c b/sm/sign.c index 4f5e8e3a0..235dac8cb 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -688,6 +688,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, } gnupg_ksba_set_progress_cb (b64writer, gpgsm_progress_cb, ctrl); + if (ctrl->input_size_hint) + gnupg_ksba_set_total (b64writer, ctrl->input_size_hint); err = ksba_cms_new (&cms); if (err) diff --git a/sm/verify.c b/sm/verify.c index 9125b2b06..c7f4492ce 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -159,6 +159,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) } gnupg_ksba_set_progress_cb (b64writer, gpgsm_progress_cb, ctrl); + if (ctrl->input_size_hint) + gnupg_ksba_set_total (b64writer, ctrl->input_size_hint); rc = ksba_cms_new (&cms); if (rc) From 2178f35dffdc0d0129ad1da2e34ba243d7869378 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Jun 2023 13:58:35 +0200 Subject: [PATCH 068/869] gpg: New option --no-compress as alias for -z0. --- doc/gpg.texi | 19 ++++++++++++------- g10/gpg.c | 7 +++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 61f047cc7..15b3243d0 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1675,24 +1675,29 @@ prevent the creation of a @file{~/.gnupg} homedir. @item -z @var{n} @itemx --compress-level @var{n} @itemx --bzip2-compress-level @var{n} +@itemx --no-compress @opindex compress-level @opindex bzip2-compress-level +@opindex no-compress Set compression level to @var{n} for the ZIP and ZLIB compression algorithms. The default is to use the default compression level of zlib (normally 6). @option{--bzip2-compress-level} sets the compression level for the BZIP2 compression algorithm (defaulting to 6 as well). This is a different option from @option{--compress-level} since BZIP2 uses a significant amount of memory for each additional compression level. -@option{-z} sets both. A value of 0 for @var{n} disables compression. -A value of -1 forces compression using the default level. + +Option @option{-z} sets both. A value of 0 for @var{n} disables +compression. A value of -1 forces compression using the default +level. Option @option{--no-compress} is identical to @option{-z0}. Except for the @option{--store} command compression is always used unless @command{gpg} detects that the input is already compressed. To -inhibit the use of compression use @option{-z0}; to force compression -use @option{-z-1} or option @option{z} with another compression level -than the default as indicated by -1. Note that this overriding of the -default deection works only with @option{z} and not with the long -variant of this option. +inhibit the use of compression use @option{-z0} or +@option{--no-compress}; to force compression use @option{-z-1} or +option @option{z} with another compression level than the default as +indicated by -1. Note that this overriding of the default deection +works only with @option{z} and not with the long variant of this +option. @item --bzip2-decompress-lowmem diff --git a/g10/gpg.c b/g10/gpg.c index 39776c3d1..2ae3750a9 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -259,6 +259,7 @@ enum cmd_and_opt_values oCipherAlgo, oDigestAlgo, oCertDigestAlgo, + oNoCompress, oCompressAlgo, oCompressLevel, oBZ2CompressLevel, @@ -697,6 +698,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oLockOnce, "lock-once", "@"), ARGPARSE_s_n (oLockMultiple, "lock-multiple", "@"), ARGPARSE_s_n (oLockNever, "lock-never", "@"), + ARGPARSE_s_n (oNoCompress, "no-compress", "@"), ARGPARSE_s_s (oCompressAlgo,"compress-algo", "@"), ARGPARSE_s_s (oCompressAlgo, "compression-algo", "@"), /* Alias */ ARGPARSE_s_n (oBZ2DecompressLowmem, "bzip2-decompress-lowmem", "@"), @@ -3238,6 +3240,11 @@ main (int argc, char **argv) opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int; opt.explicit_compress_option = 1; break; + case oNoCompress: + /* --no-compress is the same as -z0 */ + opt.compress_level = opt.bz2_compress_level = 0; + opt.explicit_compress_option = 1; + break; case oCompressLevel: opt.compress_level = pargs.r.ret_int; break; case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break; case oBZ2DecompressLowmem: opt.bz2_decompress_lowmem=1; break; From 3bab25d7d5197cd6178be653feb1182cd313ecbe Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Jun 2023 13:52:18 +0200 Subject: [PATCH 069/869] gpgtar: New option --no-compress. * tools/gpgtar.c: Add option --no-compress. * tools/gpgtar.h (opt): Add field no_compress. * tools/gpgtar-create.c (gpgtar_create): Pass -z0 to gpg. -- This option is probably easier to remember than --gpg-args '-z0'. --- doc/tools.texi | 6 ++++++ tools/gpgtar-create.c | 2 ++ tools/gpgtar.c | 3 +++ tools/gpgtar.h | 1 + 4 files changed, 12 insertions(+) diff --git a/doc/tools.texi b/doc/tools.texi index 5fa21c66a..eefa4f9d6 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -2049,6 +2049,12 @@ default is to take the directory name from the input filename. If no input filename is known a directory named @file{GPGARCH} is used. This option is deprecated in favor of option @option{--directory}. +@item --no-compress +@opindex no-compress +This option tells gpg to disable compression (i.e. using option -z0). +It is useful for archiving only large files which are are already +compressed (e.g. a set of videos). + @item --gpg @var{gpgcmd} @opindex gpg Use the specified command @var{gpgcmd} instead of @command{gpg}. diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index 26d37a332..0994322ea 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -1273,6 +1273,8 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, ccparray_put (&ccp, "--recipient"); ccparray_put (&ccp, arg->d); } + if (opt.no_compress) + ccparray_put (&ccp, "-z0"); for (arg = opt.gpg_arguments; arg; arg = arg->next) ccparray_put (&ccp, arg->d); diff --git a/tools/gpgtar.c b/tools/gpgtar.c index 492b3d5e5..ea1e1e751 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -76,6 +76,7 @@ enum cmd_and_opt_values oSetFilename, oNull, oUtf8Strings, + oNoCompress, oBatch, oAnswerYes, @@ -121,6 +122,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oSetFilename, "set-filename", "@"), ARGPARSE_s_n (oOpenPGP, "openpgp", "@"), ARGPARSE_s_n (oCMS, "cms", "@"), + ARGPARSE_s_n (oNoCompress, "no-compress", "@"), ARGPARSE_s_n (oBatch, "batch", "@"), ARGPARSE_s_n (oAnswerYes, "yes", "@"), @@ -350,6 +352,7 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) case oFilesFrom: files_from = pargs->r.ret_str; break; case oNull: null_names = 1; break; case oUtf8Strings: opt.utf8strings = 1; break; + case oNoCompress: opt.no_compress = 1; break; case aList: case aDecrypt: diff --git a/tools/gpgtar.h b/tools/gpgtar.h index 9177fcfcb..d86010476 100644 --- a/tools/gpgtar.h +++ b/tools/gpgtar.h @@ -33,6 +33,7 @@ struct int quiet; int dry_run; int utf8strings; + int no_compress; const char *gpg_program; strlist_t gpg_arguments; const char *outfile; From bf04b07327a5d2a7197df36daaa764b8ad5706e4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Jun 2023 15:00:28 +0200 Subject: [PATCH 070/869] dirmngr: New option --compatibility-flags. * dirmngr/dirmngr.c (oCompatibilityFlags): NEw. (opts): Add option --compatibility-flags. (compatibility_flags): New. (parse_rereadable_options): Parse them. --- dirmngr/dirmngr.c | 20 ++++++++++++++++++++ dirmngr/dirmngr.h | 15 +++++++++++++++ doc/dirmngr.texi | 8 ++++++++ 3 files changed, 43 insertions(+) diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index bb54f4edd..46521085f 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -159,6 +159,7 @@ enum cmd_and_opt_values { oConnectQuickTimeout, oListenBacklog, oFakeCRL, + oCompatibilityFlags, aTest }; @@ -297,6 +298,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oSocketName, "socket-name", "@"), /* Only for debugging. */ ARGPARSE_s_n (oDebugCacheExpiredCerts, "debug-cache-expired-certs", "@"), + ARGPARSE_s_s (oCompatibilityFlags, "compatibility-flags", "@"), ARGPARSE_header (NULL, ""), /* Stop the header group. */ @@ -329,6 +331,14 @@ static struct debug_flags_s debug_flags [] = { 77, NULL } /* 77 := Do not exit on "help" or "?". */ }; +/* The list of compatibility flags. */ +static struct compatibility_flags_s compatibility_flags [] = + { + { COMPAT_RESTRICT_HTTP_REDIR, "restrict-http-redir" }, + { 0, NULL } + }; + + #define DEFAULT_MAX_REPLIES 10 #define DEFAULT_LDAP_TIMEOUT 15 /* seconds */ @@ -712,6 +722,7 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) opt.debug_cache_expired_certs = 0; xfree (opt.fake_crl); opt.fake_crl = NULL; + opt.compat_flags = 0; return 1; } @@ -879,6 +890,15 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) opt.fake_crl = *pargs->r.ret_str? xstrdup (pargs->r.ret_str) : NULL; break; + case oCompatibilityFlags: + if (parse_compatibility_flags (pargs->r.ret_str, &opt.compat_flags, + compatibility_flags)) + { + pargs->r_opt = ARGPARSE_INVALID_ARG; + pargs->err = ARGPARSE_PRINT_WARNING; + } + break; + default: return 0; /* Not handled. */ } diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 1128e118b..5571d6181 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -154,6 +154,9 @@ struct current after nextUpdate. */ strlist_t keyserver; /* List of default keyservers. */ + + /* Compatibility flags (COMPAT_FLAG_xxxx). */ + unsigned int compat_flags; } opt; @@ -182,6 +185,18 @@ struct #define DBG_EXTPROG (opt.debug & DBG_EXTPROG_VALUE) #define DBG_KEEPTMP (opt.debug & DBG_KEEPTMP_VALUE) +/* Compatibility flags */ + +/* Since version 2.2.12 dirmngr restricted HTTP redirection in an + * attempt to mitigate certain CSRF attacks. It turned out that this + * breaks too many WKD deployments and that the attack scenario is not + * due to gnupg's redirecting but due to insecure configured systems. + * Thus from 2.4.3 on we disable this restriction but allow to use the + * old behaviour by using this compatibility flag. For details see + * https://dev.gnupg.org/T6477. */ +#define COMPAT_RESTRICT_HTTP_REDIR 1 + + /* A simple list of certificate references. FIXME: Better use certlist_t also for references (Store NULL at .cert) */ struct cert_ref_s diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 8e0979c3e..f17c6206c 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -167,6 +167,14 @@ Append all logging output to @var{file}. This is very helpful in seeing what the agent actually does. Use @file{socket://} to log to socket. +@item --compatibility-flags @var{flags} +@opindex compatibility-flags +Set compatibility flags to work around certain problems or to emulate +bugs. The @var{flags} are given as a comma separated list of flag +names and are OR-ed together. The special flag "none" clears the list +and allows to start over with an empty list. To get a list of +available flags the sole word "help" can be used. + @item --debug-level @var{level} @opindex debug-level Select the debug level for investigating problems. @var{level} may be a From 0a63afc79a0466a0554870d5e8aa6c3d8a048b3d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Jun 2023 15:06:21 +0200 Subject: [PATCH 071/869] dirmngr: Disable the HTTP redirect rewriting. * dirmngr/http.h (struct http_redir_info_s): Add restrict_redir. * dirmngr/ks-engine-hkp.c (send_request): Set it depending on flags. * dirmngr/ks-engine-http.c (ks_http_fetch): Ditto. * dirmngr/t-http-basic.c (test_http_prepare_redirect): Always set it. * dirmngr/http.c (http_prepare_redirect): Remove location rewriting unless the flag is set. -- GnuPG-bug-id: 6477 --- dirmngr/http.c | 9 +++++---- dirmngr/http.h | 1 + dirmngr/ks-engine-hkp.c | 5 +++-- dirmngr/ks-engine-http.c | 1 + dirmngr/t-http-basic.c | 1 + 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/dirmngr/http.c b/dirmngr/http.c index b4c501736..8153fcef4 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -3741,10 +3741,11 @@ http_prepare_redirect (http_redir_info_t *info, unsigned int status_code, http_release_parsed_uri (locuri); return err; } - else if (same_host_p (origuri, locuri)) + else if (!info->restrict_redir || same_host_p (origuri, locuri)) { - /* The host is the same or on an exception list and thus we can - * take the location verbatim. */ + /* Take the syntactically correct location or if restrict_redir + * is set the host is the same or on an exception list and thus + * we can take the location verbatim. */ http_release_parsed_uri (origuri); http_release_parsed_uri (locuri); newurl = xtrystrdup (location); @@ -3754,7 +3755,7 @@ http_prepare_redirect (http_redir_info_t *info, unsigned int status_code, return err; } } - else + else /* Strictly rectricted redirection which we used in the past. */ { /* We take only the host and port from the URL given in the * Location. This limits the effects of redirection attacks by diff --git a/dirmngr/http.h b/dirmngr/http.h index 18420c925..e60212761 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -117,6 +117,7 @@ struct http_redir_info_s unsigned int silent:1; /* No diagnostics. */ unsigned int allow_downgrade:1;/* Allow a downgrade from https to http. */ unsigned int trust_location:1; /* Trust the received Location header. */ + unsigned int restrict_redir:1; /* Use legacy restricted redirection. */ }; typedef struct http_redir_info_s http_redir_info_t; diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 5292da844..66291bc02 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1242,8 +1242,9 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, redirinfo.orig_url = request; redirinfo.orig_onion = uri->onion; redirinfo.allow_downgrade = 1; - /* FIXME: I am not sure whey we allow a downgrade for hkp requests. - * Needs at least an explanation here.. */ + /* FIXME: I am not sure why we allow a downgrade for hkp requests. + * Needs at least an explanation here. */ + redirinfo.restrict_redir = !!(opt.compat_flags & COMPAT_RESTRICT_HTTP_REDIR); once_more: err = http_session_new (&session, httphost, diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index f55a25774..3dca80ee6 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -88,6 +88,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags, redirinfo.orig_onion = uri->onion; redirinfo.orig_https = uri->use_tls; redirinfo.allow_downgrade = !!(flags & KS_HTTP_FETCH_ALLOW_DOWNGRADE); + redirinfo.restrict_redir = !!(opt.compat_flags & COMPAT_RESTRICT_HTTP_REDIR); /* By default we only use the system provided certificates with this * fetch command. */ diff --git a/dirmngr/t-http-basic.c b/dirmngr/t-http-basic.c index edf82efb9..ba3d07a8c 100644 --- a/dirmngr/t-http-basic.c +++ b/dirmngr/t-http-basic.c @@ -165,6 +165,7 @@ test_http_prepare_redirect (void) ri.silent = 1; ri.redirects_left = 1; ri.orig_url = tests[tidx].url; + ri.restrict_redir = 1; /* This is what we used to test here. */ err = http_prepare_redirect (&ri, 301, tests[tidx].location, &newurl); if (err && newurl) From 701a8b30f0be24552772fc2818ad07402eb14478 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 19 Jun 2023 14:05:22 +0200 Subject: [PATCH 072/869] gpgsm: Support SENDCERT_SKI for --call-dirmngr * sm/call-dirmngr.c (run_command_inq_cb): Support SENDCERT_SKI. * dirmngr/crlcache.c (crl_cache_insert): Print the CRL name along with the unknown OID nortice. --- dirmngr/crlcache.c | 1 + sm/call-dirmngr.c | 45 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 9f0b910f3..64f4de97f 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -2361,6 +2361,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader) || !strcmp (oid, oidstr_crlNumber) ) continue; log_error (_("unknown critical CRL extension %s\n"), oid); + log_info ("(CRL='%s')\n", url); if (!err2) err2 = gpg_error (GPG_ERR_INV_CRL); invalidate_crl |= INVCRL_UNKNOWN_EXTN; diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index 86beeedc1..7fe7a68f5 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -1001,16 +1001,17 @@ static gpg_error_t run_command_inq_cb (void *opaque, const char *line) { struct run_command_parm_s *parm = opaque; + gpg_error_t err; const char *s; int rc = 0; + ksba_cert_t cert = NULL; + ksba_sexp_t ski = NULL; + const unsigned char *der; + size_t derlen, n; if ((s = has_leading_keyword (line, "SENDCERT"))) - { /* send the given certificate */ - int err; - ksba_cert_t cert; - const unsigned char *der; - size_t derlen; - + { + /* Send the given certificate. */ line = s; if (!*line) return gpg_error (GPG_ERR_ASS_PARAMETER); @@ -1029,11 +1030,36 @@ run_command_inq_cb (void *opaque, const char *line) rc = gpg_error (GPG_ERR_INV_CERT_OBJ); else rc = assuan_send_data (parm->ctx, der, derlen); - ksba_cert_release (cert); + } + } + else if ((s = has_leading_keyword (line, "SENDCERT_SKI"))) + { + /* Send a certificate where a sourceKeyIdentifier is included. */ + line = s; + ski = make_simple_sexp_from_hexstr (line, &n); + line += n; + while (*line == ' ') + line++; + + err = gpgsm_find_cert (parm->ctrl, line, ski, &cert, + FIND_CERT_ALLOW_AMBIG|FIND_CERT_WITH_EPHEM); + if (err) + { + log_error ("certificate not found: %s\n", gpg_strerror (err)); + rc = gpg_error (GPG_ERR_NOT_FOUND); + } + else + { + der = ksba_cert_get_image (cert, &derlen); + if (!der) + rc = gpg_error (GPG_ERR_INV_CERT_OBJ); + else + rc = assuan_send_data (parm->ctx, der, derlen); } } else if ((s = has_leading_keyword (line, "PRINTINFO"))) - { /* Simply show the message given in the argument. */ + { + /* Simply show the message given in the argument. */ line = s; log_info ("dirmngr: %s\n", line); } @@ -1043,7 +1069,6 @@ run_command_inq_cb (void *opaque, const char *line) root certificate. */ char fpr[41]; struct rootca_flags_s rootca_flags; - int n; line = s; @@ -1067,6 +1092,8 @@ run_command_inq_cb (void *opaque, const char *line) rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE); } + ksba_cert_release (cert); + xfree (ski); return rc; } From b1ecc8353ae37e48b586a315a228bce964253ffe Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 19 Jun 2023 14:25:47 +0200 Subject: [PATCH 073/869] dirmngr: New option --ignore-crl-extensions. * dirmngr/dirmngr.c (oIgnoreCRLExtension): New. (opts): Add --ignore-crl-extension. (parse_rereadable_options): Add to list/ * dirmngr/dirmngr.h (opt): Add ignored_crl_extensions. * dirmngr/crlcache.c (crl_cache_insert): Implement option. -- This option is is useful for debugging problems with new CRL extensions. It is similar to --ignore-cert-extension. GnuPG-bug-id: 6545 --- dirmngr/crlcache.c | 9 +++++++++ dirmngr/dirmngr.c | 7 +++++++ dirmngr/dirmngr.h | 5 +++++ doc/dirmngr.texi | 9 +++++++++ 4 files changed, 30 insertions(+) diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 64f4de97f..ac673a8d5 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -2356,10 +2356,19 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader) for (idx=0; !(err=ksba_crl_get_extension (crl, idx, &oid, &critical, NULL, NULL)); idx++) { + strlist_t sl; + if (!critical || !strcmp (oid, oidstr_authorityKeyIdentifier) || !strcmp (oid, oidstr_crlNumber) ) continue; + + for (sl=opt.ignored_crl_extensions; + sl && strcmp (sl->d, oid); sl = sl->next) + ; + if (sl) + continue; /* Is in ignored list. */ + log_error (_("unknown critical CRL extension %s\n"), oid); log_info ("(CRL='%s')\n", url); if (!err2) diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 46521085f..b460ed3b3 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -147,6 +147,7 @@ enum cmd_and_opt_values { oHTTPWrapperProgram, oIgnoreCert, oIgnoreCertExtension, + oIgnoreCRLExtension, oUseTor, oNoUseTor, oKeyServer, @@ -224,6 +225,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"), ARGPARSE_s_s (oIgnoreCert,"ignore-cert", "@"), ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"), + ARGPARSE_s_s (oIgnoreCRLExtension,"ignore-crl-extension", "@"), ARGPARSE_header ("Network", N_("Network related options")), @@ -706,6 +708,7 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) opt.ignored_certs = tmp; } FREE_STRLIST (opt.ignored_cert_extensions); + FREE_STRLIST (opt.ignored_crl_extensions); http_register_tls_ca (NULL); FREE_STRLIST (hkp_cacert_filenames); FREE_STRLIST (opt.keyserver); @@ -819,6 +822,10 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str); break; + case oIgnoreCRLExtension: + add_to_strlist (&opt.ignored_crl_extensions, pargs->r.ret_str); + break; + case oUseTor: tor_mode = TOR_MODE_FORCE; break; diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 5571d6181..50c97f140 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -132,6 +132,11 @@ struct OID per string. */ strlist_t ignored_cert_extensions; + /* A list of CRL extension OIDs which are ignored so that one can + * claim that a critical extension has been handled. One OID per + * string. */ + strlist_t ignored_crl_extensions; + /* Allow expired certificates in the cache. */ int debug_cache_expired_certs; diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index f17c6206c..0bf35b72f 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -598,6 +598,15 @@ won't be rejected due to an unknown critical extension. Use this option with care because extensions are usually flagged as critical for a reason. +@item --ignore-crl-extension @var{oid} +@opindex ignore-crl-extension +Add @var{oid} to the list of ignored CRL extensions. The @var{oid} is +expected to be in dotted decimal form. Critical flagged CRL +extensions matching one of the OIDs in the list are treated as if they +are actually handled and thus the certificate won't be rejected due to +an unknown critical extension. Use this option with care because +extensions are usually flagged as critical for a reason. + @item --ignore-cert @var{fpr}|@var{file} @opindex ignore-cert Entirely ignore certificates with the fingerprint @var{fpr}. As an From 40090dbbf9ead365cb9350828da8b5ebad426f5e Mon Sep 17 00:00:00 2001 From: zhangguangzhi Date: Thu, 11 May 2023 16:34:23 +0800 Subject: [PATCH 074/869] delete redundant characters -- GnuPG-bug-id: 6482 Signed-off-by: zhangguangzhi --- README | 2 +- dirmngr/ChangeLog-2011 | 2 +- g10/ChangeLog-2011 | 2 +- tools/gpg-card.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index 84a8bacfd..c7887fc0f 100644 --- a/README +++ b/README @@ -170,7 +170,7 @@ * DOCUMENTATION The complete documentation is in the texinfo manual named - `gnupg.info'. Run "info gnupg" to read it. If you want a a + `gnupg.info'. Run "info gnupg" to read it. If you want a printable copy of the manual, change to the "doc" directory and enter "make pdf" For a HTML version enter "make html" and point your browser to gnupg.html/index.html. Standard man pages for all diff --git a/dirmngr/ChangeLog-2011 b/dirmngr/ChangeLog-2011 index 243f2b56f..30e026ff8 100644 --- a/dirmngr/ChangeLog-2011 +++ b/dirmngr/ChangeLog-2011 @@ -1373,7 +1373,7 @@ truncated search. * ldap.c (add_server_to_servers): Reactivated. (url_fetch_ldap): Call it here and try all configured servers in - case of a a failed lookup. + case of a failed lookup. (fetch_next_cert_ldap): Detect the truncation error flag. * misc.c (host_and_port_from_url, remove_percent_escapes): New. diff --git a/g10/ChangeLog-2011 b/g10/ChangeLog-2011 index 37da37bf5..4737b1fa1 100644 --- a/g10/ChangeLog-2011 +++ b/g10/ChangeLog-2011 @@ -4798,7 +4798,7 @@ * g10.c (main): Try to create the trustdb even for non-colon-mode list-key operations. This is required because getkey needs to - know whether a a key is ultimately trusted. From Werner on stable + know whether a key is ultimately trusted. From Werner on stable branch. * exec.c [__CYGWIN32__]: Keep cygwin separate from Mingw32; diff --git a/tools/gpg-card.c b/tools/gpg-card.c index a94aabea9..290ed485d 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -2822,7 +2822,7 @@ cmd_passwd (card_info_t info, char *argstr) log_assert (DIM (info->chvinfo) >= 4); - /* If there is a qualified signature use a a menu to select + /* If there is a qualified signature use a menu to select * between standard PIN and QES PINs. */ if (info->chvinfo[2] != -2 || info->chvinfo[3] != -2) { From be77c0553203fa7f0de4a6db9a33fbd7d099f591 Mon Sep 17 00:00:00 2001 From: zhangguangzhi Date: Thu, 11 May 2023 16:34:23 +0800 Subject: [PATCH 075/869] delete redundant characters -- GnuPG-bug-id: 6482 Signed-off-by: zhangguangzhi --- README | 2 +- dirmngr/ChangeLog-2011 | 2 +- g10/ChangeLog-2011 | 2 +- tools/gpg-card.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README b/README index 97961369e..aa8b3e12b 100644 --- a/README +++ b/README @@ -170,7 +170,7 @@ * DOCUMENTATION The complete documentation is in the texinfo manual named - `gnupg.info'. Run "info gnupg" to read it. If you want a a + `gnupg.info'. Run "info gnupg" to read it. If you want a printable copy of the manual, change to the "doc" directory and enter "make pdf" For a HTML version enter "make html" and point your browser to gnupg.html/index.html. Standard man pages for all diff --git a/dirmngr/ChangeLog-2011 b/dirmngr/ChangeLog-2011 index 243f2b56f..30e026ff8 100644 --- a/dirmngr/ChangeLog-2011 +++ b/dirmngr/ChangeLog-2011 @@ -1373,7 +1373,7 @@ truncated search. * ldap.c (add_server_to_servers): Reactivated. (url_fetch_ldap): Call it here and try all configured servers in - case of a a failed lookup. + case of a failed lookup. (fetch_next_cert_ldap): Detect the truncation error flag. * misc.c (host_and_port_from_url, remove_percent_escapes): New. diff --git a/g10/ChangeLog-2011 b/g10/ChangeLog-2011 index 37da37bf5..4737b1fa1 100644 --- a/g10/ChangeLog-2011 +++ b/g10/ChangeLog-2011 @@ -4798,7 +4798,7 @@ * g10.c (main): Try to create the trustdb even for non-colon-mode list-key operations. This is required because getkey needs to - know whether a a key is ultimately trusted. From Werner on stable + know whether a key is ultimately trusted. From Werner on stable branch. * exec.c [__CYGWIN32__]: Keep cygwin separate from Mingw32; diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 919e61195..4002cc185 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -2822,7 +2822,7 @@ cmd_passwd (card_info_t info, char *argstr) log_assert (DIM (info->chvinfo) >= 4); - /* If there is a qualified signature use a a menu to select + /* If there is a qualified signature use a menu to select * between standard PIN and QES PINs. */ if (info->chvinfo[2] != -2 || info->chvinfo[3] != -2) { From 28a4d0d4f5c586e1c82859da9562fa060a4ebc6e Mon Sep 17 00:00:00 2001 From: zhangguangzhi Date: Thu, 18 May 2023 20:24:41 +0800 Subject: [PATCH 076/869] kbx: Close file handle when return. * kbx/keybox-dump.c (_keybox_dump_find_dups): Close FP on the error paths. -- GnuPG-bug-id: 6495 Signed-off-by: zhangguangzhi --- kbx/keybox-dump.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index 38608ceaa..bad664721 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -810,6 +810,8 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp) gpg_error_t tmperr = gpg_error_from_syserror (); fprintf (outfp, "error allocating array for '%s': %s\n", filename, strerror(errno)); + if (fp != es_stdin) + es_fclose (fp); return tmperr; } dupitems_count = 0; @@ -834,6 +836,8 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp) fprintf (outfp, "error reallocating array for '%s': %s\n", filename, strerror(errno)); free (dupitems); + if (fp != es_stdin) + es_fclose (fp); return tmperr; } dupitems = tmp; From 06aeb2b45c606d948d84d47402c1c8402a33b584 Mon Sep 17 00:00:00 2001 From: zhangguangzhi Date: Thu, 18 May 2023 20:24:41 +0800 Subject: [PATCH 077/869] kbx: Close file handle when return. * kbx/keybox-dump.c (_keybox_dump_find_dups): Close FP on the error paths. -- GnuPG-bug-id: 6495 Signed-off-by: zhangguangzhi --- kbx/keybox-dump.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index 38608ceaa..bad664721 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -810,6 +810,8 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp) gpg_error_t tmperr = gpg_error_from_syserror (); fprintf (outfp, "error allocating array for '%s': %s\n", filename, strerror(errno)); + if (fp != es_stdin) + es_fclose (fp); return tmperr; } dupitems_count = 0; @@ -834,6 +836,8 @@ _keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp) fprintf (outfp, "error reallocating array for '%s': %s\n", filename, strerror(errno)); free (dupitems); + if (fp != es_stdin) + es_fclose (fp); return tmperr; } dupitems = tmp; From 2c7f7a5a278ce669246b4d2dce3361f505d46ba6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 21 Jun 2023 11:33:41 +0200 Subject: [PATCH 078/869] wks: Use export-clean for --mirror and --create. * tools/wks-util.c (wks_get_key): Change from export-minimal to export-clean -- To properly work with tusted introducers et al. it is important to also upload valid key signatures to the Web Key Directory. --- tools/wks-util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/wks-util.c b/tools/wks-util.c index 0aeb94b1d..ee1305b00 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -246,7 +246,7 @@ wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec, ccparray_put (&ccp, "--always-trust"); if (!binary) ccparray_put (&ccp, "--armor"); - ccparray_put (&ccp, "--export-options=export-minimal"); + ccparray_put (&ccp, "--export-options=export-clean"); ccparray_put (&ccp, "--export-filter"); ccparray_put (&ccp, filterexp); ccparray_put (&ccp, "--export"); From 10c937ee68cbf784942630115449f32cd82089fe Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 21 Jun 2023 11:34:58 +0200 Subject: [PATCH 079/869] wks: Make --add-revocs the default. * tools/gpg-wks-client.c (opt): New option --no-add-revocs. (main): Make --add-revocs the default. (command_send): Rename to ... (command_create): to match the command name. --- doc/wks.texi | 4 +++- tools/gpg-wks-client.c | 13 ++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/doc/wks.texi b/doc/wks.texi index 39e345f15..26d8b96f6 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -216,12 +216,14 @@ addrspec, e.g. "postel@@isi.edu") per line. Empty lines and lines starting with a '#' are ignored. @item --add-revocs +@itemx --no-add-revocs @opindex add-revocs +@opindex no-add-revocs If enabled append revocation certificates for the same addrspec as used in the WKD to the key. Modern gpg version are able to import and apply them for existing keys. Note that when used with the @option{--mirror} command the revocation are searched in the local -keyring and not in an LDAP directory. +keyring and not in an LDAP directory. The default is @option{--add-revocs}. @item --verbose @opindex verbose diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index 521222631..fa0278ae0 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -77,6 +77,7 @@ enum cmd_and_opt_values oBlacklist, oNoAutostart, oAddRevocs, + oNoAddRevocs, oDummy }; @@ -121,6 +122,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oBlacklist, "blacklist", "@"), ARGPARSE_s_s (oDirectory, "directory", "@"), ARGPARSE_s_n (oAddRevocs, "add-revocs", "add revocation certificates"), + ARGPARSE_s_n (oNoAddRevocs, "no-add-revocs", "do not add revocation certificates"), ARGPARSE_s_s (oFakeSubmissionAddr, "fake-submission-addr", "@"), @@ -158,7 +160,7 @@ static gpg_error_t proc_userid_from_stdin (gpg_error_t (*func)(const char *), const char *text); static gpg_error_t command_supported (char *userid); static gpg_error_t command_check (char *userid); -static gpg_error_t command_send (const char *fingerprint, const char *userid); +static gpg_error_t command_create (const char *fingerprint, const char *userid); static gpg_error_t encrypt_response (estream_t *r_output, estream_t input, const char *addrspec, const char *fingerprint); @@ -262,6 +264,9 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) case oAddRevocs: opt.add_revocs = 1; break; + case oNoAddRevocs: + opt.add_revocs = 0; + break; case aSupported: case aCreate: @@ -304,6 +309,8 @@ main (int argc, char **argv) assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); setup_libassuan_logging (&opt.debug, NULL); + opt.add_revocs = 1; /* Default add revocation certs. */ + /* Parse the command line. */ pargs.argc = &argc; pargs.argv = &argv; @@ -397,7 +404,7 @@ main (int argc, char **argv) case aCreate: if (argc != 2) wrong_args ("--create FINGERPRINT USER-ID"); - err = command_send (argv[0], argv[1]); + err = command_create (argv[0], argv[1]); if (err) log_error ("creating request failed: %s\n", gpg_strerror (err)); break; @@ -1153,7 +1160,7 @@ command_check (char *userid) /* Locate the key by fingerprint and userid and send a publication * request. */ static gpg_error_t -command_send (const char *fingerprint, const char *userid) +command_create (const char *fingerprint, const char *userid) { gpg_error_t err; KEYDB_SEARCH_DESC desc; From e9e7b5425fdd5d2b6374edf0935d1609d0e29972 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 22 Jun 2023 11:38:44 +0900 Subject: [PATCH 080/869] common: Add translate_sys2libc_fdstr. * common/sysutils.c (translate_sys2libc_fdstr): New. -- GnuPG-bug-id: 6551 Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ common/sysutils.h | 1 + 2 files changed, 51 insertions(+) diff --git a/common/sysutils.c b/common/sysutils.c index b59d2a961..e40151b26 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -575,6 +575,56 @@ translate_sys2libc_fd_int (int fd, int for_write) } +/* This is the same as translate_sys2libc_fd but takes a string + which may represent a system handle. + + (1) 0, 1, or 2 which means stdin, stdout, and stderr, respectively. + (2) Integer representation (by %d of printf). + (3) Hex representation which starts as "0x". + */ +int +translate_sys2libc_fdstr (const char *fdstr, int for_write) +{ +#ifdef HAVE_W32_SYSTEM + gnupg_fd_t fd; + char *endptr; + int base; + + if (!strcmp (fdstr, "0")) + return 0; + else if (!strcmp (fdstr, "1")) + return 1; + else if (!strcmp (fdstr, "2")) + return 2; + + if (!strncmp (fdstr, "0x", 2)) + { + base = 16; + fdstr += 2; + } + else + base = 10; + + gpg_err_set_errno (0); +#ifdef _WIN64 + fd = (gnupg_fd_t)strtoll (fdstr, &endptr, base); +#else + fd = (gnupg_fd_t)strtol (fdstr, &endptr, base); +#endif + if (errno != 0 || endptr == fdstr || *endptr != '\0') + { + log_error ("FDSTR error: %s\n", fdstr); + return -1; + } + + return translate_sys2libc_fd (fd, for_write); +#else + (void)for_write; + return atoi (fdstr); +#endif +} + + /* Check whether FNAME has the form "-&nnnn", where N is a non-zero * number. Returns this number or -1 if it is not the case. If the * caller wants to use the file descriptor for writing FOR_WRITE shall diff --git a/common/sysutils.h b/common/sysutils.h index 7063da067..10dbe3e80 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -74,6 +74,7 @@ void gnupg_sleep (unsigned int seconds); void gnupg_usleep (unsigned int usecs); int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); int translate_sys2libc_fd_int (int fd, int for_write); +int translate_sys2libc_fdstr (const char *fdstr, int for_write); int check_special_filename (const char *fname, int for_write, int notranslate); FILE *gnupg_tmpfile (void); void gnupg_reopen_std (const char *pgmname); From 04d0851ccaaee94526281c0c13fdc70ee3ce7007 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 23 Jun 2023 13:05:29 +0900 Subject: [PATCH 081/869] common: Add gnupg_sys2libc_fdstr function. * common/sysutils.c (gnupg_sys2libc_fdstr): New. (translate_sys2libc_fdstr): Use gnupg_sys2libc_fdstr. -- GnuPG-bug-id: 6551 Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 90 +++++++++++++++++++++++++++++++++++++---------- common/sysutils.h | 2 ++ 2 files changed, 74 insertions(+), 18 deletions(-) diff --git a/common/sysutils.c b/common/sysutils.c index e40151b26..faff7e4a2 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -575,27 +575,51 @@ translate_sys2libc_fd_int (int fd, int for_write) } -/* This is the same as translate_sys2libc_fd but takes a string - which may represent a system handle. +/* + * Parse the string representation of a file reference (file handle on + * Windows or file descriptor on POSIX) in FDSTR. The string + * representation may be either of folllowing: - (1) 0, 1, or 2 which means stdin, stdout, and stderr, respectively. - (2) Integer representation (by %d of printf). - (3) Hex representation which starts as "0x". + * (1) 0, 1, or 2 which means stdin, stdout, and stderr, respectively. + * (2) Integer representation (by %d of printf). + * (3) Hex representation which starts as "0x". + * + * FOR_WRITE is 1 for a file for writing, 0 otherwise. + * + * There are two use cases for the function: + * + * - R_HD != NULL, R_FD == NULL: + * Return the value in *R_HD. + * + * - R_HD == NULL, R_FD != NULL: + * Return the value in *R_FD, after translating to a file descriptor. + * */ -int -translate_sys2libc_fdstr (const char *fdstr, int for_write) +gpg_error_t +gnupg_sys2libc_fdstr (const char *fdstr, int for_write, + gnupg_fd_t *r_hd, int *r_fd) { + int fd = -1; #ifdef HAVE_W32_SYSTEM - gnupg_fd_t fd; + gnupg_fd_t hd; char *endptr; int base; if (!strcmp (fdstr, "0")) - return 0; + fd = 0; else if (!strcmp (fdstr, "1")) - return 1; + fd = 1; else if (!strcmp (fdstr, "2")) - return 2; + fd = 2; + + if (fd >= 0) + { + if (r_hd) + *r_hd = (gnupg_fd_t)(uintptr_t)fd; + else if (r_fd) + *r_fd = fd; + return 0; + } if (!strncmp (fdstr, "0x", 2)) { @@ -607,21 +631,51 @@ translate_sys2libc_fdstr (const char *fdstr, int for_write) gpg_err_set_errno (0); #ifdef _WIN64 - fd = (gnupg_fd_t)strtoll (fdstr, &endptr, base); + hd = (gnupg_fd_t)strtoll (fdstr, &endptr, base); #else - fd = (gnupg_fd_t)strtol (fdstr, &endptr, base); + hd = (gnupg_fd_t)strtol (fdstr, &endptr, base); #endif if (errno != 0 || endptr == fdstr || *endptr != '\0') + return gpg_error (GPG_ERR_INV_ARG); + + if (r_hd) + *r_hd = hd; + else if (r_fd) + *r_fd = translate_sys2libc_fd (hd, for_write); + return 0; +#else + (void)for_write; + fd = atoi (fdstr); + if (r_hd) + *r_hd = fd; + else if (r_fd) + *r_fd = fd; + return 0; +#endif +} + +/* This is the same as translate_sys2libc_fd but takes a string + which represents a system handle on Windows a file descriptor + on POSIX. + + (1) 0, 1, or 2 which means stdin, stdout, and stderr, respectively. + (2) Integer representation (by %d of printf). + (3) Hex representation which starts as "0x". +*/ +int +translate_sys2libc_fdstr (const char *fdstr, int for_write) +{ + gpg_error_t err; + gnupg_fd_t fd; + + err = gnupg_sys2libc_fdstr (fdstr, for_write, NULL, &fd); + if (err) { log_error ("FDSTR error: %s\n", fdstr); return -1; } - return translate_sys2libc_fd (fd, for_write); -#else - (void)for_write; - return atoi (fdstr); -#endif + return fd; } diff --git a/common/sysutils.h b/common/sysutils.h index 10dbe3e80..2d864a983 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -74,6 +74,8 @@ void gnupg_sleep (unsigned int seconds); void gnupg_usleep (unsigned int usecs); int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); int translate_sys2libc_fd_int (int fd, int for_write); +gpg_error_t gnupg_sys2libc_fdstr (const char *fdstr, int for_write, + gnupg_fd_t *r_hd, int *r_fd); int translate_sys2libc_fdstr (const char *fdstr, int for_write); int check_special_filename (const char *fname, int for_write, int notranslate); FILE *gnupg_tmpfile (void); From 2756147e392c8f58fc79db6b9420b306b6ddd082 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 23 Jun 2023 13:10:19 +0900 Subject: [PATCH 082/869] gpg,sm,tools: Use string for option --*-fd. * g10/gpg.c (opts): Use string for oLoggerFD, oOverrideSessionKeyFD, oStatusFD, oAttributeFD, oCommandFD, and oPassphraseFD. (main): Use translate_sys2libc_fdstr. * g10/gpgv.c (opts): Use string for oLoggerFD, and oStatusFD. (main): Use translate_sys2libc_fdstr. * sm/gpgsm.c (opts): Use string for oLoggerFD, oStatusFD, and oPassphraseFD. (main): Use translate_sys2libc_fdstr. * tools/gpg-auth.c (opts): Use string for oStatusFD. (main): Use translate_sys2libc_fdstr. tools/gpg-card.c (opts): Use string for oStatusFD. (main): Use translate_sys2libc_fdstr. * tools/gpg-pair-tool.c (opts): Use string for oStatusFD. (main): Use translate_sys2libc_fdstr. * tools/gpg-wks-client.c (opts): Use string for oStatusFD. (main): Use translate_sys2libc_fdstr. * tools/gpgconf.c (opts): Use string for oStatusFD. (main): Use translate_sys2libc_fdstr. * tools/gpgtar-create.c (gpgtar_create): Fix for opt.status_fd. * tools/gpgtar-extract.c (gpgtar_extract): Fix for opt.status_fd. * tools/gpgtar-list.c (gpgtar_list): Fix for opt.status_fd. * tools/gpgtar.c (opts): Use string for oStatusFD. (main): Use translate_sys2libc_fdstr. * tools/gpgtar.h (opts): Use string for oStatusFD. -- GnuPG-bug-id: 6551 Signed-off-by: NIIBE Yutaka --- g10/gpg.c | 24 ++++++++++++------------ g10/gpgv.c | 8 ++++---- sm/gpgsm.c | 12 ++++++------ tools/gpg-auth.c | 4 ++-- tools/gpg-card.c | 4 ++-- tools/gpg-pair-tool.c | 4 ++-- tools/gpg-wks-client.c | 4 ++-- tools/gpgconf.c | 4 ++-- tools/gpgtar-create.c | 12 +++++++++--- tools/gpgtar-extract.c | 12 +++++++++--- tools/gpgtar-list.c | 12 +++++++++--- tools/gpgtar.c | 36 ++++++++++++++++++++++++++++-------- tools/gpgtar.h | 2 +- 13 files changed, 88 insertions(+), 50 deletions(-) diff --git a/g10/gpg.c b/g10/gpg.c index 6e54aa763..b766e318f 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -603,7 +603,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oDisplayCharset, "charset", "@"), ARGPARSE_conffile (oOptions, "options", N_("|FILE|read options from FILE")), ARGPARSE_noconffile (oNoOptions, "no-options", "@"), - ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), + ARGPARSE_s_s (oLoggerFD, "logger-fd", "@"), ARGPARSE_s_s (oLoggerFile, "log-file", N_("|FILE|write server mode logs to FILE")), ARGPARSE_s_s (oLoggerFile, "logger-file", "@"), /* 1.4 compatibility. */ @@ -854,7 +854,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"), ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"), ARGPARSE_s_s (oOverrideSessionKey, "override-session-key", "@"), - ARGPARSE_s_i (oOverrideSessionKeyFD, "override-session-key-fd", "@"), + ARGPARSE_s_s (oOverrideSessionKeyFD, "override-session-key-fd", "@"), ARGPARSE_header ("Security", N_("Options controlling the security")), @@ -894,14 +894,14 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oNoBatch, "no-batch", "@"), ARGPARSE_s_n (oAnswerYes, "yes", "@"), ARGPARSE_s_n (oAnswerNo, "no", "@"), - ARGPARSE_s_i (oStatusFD, "status-fd", "@"), + ARGPARSE_s_s (oStatusFD, "status-fd", "@"), ARGPARSE_s_s (oStatusFile, "status-file", "@"), - ARGPARSE_s_i (oAttributeFD, "attribute-fd", "@"), + ARGPARSE_s_s (oAttributeFD, "attribute-fd", "@"), ARGPARSE_s_s (oAttributeFile, "attribute-file", "@"), - ARGPARSE_s_i (oCommandFD, "command-fd", "@"), + ARGPARSE_s_s (oCommandFD, "command-fd", "@"), ARGPARSE_s_s (oCommandFile, "command-file", "@"), ARGPARSE_o_s (oPassphrase, "passphrase", "@"), - ARGPARSE_s_i (oPassphraseFD, "passphrase-fd", "@"), + ARGPARSE_s_s (oPassphraseFD, "passphrase-fd", "@"), ARGPARSE_s_s (oPassphraseFile, "passphrase-file", "@"), ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"), ARGPARSE_s_s (oPinentryMode, "pinentry-mode", "@"), @@ -2867,19 +2867,19 @@ main (int argc, char **argv) break; case oStatusFD: - set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) ); + set_status_fd ( translate_sys2libc_fdstr (pargs.r.ret_str, 1) ); break; case oStatusFile: set_status_fd ( open_info_file (pargs.r.ret_str, 1, 0) ); break; case oAttributeFD: - set_attrib_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) ); + set_attrib_fd ( translate_sys2libc_fdstr (pargs.r.ret_str, 1) ); break; case oAttributeFile: set_attrib_fd ( open_info_file (pargs.r.ret_str, 1, 1) ); break; case oLoggerFD: - log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); + log_set_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); break; case oLoggerFile: logfile = pargs.r.ret_str; @@ -3245,7 +3245,7 @@ main (int argc, char **argv) set_passphrase_from_string (pargs.r_type ? pargs.r.ret_str : ""); break; case oPassphraseFD: - pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); + pwfd = translate_sys2libc_fdstr (pargs.r.ret_str, 0); break; case oPassphraseFile: pwfd = open_info_file (pargs.r.ret_str, 0, 1); @@ -3267,7 +3267,7 @@ main (int argc, char **argv) break; case oCommandFD: - opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); + opt.command_fd = translate_sys2libc_fdstr (pargs.r.ret_str, 0); if (! gnupg_fd_valid (opt.command_fd)) log_error ("command-fd is invalid: %s\n", strerror (errno)); break; @@ -3526,7 +3526,7 @@ main (int argc, char **argv) opt.override_session_key = pargs.r.ret_str; break; case oOverrideSessionKeyFD: - ovrseskeyfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); + ovrseskeyfd = translate_sys2libc_fdstr (pargs.r.ret_str, 0); break; case oMergeOnly: deprecated_warning(configname,pargs.lineno,"--merge-only", diff --git a/g10/gpgv.c b/g10/gpgv.c index f2895563e..c46cfa9b7 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -82,9 +82,9 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")), ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", N_("make timestamp conflicts only a warning")), - ARGPARSE_s_i (oStatusFD, "status-fd", + ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), - ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), + ARGPARSE_s_s (oLoggerFD, "logger-fd", "@"), ARGPARSE_s_s (oLoggerFile, "log-file", "@"), ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_s (oWeakDigest, "weak-digest", @@ -232,10 +232,10 @@ main( int argc, char **argv ) case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; case oOutput: opt.outfile = pargs.r.ret_str; break; case oStatusFD: - set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); + set_status_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); break; case oLoggerFD: - log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); + log_set_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); break; case oLoggerFile: log_set_file (pargs.r.ret_str); diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 07c3ff480..ceb58a13f 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -290,7 +290,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write server mode logs to FILE")), ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"), - ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), + ARGPARSE_s_s (oLoggerFD, "logger-fd", "@"), ARGPARSE_s_n (oLogTime, "log-time", "@"), ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"), @@ -422,9 +422,9 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oNoBatch, "no-batch", "@"), ARGPARSE_s_n (oAnswerYes, "yes", N_("assume yes on most questions")), ARGPARSE_s_n (oAnswerNo, "no", N_("assume no on most questions")), - ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"), - ARGPARSE_s_i (oPassphraseFD, "passphrase-fd", "@"), + ARGPARSE_s_s (oPassphraseFD, "passphrase-fd", "@"), ARGPARSE_s_s (oPinentryMode, "pinentry-mode", "@"), @@ -1156,7 +1156,7 @@ main ( int argc, char **argv) break; case oPassphraseFD: - pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); + pwfd = translate_sys2libc_fdstr (pargs.r.ret_str, 0); break; case oPinentryMode: @@ -1300,10 +1300,10 @@ main ( int argc, char **argv) break; case oStatusFD: - ctrl.status_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 1); + ctrl.status_fd = translate_sys2libc_fdstr (pargs.r.ret_str, 1); break; case oLoggerFD: - log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); + log_set_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); break; case oWithMD5Fingerprint: opt.with_md5_fingerprint=1; /*fall through*/ diff --git a/tools/gpg-auth.c b/tools/gpg-auth.c index f433ba220..6de3494ad 100644 --- a/tools/gpg-auth.c +++ b/tools/gpg-auth.c @@ -94,7 +94,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oVerbose, "verbose", ("verbose")), ARGPARSE_s_n (oQuiet, "quiet", ("be somewhat more quiet")), ARGPARSE_s_s (oDebug, "debug", "@"), - ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"), ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), @@ -168,7 +168,7 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) case oAgentProgram: opt.agent_program = pargs->r.ret_str; break; case oStatusFD: - gnupg_set_status_fd (translate_sys2libc_fd_int (pargs->r.ret_int, 1)); + gnupg_set_status_fd (translate_sys2libc_fdstr (pargs->r.ret_str, 1)); break; case oWithColons: opt.with_colons = 1; break; diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 4002cc185..24518d105 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -94,7 +94,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oGpgProgram, "gpg", "@"), ARGPARSE_s_s (oGpgsmProgram, "gpgsm", "@"), - ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"), ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), @@ -225,7 +225,7 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) case oAgentProgram: opt.agent_program = pargs->r.ret_str; break; case oStatusFD: - gnupg_set_status_fd (translate_sys2libc_fd_int (pargs->r.ret_int, 1)); + gnupg_set_status_fd (translate_sys2libc_fdstr (pargs->r.ret_str, 1)); break; case oWithColons: opt.with_colons = 1; break; diff --git a/tools/gpg-pair-tool.c b/tools/gpg-pair-tool.c index cf9778838..069bd1668 100644 --- a/tools/gpg-pair-tool.c +++ b/tools/gpg-pair-tool.c @@ -179,7 +179,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oSAS, "sas", N_("|SAS|the SAS as shown by the peer")), ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oOutput, "output", N_("|FILE|write the request to FILE")), - ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_s (oHomedir, "homedir", "@"), @@ -390,7 +390,7 @@ main (int argc, char **argv) break; case oStatusFD: - set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); + set_status_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); break; case oHomedir: diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index 521222631..ee0554014 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -115,7 +115,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oGpgProgram, "gpg", "@"), ARGPARSE_s_n (oSend, "send", "send the mail using sendmail"), ARGPARSE_s_s (oOutput, "output", "|FILE|write the mail to FILE"), - ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"), ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_s (oBlacklist, "blacklist", "@"), @@ -248,7 +248,7 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) fake_submission_addr = pargs->r.ret_str; break; case oStatusFD: - wks_set_status_fd (translate_sys2libc_fd_int (pargs->r.ret_int, 1)); + wks_set_status_fd (translate_sys2libc_fdstr (pargs->r.ret_str, 1)); break; case oWithColons: opt.with_colons = 1; diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 522ce517b..9738ffe97 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -118,7 +118,7 @@ static gpgrt_opt_t opts[] = { oQuiet, "quiet", 0, N_("quiet") }, { oDryRun, "dry-run", 0, N_("do not make any changes") }, { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") }, - ARGPARSE_s_i (oStatusFD, "status-fd", + ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), /* hidden options */ { oHomedir, "homedir", 2, "@" }, @@ -645,7 +645,7 @@ main (int argc, char **argv) case oBuilddir: gnupg_set_builddir (pargs.r.ret_str); break; case oNull: opt.null = 1; break; case oStatusFD: - set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); + set_status_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); break; case oShowSocket: show_socket = 1; break; case oChUid: changeuser = pargs.r.ret_str; break; diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index e6f5b55a2..99da9ecf0 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -1246,13 +1246,19 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, ccparray_put (&ccp, "--no"); if (opt.require_compliance) ccparray_put (&ccp, "--require-compliance"); - if (opt.status_fd != -1) + if (opt.status_fd) { static char tmpbuf[40]; + es_syshd_t hd; - snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%d", opt.status_fd); + snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%s", opt.status_fd); ccparray_put (&ccp, tmpbuf); - except[0] = opt.status_fd; + es_syshd (opt.status_stream, &hd); +#ifdef HAVE_W32_SYSTEM + except[0] = hd.u.handle; +#else + except[0] = hd.u.fd; +#endif } ccparray_put (&ccp, "--output"); diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index be483f87c..33b88ff4d 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -392,13 +392,19 @@ gpgtar_extract (const char *filename, int decrypt) ccparray_put (&ccp, "--batch"); if (opt.require_compliance) ccparray_put (&ccp, "--require-compliance"); - if (opt.status_fd != -1) + if (opt.status_fd) { static char tmpbuf[40]; + es_syshd_t hd; - snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%d", opt.status_fd); + snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%s", opt.status_fd); ccparray_put (&ccp, tmpbuf); - except[0] = opt.status_fd; + es_syshd (opt.status_stream, &hd); +#ifdef HAVE_W32_SYSTEM + except[0] = hd.u.handle; +#else + except[0] = hd.u.fd; +#endif } if (opt.with_log) { diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c index 31bcd8d46..846008ee8 100644 --- a/tools/gpgtar-list.c +++ b/tools/gpgtar-list.c @@ -476,13 +476,19 @@ gpgtar_list (const char *filename, int decrypt) ccparray_put (&ccp, "--batch"); if (opt.require_compliance) ccparray_put (&ccp, "--require-compliance"); - if (opt.status_fd != -1) + if (opt.status_fd) { static char tmpbuf[40]; + es_syshd_t hd; - snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%d", opt.status_fd); + snprintf (tmpbuf, sizeof tmpbuf, "--status-fd=%s", opt.status_fd); ccparray_put (&ccp, tmpbuf); - except[0] = opt.status_fd; + es_syshd (opt.status_stream, &hd); +#ifdef HAVE_W32_SYSTEM + except[0] = hd.u.handle; +#else + except[0] = hd.u.fd; +#endif } ccparray_put (&ccp, "--output"); ccparray_put (&ccp, "-"); diff --git a/tools/gpgtar.c b/tools/gpgtar.c index 492b3d5e5..dd269043f 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -125,7 +125,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oBatch, "batch", "@"), ARGPARSE_s_n (oAnswerYes, "yes", "@"), ARGPARSE_s_n (oAnswerNo, "no", "@"), - ARGPARSE_s_i (oStatusFD, "status-fd", "@"), + ARGPARSE_s_s (oStatusFD, "status-fd", "@"), ARGPARSE_s_n (oRequireCompliance, "require-compliance", "@"), ARGPARSE_s_n (oWithLog, "with-log", "@"), @@ -395,7 +395,7 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) case oBatch: opt.batch = 1; break; case oAnswerYes: opt.answer_yes = 1; break; case oAnswerNo: opt.answer_no = 1; break; - case oStatusFD: opt.status_fd = pargs->r.ret_int; break; + case oStatusFD: opt.status_fd = pargs->r.ret_str; break; case oRequireCompliance: opt.require_compliance = 1; break; case oWithLog: opt.with_log = 1; break; @@ -477,7 +477,7 @@ main (int argc, char **argv) log_assert (sizeof (struct ustar_raw_header) == 512); /* Set default options */ - opt.status_fd = -1; + opt.status_fd = NULL; /* The configuraton directories for use by gpgrt_argparser. */ gpgrt_set_confdir (GPGRT_CONFDIR_SYS, gnupg_sysconfdir ()); @@ -509,12 +509,23 @@ main (int argc, char **argv) /* Set status stream for our own use of --status-fd. The original * status fd is passed verbatim to gpg. */ - if (opt.status_fd != -1) + if (opt.status_fd) { - int fd = translate_sys2libc_fd_int (opt.status_fd, 1); + int fd = -1; - if (!gnupg_fd_valid (fd)) - log_fatal ("status-fd is invalid: %s\n", strerror (errno)); +#ifdef HAVE_W32_SYSTEM + gnupg_fd_t hd; + + err = gnupg_sys2libc_fdstr (opt.status_fd, 1, &hd, NULL); + if ((uintptr_t)hd == 1) + fd = 1; + else if ((uintptr_t)hd == 2) + fd = 2; +#else + err = gnupg_sys2libc_fdstr (opt.status_fd, 1, NULL, &fd); +#endif + if (err) + log_fatal ("status-fd is invalid: %s\n", gpg_strerror (err)); if (fd == 1) { @@ -526,7 +537,16 @@ main (int argc, char **argv) opt.status_stream = es_stderr; else { - opt.status_stream = es_fdopen (fd, "w"); + es_syshd_t syshd; + +#ifdef HAVE_W32_SYSTEM + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = hd; +#else + syshd.type = ES_SYSHD_FD; + syshd.u.handle = fd; +#endif + opt.status_stream = es_sysopen (&syshd, "w"); if (opt.status_stream) es_setvbuf (opt.status_stream, NULL, _IOLBF, 0); } diff --git a/tools/gpgtar.h b/tools/gpgtar.h index 9177fcfcb..26b405f0b 100644 --- a/tools/gpgtar.h +++ b/tools/gpgtar.h @@ -44,7 +44,7 @@ struct int batch; int answer_yes; int answer_no; - int status_fd; + const char *status_fd; estream_t status_stream; int require_compliance; int with_log; From 87a73e8eb0c9e61858253c7616b95a943e56028f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 23 Jun 2023 13:37:08 +0900 Subject: [PATCH 083/869] common: Remove translate_sys2libc_fd_int. * common/sysutils.c (translate_sys2libc_fd_int): Remove. (check_special_filename): Use translate_sys2libc_fdstr. * common/sysutils.h (translate_sys2libc_fd_int): Remove. -- GnuPG-bug-id: 6551 Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 20 +------------------- common/sysutils.h | 1 - 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/common/sysutils.c b/common/sysutils.c index faff7e4a2..b6e22e943 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -556,24 +556,6 @@ translate_sys2libc_fd (gnupg_fd_t fd, int for_write) #endif } -/* This is the same as translate_sys2libc_fd but takes an integer - which is assumed to be such an system handle. On WindowsCE the - passed FD is a rendezvous ID and the function finishes the pipe - creation. */ -int -translate_sys2libc_fd_int (int fd, int for_write) -{ -#ifdef HAVE_W32_SYSTEM - if (fd <= 2) - return fd; /* Do not do this for error, stdin, stdout, stderr. */ - - return translate_sys2libc_fd ((void*)fd, for_write); -#else - (void)for_write; - return fd; -#endif -} - /* * Parse the string representation of a file reference (file handle on @@ -697,7 +679,7 @@ check_special_filename (const char *fname, int for_write, int notranslate) ; if (!fname[i]) return notranslate? atoi (fname) - /**/ : translate_sys2libc_fd_int (atoi (fname), for_write); + /**/ : translate_sys2libc_fdstr (fname, for_write); } return -1; } diff --git a/common/sysutils.h b/common/sysutils.h index 2d864a983..380a6d9a9 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -73,7 +73,6 @@ unsigned int get_uint_nonce (void); void gnupg_sleep (unsigned int seconds); void gnupg_usleep (unsigned int usecs); int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); -int translate_sys2libc_fd_int (int fd, int for_write); gpg_error_t gnupg_sys2libc_fdstr (const char *fdstr, int for_write, gnupg_fd_t *r_hd, int *r_fd); int translate_sys2libc_fdstr (const char *fdstr, int for_write); From f0ecc07c4e4866e1509316639c0ca4cfc5385d53 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 26 Jun 2023 10:17:23 +0900 Subject: [PATCH 084/869] tools: Fix use of EXCEPTS when spawning a process. * tools/gpgtar-create.c (gpgtar_create) [HAVE_W32_SYSTEM]: Use HANDLE. * tools/gpgtar-extract.c (gpgtar_extract) [HAVE_W32_SYSTEM]: Likewise. * tools/gpgtar-list.c (gpgtar_list) [HAVE_W32_SYSTEM]: Likewise. -- Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 2 +- tools/gpgtar-create.c | 4 ++++ tools/gpgtar-extract.c | 4 ++++ tools/gpgtar-list.c | 4 ++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/common/sysutils.c b/common/sysutils.c index b6e22e943..7c3667ce7 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -648,7 +648,7 @@ int translate_sys2libc_fdstr (const char *fdstr, int for_write) { gpg_error_t err; - gnupg_fd_t fd; + int fd; err = gnupg_sys2libc_fdstr (fdstr, for_write, NULL, &fd); if (err) diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index 99da9ecf0..534141cc1 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -1228,7 +1228,11 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, { strlist_t arg; ccparray_t ccp; +#ifdef HAVE_W32_SYSTEM + HANDLE except[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; +#else int except[2] = { -1, -1 }; +#endif const char **argv; /* '--encrypt' may be combined with '--symmetric', but 'encrypt' diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index 33b88ff4d..87113b054 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -384,7 +384,11 @@ gpgtar_extract (const char *filename, int decrypt) { strlist_t arg; ccparray_t ccp; +#ifdef HAVE_W32_SYSTEM + HANDLE except[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; +#else int except[2] = { -1, -1 }; +#endif const char **argv; ccparray_init (&ccp, 0); diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c index 846008ee8..0c5e474f3 100644 --- a/tools/gpgtar-list.c +++ b/tools/gpgtar-list.c @@ -468,7 +468,11 @@ gpgtar_list (const char *filename, int decrypt) { strlist_t arg; ccparray_t ccp; +#ifdef HAVE_W32_SYSTEM + HANDLE except[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; +#else int except[2] = { -1, -1 }; +#endif const char **argv; ccparray_init (&ccp, 0); From 1f9a4fbc7e6c5c8d39ef3978fd4461fe00897fe5 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 26 Jun 2023 10:59:35 +0900 Subject: [PATCH 085/869] gpg,w32: Add comment about debug output of ShellExecuteEx. * g10/photoid.c (w32_system): Add comment about hInstApp, why we use the integer value of possibly smaller size for the debug output. -- GnuPG-bug-id: 6508 Signed-off-by: NIIBE Yutaka --- g10/photoid.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/g10/photoid.c b/g10/photoid.c index 80fc35f8c..5f4bf5e2b 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -92,8 +92,15 @@ w32_system (const char *command) return -1; } if (DBG_EXTPROG) - log_debug ("ShellExecuteEx succeeded (hProcess=%p,hInstApp=%d)\n", - see.hProcess, (int)see.hInstApp); + { + /* hInstApp has HINSTANCE type. The documentations says + that it's not a true HINSTANCE and it can be cast only to + an int. */ + int hinstance = (intptr_t)see.hInstApp; + + log_debug ("ShellExecuteEx succeeded (hProcess=%p,hInstApp=%d)\n", + see.hProcess, hinstance); + } if (!see.hProcess) { From 76df9349292831970961d50493115a1ed7d22451 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 26 Jun 2023 14:47:28 +0900 Subject: [PATCH 086/869] tests:gpgscm: Add annotation for unreachable code for GCC. * tests/gpgscm/scheme.c [__GNUC__] (type_to_string): Use __builtin_unreachable for GCC. -- Signed-off-by: NIIBE Yutaka --- tests/gpgscm/scheme.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/gpgscm/scheme.c b/tests/gpgscm/scheme.c index bde39fcd0..003e85037 100644 --- a/tests/gpgscm/scheme.c +++ b/tests/gpgscm/scheme.c @@ -169,7 +169,11 @@ type_to_string (enum scheme_types typ) case T_SINK: return "sink"; case T_FRAME: return "frame"; } +#ifdef __GNUC__ + __builtin_unreachable (); +#else assert (! "not reached"); +#endif } /* ADJ is enough slack to align cells in a TYPE_BITS-bit boundary */ From 72ac77c4fab90551be2a9810793a1b253ac6229b Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 26 Jun 2023 14:58:58 +0900 Subject: [PATCH 087/869] agent: Fix cast mistake for Windows. * agent/call-daemon.c [HAVE_W32_SYSTEM] (daemon_start): Use %p for the format with a pointer. -- GnuPG-bug-id: 6508 Signed-off-by: NIIBE Yutaka --- agent/call-daemon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/call-daemon.c b/agent/call-daemon.c index 0c3605274..732e485e3 100644 --- a/agent/call-daemon.c +++ b/agent/call-daemon.c @@ -471,8 +471,8 @@ daemon_start (enum daemon_type type, ctrl_t ctrl) char buf[100]; #ifdef HAVE_W32_SYSTEM - snprintf (buf, sizeof buf, "OPTION event-signal=%lx", - (unsigned long)get_agent_daemon_notify_event ()); + snprintf (buf, sizeof buf, "OPTION event-signal=%p", + get_agent_daemon_notify_event ()); #else snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2); #endif From b9b0c183204f81ae12b31ef15045ebee98a4c970 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 27 Jun 2023 14:44:01 +0900 Subject: [PATCH 088/869] common,gpg,sm,tools: Don't remove translate_sys2libc_fd_int. * common/sysutils.c (translate_sys2libc_fd_int): Recover. (translate_sys2libc_fdstr): Remove. (check_special_filename): Follow the change. * common/sysutils.h (translate_sys2libc_fd_int): Recover. (translate_sys2libc_fdstr): Remove. * g10/gpg.c, g10/gpgv.c, sm/gpgsm.c: Revert the changes. * tools/gpg-auth.c, tools/gpg-card.c, tools/gpg-pair-tool.c: Likewise. * tools/gpg-wks-client.c, tools/gpgconf.c: Likewise. -- GnuPG-bug-id: 6551 Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 44 ++++++++++++++++++------------------------ common/sysutils.h | 2 +- g10/gpg.c | 24 +++++++++++------------ g10/gpgv.c | 8 ++++---- sm/gpgsm.c | 12 ++++++------ tools/gpg-auth.c | 4 ++-- tools/gpg-card.c | 4 ++-- tools/gpg-pair-tool.c | 4 ++-- tools/gpg-wks-client.c | 4 ++-- tools/gpgconf.c | 4 ++-- 10 files changed, 52 insertions(+), 58 deletions(-) diff --git a/common/sysutils.c b/common/sysutils.c index 7c3667ce7..042387297 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -556,6 +556,24 @@ translate_sys2libc_fd (gnupg_fd_t fd, int for_write) #endif } +/* This is the same as translate_sys2libc_fd but takes an integer + which is assumed to be such an system handle. On WindowsCE the + passed FD is a rendezvous ID and the function finishes the pipe + creation. */ +int +translate_sys2libc_fd_int (int fd, int for_write) +{ +#ifdef HAVE_W32_SYSTEM + if (fd <= 2) + return fd; /* Do not do this for error, stdin, stdout, stderr. */ + + return translate_sys2libc_fd ((void*)fd, for_write); +#else + (void)for_write; + return fd; +#endif +} + /* * Parse the string representation of a file reference (file handle on @@ -636,30 +654,6 @@ gnupg_sys2libc_fdstr (const char *fdstr, int for_write, #endif } -/* This is the same as translate_sys2libc_fd but takes a string - which represents a system handle on Windows a file descriptor - on POSIX. - - (1) 0, 1, or 2 which means stdin, stdout, and stderr, respectively. - (2) Integer representation (by %d of printf). - (3) Hex representation which starts as "0x". -*/ -int -translate_sys2libc_fdstr (const char *fdstr, int for_write) -{ - gpg_error_t err; - int fd; - - err = gnupg_sys2libc_fdstr (fdstr, for_write, NULL, &fd); - if (err) - { - log_error ("FDSTR error: %s\n", fdstr); - return -1; - } - - return fd; -} - /* Check whether FNAME has the form "-&nnnn", where N is a non-zero * number. Returns this number or -1 if it is not the case. If the @@ -679,7 +673,7 @@ check_special_filename (const char *fname, int for_write, int notranslate) ; if (!fname[i]) return notranslate? atoi (fname) - /**/ : translate_sys2libc_fdstr (fname, for_write); + /**/ : translate_sys2libc_fd_int (atoi (fname), for_write); } return -1; } diff --git a/common/sysutils.h b/common/sysutils.h index 380a6d9a9..95cbc0bec 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -73,9 +73,9 @@ unsigned int get_uint_nonce (void); void gnupg_sleep (unsigned int seconds); void gnupg_usleep (unsigned int usecs); int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); +int translate_sys2libc_fd_int (int fd, int for_write); gpg_error_t gnupg_sys2libc_fdstr (const char *fdstr, int for_write, gnupg_fd_t *r_hd, int *r_fd); -int translate_sys2libc_fdstr (const char *fdstr, int for_write); int check_special_filename (const char *fname, int for_write, int notranslate); FILE *gnupg_tmpfile (void); void gnupg_reopen_std (const char *pgmname); diff --git a/g10/gpg.c b/g10/gpg.c index b766e318f..6e54aa763 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -603,7 +603,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oDisplayCharset, "charset", "@"), ARGPARSE_conffile (oOptions, "options", N_("|FILE|read options from FILE")), ARGPARSE_noconffile (oNoOptions, "no-options", "@"), - ARGPARSE_s_s (oLoggerFD, "logger-fd", "@"), + ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), ARGPARSE_s_s (oLoggerFile, "log-file", N_("|FILE|write server mode logs to FILE")), ARGPARSE_s_s (oLoggerFile, "logger-file", "@"), /* 1.4 compatibility. */ @@ -854,7 +854,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"), ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"), ARGPARSE_s_s (oOverrideSessionKey, "override-session-key", "@"), - ARGPARSE_s_s (oOverrideSessionKeyFD, "override-session-key-fd", "@"), + ARGPARSE_s_i (oOverrideSessionKeyFD, "override-session-key-fd", "@"), ARGPARSE_header ("Security", N_("Options controlling the security")), @@ -894,14 +894,14 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oNoBatch, "no-batch", "@"), ARGPARSE_s_n (oAnswerYes, "yes", "@"), ARGPARSE_s_n (oAnswerNo, "no", "@"), - ARGPARSE_s_s (oStatusFD, "status-fd", "@"), + ARGPARSE_s_i (oStatusFD, "status-fd", "@"), ARGPARSE_s_s (oStatusFile, "status-file", "@"), - ARGPARSE_s_s (oAttributeFD, "attribute-fd", "@"), + ARGPARSE_s_i (oAttributeFD, "attribute-fd", "@"), ARGPARSE_s_s (oAttributeFile, "attribute-file", "@"), - ARGPARSE_s_s (oCommandFD, "command-fd", "@"), + ARGPARSE_s_i (oCommandFD, "command-fd", "@"), ARGPARSE_s_s (oCommandFile, "command-file", "@"), ARGPARSE_o_s (oPassphrase, "passphrase", "@"), - ARGPARSE_s_s (oPassphraseFD, "passphrase-fd", "@"), + ARGPARSE_s_i (oPassphraseFD, "passphrase-fd", "@"), ARGPARSE_s_s (oPassphraseFile, "passphrase-file", "@"), ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"), ARGPARSE_s_s (oPinentryMode, "pinentry-mode", "@"), @@ -2867,19 +2867,19 @@ main (int argc, char **argv) break; case oStatusFD: - set_status_fd ( translate_sys2libc_fdstr (pargs.r.ret_str, 1) ); + set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) ); break; case oStatusFile: set_status_fd ( open_info_file (pargs.r.ret_str, 1, 0) ); break; case oAttributeFD: - set_attrib_fd ( translate_sys2libc_fdstr (pargs.r.ret_str, 1) ); + set_attrib_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) ); break; case oAttributeFile: set_attrib_fd ( open_info_file (pargs.r.ret_str, 1, 1) ); break; case oLoggerFD: - log_set_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); + log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); break; case oLoggerFile: logfile = pargs.r.ret_str; @@ -3245,7 +3245,7 @@ main (int argc, char **argv) set_passphrase_from_string (pargs.r_type ? pargs.r.ret_str : ""); break; case oPassphraseFD: - pwfd = translate_sys2libc_fdstr (pargs.r.ret_str, 0); + pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); break; case oPassphraseFile: pwfd = open_info_file (pargs.r.ret_str, 0, 1); @@ -3267,7 +3267,7 @@ main (int argc, char **argv) break; case oCommandFD: - opt.command_fd = translate_sys2libc_fdstr (pargs.r.ret_str, 0); + opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); if (! gnupg_fd_valid (opt.command_fd)) log_error ("command-fd is invalid: %s\n", strerror (errno)); break; @@ -3526,7 +3526,7 @@ main (int argc, char **argv) opt.override_session_key = pargs.r.ret_str; break; case oOverrideSessionKeyFD: - ovrseskeyfd = translate_sys2libc_fdstr (pargs.r.ret_str, 0); + ovrseskeyfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); break; case oMergeOnly: deprecated_warning(configname,pargs.lineno,"--merge-only", diff --git a/g10/gpgv.c b/g10/gpgv.c index c46cfa9b7..f2895563e 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -82,9 +82,9 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")), ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", N_("make timestamp conflicts only a warning")), - ARGPARSE_s_s (oStatusFD, "status-fd", + ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), - ARGPARSE_s_s (oLoggerFD, "logger-fd", "@"), + ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), ARGPARSE_s_s (oLoggerFile, "log-file", "@"), ARGPARSE_s_s (oHomedir, "homedir", "@"), ARGPARSE_s_s (oWeakDigest, "weak-digest", @@ -232,10 +232,10 @@ main( int argc, char **argv ) case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; case oOutput: opt.outfile = pargs.r.ret_str; break; case oStatusFD: - set_status_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); + set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); break; case oLoggerFD: - log_set_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); + log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); break; case oLoggerFile: log_set_file (pargs.r.ret_str); diff --git a/sm/gpgsm.c b/sm/gpgsm.c index ceb58a13f..07c3ff480 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -290,7 +290,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write server mode logs to FILE")), ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"), - ARGPARSE_s_s (oLoggerFD, "logger-fd", "@"), + ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), ARGPARSE_s_n (oLogTime, "log-time", "@"), ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"), @@ -422,9 +422,9 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oNoBatch, "no-batch", "@"), ARGPARSE_s_n (oAnswerYes, "yes", N_("assume yes on most questions")), ARGPARSE_s_n (oAnswerNo, "no", N_("assume no on most questions")), - ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"), - ARGPARSE_s_s (oPassphraseFD, "passphrase-fd", "@"), + ARGPARSE_s_i (oPassphraseFD, "passphrase-fd", "@"), ARGPARSE_s_s (oPinentryMode, "pinentry-mode", "@"), @@ -1156,7 +1156,7 @@ main ( int argc, char **argv) break; case oPassphraseFD: - pwfd = translate_sys2libc_fdstr (pargs.r.ret_str, 0); + pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0); break; case oPinentryMode: @@ -1300,10 +1300,10 @@ main ( int argc, char **argv) break; case oStatusFD: - ctrl.status_fd = translate_sys2libc_fdstr (pargs.r.ret_str, 1); + ctrl.status_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 1); break; case oLoggerFD: - log_set_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); + log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); break; case oWithMD5Fingerprint: opt.with_md5_fingerprint=1; /*fall through*/ diff --git a/tools/gpg-auth.c b/tools/gpg-auth.c index 6de3494ad..f433ba220 100644 --- a/tools/gpg-auth.c +++ b/tools/gpg-auth.c @@ -94,7 +94,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oVerbose, "verbose", ("verbose")), ARGPARSE_s_n (oQuiet, "quiet", ("be somewhat more quiet")), ARGPARSE_s_s (oDebug, "debug", "@"), - ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"), ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), @@ -168,7 +168,7 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) case oAgentProgram: opt.agent_program = pargs->r.ret_str; break; case oStatusFD: - gnupg_set_status_fd (translate_sys2libc_fdstr (pargs->r.ret_str, 1)); + gnupg_set_status_fd (translate_sys2libc_fd_int (pargs->r.ret_int, 1)); break; case oWithColons: opt.with_colons = 1; break; diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 24518d105..4002cc185 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -94,7 +94,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oGpgProgram, "gpg", "@"), ARGPARSE_s_s (oGpgsmProgram, "gpgsm", "@"), - ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"), ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), @@ -225,7 +225,7 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) case oAgentProgram: opt.agent_program = pargs->r.ret_str; break; case oStatusFD: - gnupg_set_status_fd (translate_sys2libc_fdstr (pargs->r.ret_str, 1)); + gnupg_set_status_fd (translate_sys2libc_fd_int (pargs->r.ret_int, 1)); break; case oWithColons: opt.with_colons = 1; break; diff --git a/tools/gpg-pair-tool.c b/tools/gpg-pair-tool.c index 069bd1668..cf9778838 100644 --- a/tools/gpg-pair-tool.c +++ b/tools/gpg-pair-tool.c @@ -179,7 +179,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oSAS, "sas", N_("|SAS|the SAS as shown by the peer")), ARGPARSE_s_s (oDebug, "debug", "@"), ARGPARSE_s_s (oOutput, "output", N_("|FILE|write the request to FILE")), - ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_s (oHomedir, "homedir", "@"), @@ -390,7 +390,7 @@ main (int argc, char **argv) break; case oStatusFD: - set_status_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); + set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); break; case oHomedir: diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index ee0554014..521222631 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -115,7 +115,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oGpgProgram, "gpg", "@"), ARGPARSE_s_n (oSend, "send", "send the mail using sendmail"), ARGPARSE_s_s (oOutput, "output", "|FILE|write the mail to FILE"), - ARGPARSE_s_s (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), + ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"), ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_s (oBlacklist, "blacklist", "@"), @@ -248,7 +248,7 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) fake_submission_addr = pargs->r.ret_str; break; case oStatusFD: - wks_set_status_fd (translate_sys2libc_fdstr (pargs->r.ret_str, 1)); + wks_set_status_fd (translate_sys2libc_fd_int (pargs->r.ret_int, 1)); break; case oWithColons: opt.with_colons = 1; diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 9738ffe97..522ce517b 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -118,7 +118,7 @@ static gpgrt_opt_t opts[] = { oQuiet, "quiet", 0, N_("quiet") }, { oDryRun, "dry-run", 0, N_("do not make any changes") }, { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") }, - ARGPARSE_s_s (oStatusFD, "status-fd", + ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), /* hidden options */ { oHomedir, "homedir", 2, "@" }, @@ -645,7 +645,7 @@ main (int argc, char **argv) case oBuilddir: gnupg_set_builddir (pargs.r.ret_str); break; case oNull: opt.null = 1; break; case oStatusFD: - set_status_fd (translate_sys2libc_fdstr (pargs.r.ret_str, 1)); + set_status_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1)); break; case oShowSocket: show_socket = 1; break; case oChUid: changeuser = pargs.r.ret_str; break; From 631c23b6640450c63bcab5e45f79d5ab8c8a930f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 27 Jun 2023 14:58:13 +0900 Subject: [PATCH 089/869] gpgtar: Use FD on POSIX. * tools/gpgtar.c (main): Fix the use of the union. -- Fixes-commit: 2756147e392c8f58fc79db6b9420b306b6ddd082 GnuPG-bug-id: 6562 Signed-off-by: NIIBE Yutaka --- tools/gpgtar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gpgtar.c b/tools/gpgtar.c index dd269043f..01efacc7d 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -544,7 +544,7 @@ main (int argc, char **argv) syshd.u.handle = hd; #else syshd.type = ES_SYSHD_FD; - syshd.u.handle = fd; + syshd.u.fd = fd; #endif opt.status_stream = es_sysopen (&syshd, "w"); if (opt.status_stream) From 7cfbf0dd72d8d5c14fbf19c13722d153bd1cbd70 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 27 Jun 2023 15:43:35 +0900 Subject: [PATCH 090/869] scd:piv: Fix authentication with Administration Key. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * scd/app-piv.c (auth_adm_key): Fix the value of the Response Tag. (do_setattr): Fix the comment. -- Reported-by: Heiko Schäfer Signed-off-by: NIIBE Yutaka --- scd/app-piv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scd/app-piv.c b/scd/app-piv.c index a51ac31ec..c8ef7b43a 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -928,7 +928,7 @@ auth_adm_key (app_t app, const unsigned char *value, size_t valuelen) tmpl[12] = 0x81; tmpl[13] = 8; gcry_create_nonce (tmpl+14, 8); - tmpl[22] = 0x80; + tmpl[22] = 0x82; tmpl[23] = 0; tmpllen = 24; xfree (outdata); @@ -1039,7 +1039,7 @@ do_setattr (app_t app, ctrl_t ctrl, const char *name, int special; /* Special mode to use for thus NAME. */ } table[] = { /* Authenticate using the PIV Card Application Administration Key - * (0x0B). Note that Yubico calls this key the "management key" + * (0x9B). Note that Yubico calls this key the "management key" * which we don't do because that term is too similar to "Cert * Management Key" (0x9D). */ { "AUTH-ADM-KEY", 0x0000, 0x0000, 1 }, From cacb01899224a4b5370b96f16f1844a1ef510b3f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 28 Jun 2023 13:59:52 +0900 Subject: [PATCH 091/869] tools:gpgtar: Clean up the use of --status-fd. * common/sysutils.c (gnupg_parse_fdstr): Rename from gnupg_sys2libc_fdstr, as there is no translation any more. * common/sysutils.h (gnupg_parse_fdstr): Rename from gnupg_sys2libc_fdstr. * tools/gpgtar.c (main): Use gnupg_parse_fdstr, in cleaner way. -- GnuPG-bug-id: 6562 Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 32 ++++++++------------------------ common/sysutils.h | 3 +-- tools/gpgtar.c | 31 ++++++------------------------- 3 files changed, 15 insertions(+), 51 deletions(-) diff --git a/common/sysutils.c b/common/sysutils.c index 042387297..5dfbb72e7 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -584,20 +584,11 @@ translate_sys2libc_fd_int (int fd, int for_write) * (2) Integer representation (by %d of printf). * (3) Hex representation which starts as "0x". * - * FOR_WRITE is 1 for a file for writing, 0 otherwise. - * - * There are two use cases for the function: - * - * - R_HD != NULL, R_FD == NULL: - * Return the value in *R_HD. - * - * - R_HD == NULL, R_FD != NULL: - * Return the value in *R_FD, after translating to a file descriptor. + * Then, fill R_SYSHD, according to the value of a file reference. * */ gpg_error_t -gnupg_sys2libc_fdstr (const char *fdstr, int for_write, - gnupg_fd_t *r_hd, int *r_fd) +gnupg_parse_fdstr (const char *fdstr, es_syshd_t *r_syshd) { int fd = -1; #ifdef HAVE_W32_SYSTEM @@ -614,10 +605,8 @@ gnupg_sys2libc_fdstr (const char *fdstr, int for_write, if (fd >= 0) { - if (r_hd) - *r_hd = (gnupg_fd_t)(uintptr_t)fd; - else if (r_fd) - *r_fd = fd; + r_syshd->type = ES_SYSHD_FD; + r_syshd->u.fd = fd; return 0; } @@ -638,18 +627,13 @@ gnupg_sys2libc_fdstr (const char *fdstr, int for_write, if (errno != 0 || endptr == fdstr || *endptr != '\0') return gpg_error (GPG_ERR_INV_ARG); - if (r_hd) - *r_hd = hd; - else if (r_fd) - *r_fd = translate_sys2libc_fd (hd, for_write); + r_syshd->type = ES_SYSHD_HANDLE; + r_syshd->u.handle = hd; return 0; #else - (void)for_write; fd = atoi (fdstr); - if (r_hd) - *r_hd = fd; - else if (r_fd) - *r_fd = fd; + r_syshd->type = ES_SYSHD_FD; + r_syshd->u.fd = fd; return 0; #endif } diff --git a/common/sysutils.h b/common/sysutils.h index 95cbc0bec..7fd01bae1 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -74,8 +74,7 @@ void gnupg_sleep (unsigned int seconds); void gnupg_usleep (unsigned int usecs); int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); int translate_sys2libc_fd_int (int fd, int for_write); -gpg_error_t gnupg_sys2libc_fdstr (const char *fdstr, int for_write, - gnupg_fd_t *r_hd, int *r_fd); +gpg_error_t gnupg_parse_fdstr (const char *fdstr, es_syshd_t *r_syshd); int check_special_filename (const char *fname, int for_write, int notranslate); FILE *gnupg_tmpfile (void); void gnupg_reopen_std (const char *pgmname); diff --git a/tools/gpgtar.c b/tools/gpgtar.c index 01efacc7d..ace5e5978 100644 --- a/tools/gpgtar.c +++ b/tools/gpgtar.c @@ -511,49 +511,30 @@ main (int argc, char **argv) * status fd is passed verbatim to gpg. */ if (opt.status_fd) { - int fd = -1; + es_syshd_t syshd; -#ifdef HAVE_W32_SYSTEM - gnupg_fd_t hd; - - err = gnupg_sys2libc_fdstr (opt.status_fd, 1, &hd, NULL); - if ((uintptr_t)hd == 1) - fd = 1; - else if ((uintptr_t)hd == 2) - fd = 2; -#else - err = gnupg_sys2libc_fdstr (opt.status_fd, 1, NULL, &fd); -#endif + err = gnupg_parse_fdstr (opt.status_fd, &syshd); if (err) log_fatal ("status-fd is invalid: %s\n", gpg_strerror (err)); - if (fd == 1) + if (syshd.type == ES_SYSHD_FD && syshd.u.fd == 1) { opt.status_stream = es_stdout; if (!skip_crypto) log_fatal ("using stdout for the status-fd is not possible\n"); } - else if (fd == 2) + else if (syshd.type == ES_SYSHD_FD && syshd.u.fd == 2) opt.status_stream = es_stderr; else { - es_syshd_t syshd; - -#ifdef HAVE_W32_SYSTEM - syshd.type = ES_SYSHD_HANDLE; - syshd.u.handle = hd; -#else - syshd.type = ES_SYSHD_FD; - syshd.u.fd = fd; -#endif opt.status_stream = es_sysopen (&syshd, "w"); if (opt.status_stream) es_setvbuf (opt.status_stream, NULL, _IOLBF, 0); } if (!opt.status_stream) { - log_fatal ("can't open fd %d for status output: %s\n", - fd, strerror (errno)); + log_fatal ("can't open fd %s for status output: %s\n", + opt.status_fd, strerror (errno)); } } From 25b59cf6ce86dcd50845cdd2e1cf0645531e7a46 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 27 Jun 2023 15:43:35 +0900 Subject: [PATCH 092/869] scd:piv: Fix authentication with Administration Key. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * scd/app-piv.c (auth_adm_key): Fix the value of the Response Tag. (do_setattr): Fix the comment. -- Cherry-pick master commit of: 7cfbf0dd72d8d5c14fbf19c13722d153bd1cbd70 Reported-by: Heiko Schäfer Signed-off-by: NIIBE Yutaka --- scd/app-piv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scd/app-piv.c b/scd/app-piv.c index a51ac31ec..c8ef7b43a 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -928,7 +928,7 @@ auth_adm_key (app_t app, const unsigned char *value, size_t valuelen) tmpl[12] = 0x81; tmpl[13] = 8; gcry_create_nonce (tmpl+14, 8); - tmpl[22] = 0x80; + tmpl[22] = 0x82; tmpl[23] = 0; tmpllen = 24; xfree (outdata); @@ -1039,7 +1039,7 @@ do_setattr (app_t app, ctrl_t ctrl, const char *name, int special; /* Special mode to use for thus NAME. */ } table[] = { /* Authenticate using the PIV Card Application Administration Key - * (0x0B). Note that Yubico calls this key the "management key" + * (0x9B). Note that Yubico calls this key the "management key" * which we don't do because that term is too similar to "Cert * Management Key" (0x9D). */ { "AUTH-ADM-KEY", 0x0000, 0x0000, 1 }, From c926967d8558df114e14ba40595093d522d049a9 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 22 Jun 2023 18:42:55 +0200 Subject: [PATCH 093/869] sm: Remove duplicated code. * sm/minip12.c (struct tag_info): Change type of length and nhdr. (dump_tag_info): Adjust. (parse_tag): Re-implement using the parse_ber_header. --- common/tlv.c | 9 +++-- sm/minip12.c | 109 +++++++++++++-------------------------------------- 2 files changed, 34 insertions(+), 84 deletions(-) diff --git a/common/tlv.c b/common/tlv.c index 4cc1dc7cf..4ba9ef20d 100644 --- a/common/tlv.c +++ b/common/tlv.c @@ -150,13 +150,16 @@ find_tlv_unchecked (const unsigned char *buffer, size_t length, /* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag - and the length part from the TLV triplet. Update BUFFER and SIZE - on success. */ + * and the length part from the TLV triplet. Update BUFFER and SIZE + * on success. Note that this function does not check that the value + * fits into the provided buffer; this allows to work on the TL part + * of a TLV. */ gpg_error_t parse_ber_header (unsigned char const **buffer, size_t *size, int *r_class, int *r_tag, int *r_constructed, int *r_ndef, - size_t *r_length, size_t *r_nhdr){ + size_t *r_length, size_t *r_nhdr) +{ int c; unsigned long tag; const unsigned char *buf = *buffer; diff --git a/sm/minip12.c b/sm/minip12.c index 29b48984e..695c60ff1 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -138,8 +138,8 @@ struct tag_info int class; int is_constructed; unsigned long tag; - unsigned long length; /* length part of the TLV */ - int nhdr; + size_t length; /* length part of the TLV */ + size_t nhdr; int ndef; /* It is an indefinite length */ }; @@ -174,14 +174,17 @@ p12_set_verbosity (int verbose) } -/* static void */ -/* dump_tag_info (struct tag_info *ti) */ -/* { */ -/* log_debug ("p12_parse: ti.class=%d tag=%lu len=%lu nhdr=%d %s%s\n", */ -/* ti->class, ti->tag, ti->length, ti->nhdr, */ -/* ti->is_constructed?" cons":"", */ -/* ti->ndef?" ndef":""); */ -/* } */ +#if 0 +static void +dump_tag_info (const char *text, struct tag_info *ti) +{ + log_debug ("p12_parse(%s): ti.class=%d tag=%lu len=%zu nhdr=%zu %s%s\n", + text, + ti->class, ti->tag, ti->length, ti->nhdr, + ti->is_constructed?" cons":"", + ti->ndef?" ndef":""); +} +#endif /* Wrapper around tlv_builder_add_ptr to add an OID. When we @@ -277,84 +280,28 @@ builder_add_mpi (tlv_builder_t tb, int class, int tag, gcry_mpi_t mpi, /* Parse the buffer at the address BUFFER which is of SIZE and return - the tag and the length part from the TLV triplet. Update BUFFER - and SIZE on success. Checks that the encoded length does not - exhaust the length of the provided buffer. */ + * the tag and the length part from the TLV triplet. Update BUFFER + * and SIZE on success. Checks that the encoded length does not + * exhaust the length of the provided buffer. */ static int parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti) { - int c; - unsigned long tag; - const unsigned char *buf = *buffer; - size_t length = *size; + gpg_error_t err; + int tag; - ti->length = 0; - ti->ndef = 0; - ti->nhdr = 0; - - /* Get the tag */ - if (!length) - return -1; /* premature eof */ - c = *buf++; length--; - ti->nhdr++; - - ti->class = (c & 0xc0) >> 6; - ti->is_constructed = !!(c & 0x20); - tag = c & 0x1f; - - if (tag == 0x1f) - { - tag = 0; - do - { - tag <<= 7; - if (!length) - return -1; /* premature eof */ - c = *buf++; length--; - ti->nhdr++; - tag |= c & 0x7f; - } - while (c & 0x80); - } + err = parse_ber_header (buffer, size, + &ti->class, &tag, + &ti->is_constructed, &ti->ndef, + &ti->length, &ti->nhdr); + if (err) + return err; + if (tag < 0) + return gpg_error (GPG_ERR_EOVERFLOW); ti->tag = tag; - /* Get the length */ - if (!length) - return -1; /* prematureeof */ - c = *buf++; length--; - ti->nhdr++; + if (ti->length > *size) + return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); /* data larger than buffer. */ - if ( !(c & 0x80) ) - ti->length = c; - else if (c == 0x80) - ti->ndef = 1; - else if (c == 0xff) - return -1; /* forbidden length value */ - else - { - unsigned long len = 0; - int count = c & 0x7f; - - for (; count; count--) - { - len <<= 8; - if (!length) - return -1; /* premature_eof */ - c = *buf++; length--; - ti->nhdr++; - len |= c & 0xff; - } - ti->length = len; - } - - if (ti->class == CLASS_UNIVERSAL && !ti->tag) - ti->length = 0; - - if (ti->length > length) - return -1; /* data larger than buffer. */ - - *buffer = buf; - *size = length; return 0; } From 101433dfb42b333e48427baf9dd58ac4787c9786 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 28 Jun 2023 17:33:24 +0200 Subject: [PATCH 094/869] sm: Major rewrite of the PKCS#12 parser * sm/minip12.c: Reworked most of the parser. (p12_set_verbosity): Add arg debug and change all callers. * sm/t-minip12.c: Major rewrite to run regression tests unattended. * sm/Makefile.am (module_maint_tests): Move t-Minit to ... (module_tests): here. * tests/cms/samplekeys/Description-p12: New. -- Note that cram_octet_string stuff has not yet been reworked. I need to locate the sample files first. GnuPG-bug-id: 6536 --- sm/Makefile.am | 4 +- sm/gpgsm.c | 2 +- sm/minip12.c | 2043 ++++++++++++++++---------- sm/minip12.h | 2 +- sm/t-minip12.c | 742 +++++++++- tests/cms/samplekeys/Description-p12 | 20 + tests/cms/samplekeys/README | 8 +- 7 files changed, 1951 insertions(+), 870 deletions(-) create mode 100644 tests/cms/samplekeys/Description-p12 diff --git a/sm/Makefile.am b/sm/Makefile.am index 03de7026a..ee728e851 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -77,8 +77,8 @@ gpgsm_LDFLAGS = gpgsm_DEPENDENCIES = $(resource_objs) -module_tests = -module_maint_tests = t-minip12 +module_tests = t-minip12 +module_maint_tests = t_common_src = t_common_ldadd = $(libcommon) $(LIBGCRYPT_LIBS) $(KSBA_LIBS) \ diff --git a/sm/gpgsm.c b/sm/gpgsm.c index ad7652c7d..ce977413d 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -804,7 +804,7 @@ set_debug (void) /* minip12.c may be used outside of GnuPG, thus we don't have the * opt structure over there. */ - p12_set_verbosity (opt.verbose); + p12_set_verbosity (opt.verbose, opt.debug); } diff --git a/sm/minip12.c b/sm/minip12.c index 695c60ff1..69e23455a 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -1,7 +1,7 @@ /* minip12.c - A minimal pkcs-12 implementation. * Copyright (C) 2002, 2003, 2004, 2006, 2011 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch - * Copyright (C) 2022 g10 Code GmbH + * Copyright (C) 2022, 2023 g10 Code GmbH * * This file is part of GnuPG. * @@ -78,6 +78,8 @@ static unsigned char const oid_pkcs5PBES2[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0D }; static unsigned char const oid_aes128_CBC[9] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02 }; +static unsigned char const oid_aes256_CBC[9] = { + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2A }; static unsigned char const oid_rsaEncryption[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }; @@ -143,6 +145,35 @@ struct tag_info int ndef; /* It is an indefinite length */ }; + +#define TLV_MAX_DEPTH 20 + +/* An object to control the ASN.1 parsing. */ +struct tlv_ctx_s +{ + /* The current buffer we are working on and its length. */ + const unsigned char *buffer; + size_t bufsize; + + size_t offset; /* The current offset into this buffer. */ + int in_ndef; /* Flag indicating that we are in a NDEF. */ + int pending; /* The last tlv_next has not yet been processed. */ + + struct tag_info ti; /* The current tag. */ + gpg_error_t lasterr; /* Last error from tlv function. */ + const char *lastfunc;/* Name of last called function. */ + + unsigned int pop_count;/* Number of pops by tlv_next. */ + unsigned int stacklen; /* Used size of the stack. */ + struct { + const unsigned char *buffer; /* Saved value of BUFFER. */ + size_t bufsize; /* Saved value of BUFSIZE. */ + size_t offset; /* Saved value of OFFSET. */ + int in_ndef; /* Saved IN_NDEF flag. */ + } stack[TLV_MAX_DEPTH]; +}; + + /* Parser communication object. */ struct p12_parse_ctx_s { @@ -168,23 +199,24 @@ static int opt_verbose; void -p12_set_verbosity (int verbose) +p12_set_verbosity (int verbose, int debug) { - opt_verbose = verbose; + opt_verbose = !!verbose; + if (debug) + opt_verbose = 2; } -#if 0 static void dump_tag_info (const char *text, struct tag_info *ti) { - log_debug ("p12_parse(%s): ti.class=%d tag=%lu len=%zu nhdr=%zu %s%s\n", - text, - ti->class, ti->tag, ti->length, ti->nhdr, - ti->is_constructed?" cons":"", - ti->ndef?" ndef":""); + if (opt_verbose > 1) + log_debug ("p12_parse(%s): ti.class=%d tag=%lu len=%zu nhdr=%zu %s%s\n", + text, + ti->class, ti->tag, ti->length, ti->nhdr, + ti->is_constructed?" cons":"", + ti->ndef?" ndef":""); } -#endif /* Wrapper around tlv_builder_add_ptr to add an OID. When we @@ -279,6 +311,7 @@ builder_add_mpi (tlv_builder_t tb, int class, int tag, gcry_mpi_t mpi, } + /* Parse the buffer at the address BUFFER which is of SIZE and return * the tag and the length part from the TLV triplet. Update BUFFER * and SIZE on success. Checks that the encoded length does not @@ -306,6 +339,382 @@ parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti) } +/* Create a new TLV object. */ +static struct tlv_ctx_s * +tlv_new (const unsigned char *buffer, size_t bufsize) +{ + struct tlv_ctx_s *tlv; + tlv = xtrycalloc (1, sizeof *tlv); + if (tlv) + { + tlv->buffer = buffer; + tlv->bufsize = bufsize; + } + return tlv; +} + + +static void +tlv_release (struct tlv_ctx_s *tlv) +{ + xfree (tlv); +} + + +/* Helper for tlv_next and tlv_peek. */ +static gpg_error_t +_tlv_peek (struct tlv_ctx_s *tlv, size_t *r_n) +{ + const unsigned char *p; + + if (tlv->offset > tlv->bufsize) + return gpg_error (GPG_ERR_BUG); + p = tlv->buffer + tlv->offset; + *r_n = tlv->bufsize - tlv->offset; + return parse_tag (&p, r_n, &tlv->ti); +} + + +/* Helper for tlv_expect_sequence and tlv_expect_context_tag. */ +static gpg_error_t +_tlv_push (struct tlv_ctx_s *tlv) +{ + if (tlv->stacklen >= TLV_MAX_DEPTH) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_MANY)); + tlv->stack[tlv->stacklen].buffer = tlv->buffer; + tlv->stack[tlv->stacklen].bufsize = tlv->bufsize; + tlv->stack[tlv->stacklen].offset = tlv->offset; + tlv->stack[tlv->stacklen].in_ndef = tlv->in_ndef; + tlv->stacklen++; + tlv->buffer += tlv->offset; + tlv->bufsize = tlv->ti.length; + tlv->offset = 0; + tlv->in_ndef = tlv->ti.ndef; + return 0; +} + + +/* Helper for tlv_next. */ +static gpg_error_t +_tlv_pop (struct tlv_ctx_s *tlv) +{ + size_t saveoff; + + if (!tlv->stacklen) + return gpg_error (GPG_ERR_EOF); + + saveoff = tlv->offset; + + tlv->stacklen--; + tlv->buffer = tlv->stack[tlv->stacklen].buffer; + tlv->bufsize = tlv->stack[tlv->stacklen].bufsize; + tlv->offset = tlv->stack[tlv->stacklen].offset; + tlv->in_ndef = tlv->stack[tlv->stacklen].in_ndef; + + /* Move offset of the container to the end of the container. */ + tlv->offset += saveoff; + if (tlv->offset > tlv->bufsize) + return gpg_error (GPG_ERR_INV_BER); + + tlv->pop_count++; + return 0; +} + + +/* Parse the next tag and value. Also detect the end of a container; + * tlv_popped() can be used to detect this. */ +static gpg_error_t +tlv_next (struct tlv_ctx_s *tlv) +{ + gpg_error_t err; + size_t n; + + tlv->pop_count = 0; + tlv->lasterr = 0; + tlv->lastfunc = __func__; + if (tlv->pending) + { + tlv->pending = 0; + return 0; + } + + if (!tlv->in_ndef && tlv->offset == tlv->bufsize) + { + /* We are at the end of a container. Pop the stack. */ + do + err = _tlv_pop (tlv); + while (!err && !tlv->in_ndef && tlv->offset == tlv->bufsize); + if (err) + return (tlv->lasterr = err); + } + + err = _tlv_peek (tlv, &n); + if (err) + return err; + if (tlv->in_ndef && (tlv->ti.class == CLASS_UNIVERSAL + && !tlv->ti.tag && !tlv->ti.is_constructed)) + { + /* End tag while in ndef container. Skip the tag, and pop. */ + tlv->offset += n - (tlv->bufsize - tlv->offset); + err = _tlv_pop (tlv); + // FIXME see above and run peek again. + if (err) + return (tlv->lasterr = err); + } + + /* Set offset to the value of the TLV. */ + tlv->offset += tlv->bufsize - tlv->offset - n; + dump_tag_info ("tlv_next", &tlv->ti); + return 0; +} + + +/* Return the current neting level of the TLV object. */ +static unsigned int +tlv_level (struct tlv_ctx_s *tlv) +{ + return tlv->stacklen; +} + + +/* If called right after tlv_next the number of container levels + * popped are returned. */ +static unsigned int +tlv_popped (struct tlv_ctx_s *tlv) +{ + return tlv->pop_count; +} + + +/* Set a flag to indicate that the last tlv_next has not yet been + * consumed. */ +static void +tlv_set_pending (struct tlv_ctx_s *tlv) +{ + tlv->pending = 1; +} + + +/* Skip over the value of the current tag. */ +static void +tlv_skip (struct tlv_ctx_s *tlv) +{ + tlv->lastfunc = __func__; + tlv->offset += tlv->ti.length; +} + + +/* Expect that the current tag is a sequence and setup the context for + * processing. */ +static gpg_error_t +tlv_expect_sequence (struct tlv_ctx_s *tlv) +{ + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_SEQUENCE + && tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + return _tlv_push (tlv); +} + +/* Variant of tlv_expect_sequence to be used for the ouyter sequence + * of an object which might have padding after the ASN.1 data. */ +static gpg_error_t +tlv_expect_top_sequence (struct tlv_ctx_s *tlv) +{ + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_SEQUENCE + && tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + tlv->bufsize = tlv->ti.nhdr + tlv->ti.length; + return _tlv_push (tlv); +} + + +/* Expect that the current tag is a context tag and setup the context + * for processing. The tag of the context is returned at R_TAG. */ +static gpg_error_t +tlv_expect_context_tag (struct tlv_ctx_s *tlv, int *r_tag) +{ + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_CONTEXT && tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + *r_tag = tlv->ti.tag; + return _tlv_push (tlv); +} + + +/* Expect that the current tag is a SET and setup the context for + * processing. */ +static gpg_error_t +tlv_expect_set (struct tlv_ctx_s *tlv) +{ + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_SET + && tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + return _tlv_push (tlv); +} + + +/* Expect an object of CLASS with TAG and store its value at + * (R_DATA,R_DATALEN). Then skip over its value to the next tag. + * Note that the stored value are not allocated but point into + * TLV. */ +static gpg_error_t +tlv_expect_object (struct tlv_ctx_s *tlv, int class, int tag, + unsigned char const **r_data, size_t *r_datalen) +{ + const unsigned char *p; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == class && tlv->ti.tag == tag + && !tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer + tlv->offset; + if (!tlv->ti.length) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + *r_data = p; + *r_datalen = tlv->ti.length; + + tlv->offset += tlv->ti.length; + return 0; +} + + +/* Expect that the current tag is an object string and store its value + * at (R_DATA,R_DATALEN). Then skip over its value to the next tag. + * Note that the stored value are not allocated but point into TLV. + * If ENCAPSULATES is set the octet string is used as a new + * container. R_DATA and R_DATALEN are optional. */ +static gpg_error_t +tlv_expect_octet_string (struct tlv_ctx_s *tlv, int encapsulates, + unsigned char const **r_data, size_t *r_datalen) +{ + const unsigned char *p; + size_t n; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_OCTET_STRING + && !tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer + tlv->offset; + if (!(n=tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + if (r_data) + *r_data = p; + if (r_datalen) + *r_datalen = tlv->ti.length; + if (encapsulates) + return _tlv_push (tlv); + + tlv->offset += tlv->ti.length; + return 0; +} + + +/* Expect a NULL tag. */ +static gpg_error_t +tlv_expect_null (struct tlv_ctx_s *tlv) +{ + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_NULL + && !tlv->ti.is_constructed && !tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + return 0; +} + + +/* Expect that the current tag is an integer and return its value at + * R_VALUE. Then skip over its value to the next tag. */ +static gpg_error_t +tlv_expect_integer (struct tlv_ctx_s *tlv, int *r_value) +{ + const unsigned char *p; + size_t n; + int value; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_INTEGER + && !tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer + tlv->offset; + if (!(n=tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + /* We currently support only positive values. */ + if ((*p & 0x80)) + return (tlv->lasterr = gpg_error (GPG_ERR_ERANGE)); + + for (value = 0; n; n--) + { + value <<= 8; + value |= (*p++) & 0xff; + if (value < 0) + return (tlv->lasterr = gpg_error (GPG_ERR_EOVERFLOW)); + } + *r_value = value; + tlv->offset += tlv->ti.length; + return 0; +} + + +/* Variant of tlv_expect_integer which returns an MPI. If IGNORE_ZERO + * is set a value of 0 is ignored and R_VALUE not changed and the + * function returns GPG_ERR_FALSE. No check for negative encoded + * integers is doe because the old code here worked the same and we + * can't foreclose invalid encoded PKCS#12 stuff - after all it is + * PKCS#12 see https://www.cs.auckland.ac.nz/~pgut001/pubs/pfx.html */ +static gpg_error_t +tlv_expect_mpinteger (struct tlv_ctx_s *tlv, int ignore_zero, + gcry_mpi_t *r_value) +{ + const unsigned char *p; + size_t n; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_INTEGER + && !tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer + tlv->offset; + if (!(n=tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + tlv->offset += tlv->ti.length; + if (ignore_zero && n == 1 && !*p) + return gpg_error (GPG_ERR_FALSE); + + return gcry_mpi_scan (r_value, GCRYMPI_FMT_USG, p, n, NULL); +} + + +/* Expect that the current tag is an object id and store its value at + * (R_OID,R_OIDLEN). Then skip over its value to the next tag. Note + * that the stored value is not allocated but points into TLV. */ +static gpg_error_t +tlv_expect_object_id (struct tlv_ctx_s *tlv, + unsigned char const **r_oid, size_t *r_oidlen) +{ + const unsigned char *p; + size_t n; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_OBJECT_ID + && !tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer + tlv->offset; + if (!(n=tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + *r_oid = p; + *r_oidlen = tlv->ti.length; + tlv->offset += tlv->ti.length; + return 0; +} + + + /* Given an ASN.1 chunk of a structure like: 24 NDEF: OCTET STRING -- This is not passed to us @@ -561,7 +970,7 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen, return; } - if (cipher_algo == GCRY_CIPHER_AES128 + if ((cipher_algo == GCRY_CIPHER_AES128 || cipher_algo == GCRY_CIPHER_AES256) ? set_key_iv_pbes2 (chd, salt, saltlen, iter, iv, ivlen, pw, cipher_algo) : set_key_iv (chd, salt, saltlen, iter, pw, cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24)) @@ -708,482 +1117,508 @@ bag_decrypted_data_p (const void *plaintext, size_t length) static int -parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, - const unsigned char *buffer, size_t length, - int startoffset, size_t *r_consumed) +parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) { - struct tag_info ti; - const unsigned char *p = buffer; - const unsigned char *p_start = buffer; - size_t n = length; + gpg_error_t err = 0; const char *where; + const unsigned char *oid; + size_t oidlen; + const unsigned char *data; + size_t datalen; + int intval; char salt[20]; size_t saltlen; char iv[16]; unsigned int iter; unsigned char *plain = NULL; - unsigned char *cram_buffer = NULL; - size_t consumed = 0; /* Number of bytes consumed from the original buffer. */ int is_3des = 0; int is_pbes2 = 0; + int is_aes256 = 0; int keyelem_count; + int renewed_tlv = 0; + int loopcount; + unsigned int startlevel; - where = "start"; - if (parse_tag (&p, &n, &ti)) + where = "bag.encryptedData"; + if (opt_verbose) + log_info ("processing %s\n", where); + + if (tlv_next (tlv)) goto bailout; - if (ti.class != CLASS_CONTEXT || ti.tag) + if (tlv_expect_context_tag (tlv, &intval) || intval != 0 ) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; where = "bag.encryptedData.version"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 0) + if ((err = tlv_expect_integer (tlv, &intval))) goto bailout; - p++; n--; - if (parse_tag (&p, &n, &ti)) + if (intval) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto bailout; + } + + if (tlv_next (tlv)) goto bailout; - if (ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; where = "bag.encryptedData.data"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data) - || memcmp (p, oid_data, DIM(oid_data))) + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + if (oidlen != DIM(oid_data) || memcmp (oid, oid_data, DIM(oid_data))) goto bailout; - p += DIM(oid_data); - n -= DIM(oid_data); where = "bag.encryptedData.keyinfo"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (!ti.class && ti.tag == TAG_OBJECT_ID - && ti.length == DIM(oid_pbeWithSHAAnd40BitRC2_CBC) - && !memcmp (p, oid_pbeWithSHAAnd40BitRC2_CBC, - DIM(oid_pbeWithSHAAnd40BitRC2_CBC))) - { - p += DIM(oid_pbeWithSHAAnd40BitRC2_CBC); - n -= DIM(oid_pbeWithSHAAnd40BitRC2_CBC); - } - else if (!ti.class && ti.tag == TAG_OBJECT_ID - && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC) - && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC, - DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC))) - { - p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); - n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); - is_3des = 1; - } - else if (!ti.class && ti.tag == TAG_OBJECT_ID - && ti.length == DIM(oid_pkcs5PBES2) - && !memcmp (p, oid_pkcs5PBES2, ti.length)) - { - p += ti.length; - n -= ti.length; - is_pbes2 = 1; - } - else + if (tlv_expect_sequence (tlv)) goto bailout; + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + if (oidlen == DIM(oid_pbeWithSHAAnd40BitRC2_CBC) + && !memcmp (oid, oid_pbeWithSHAAnd40BitRC2_CBC, + DIM(oid_pbeWithSHAAnd40BitRC2_CBC))) + ; + else if (oidlen == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC) + && !memcmp (oid, oid_pbeWithSHAAnd3_KeyTripleDES_CBC, + DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC))) + is_3des = 1; + else if (oidlen == DIM(oid_pkcs5PBES2) + && !memcmp (oid, oid_pkcs5PBES2, oidlen)) + is_pbes2 = 1; + else + { + err = gpg_error (GPG_ERR_UNKNOWN_ALGORITHM); + goto bailout; + } + + /*FIXME: This code is duplicated in parse_shrouded_key_bag. */ if (is_pbes2) { where = "pkcs5PBES2-params"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (!(!ti.class && ti.tag == TAG_OBJECT_ID - && ti.length == DIM(oid_pkcs5PBKDF2) - && !memcmp (p, oid_pkcs5PBKDF2, ti.length))) - goto bailout; /* Not PBKDF2. */ - p += ti.length; - n -= ti.length; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (!(!ti.class && ti.tag == TAG_OCTET_STRING - && ti.length >= 8 && ti.length < sizeof salt)) - goto bailout; /* No salt or unsupported length. */ - saltlen = ti.length; - memcpy (salt, p, saltlen); - p += saltlen; - n -= saltlen; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (!(!ti.class && ti.tag == TAG_INTEGER && ti.length)) - goto bailout; /* No valid iteration count. */ - for (iter=0; ti.length; ti.length--) + if (tlv_expect_sequence (tlv)) + goto bailout; + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + if (oidlen != DIM(oid_pkcs5PBKDF2) + || memcmp (oid, oid_pkcs5PBKDF2, oidlen)) { - iter <<= 8; - iter |= (*p++) & 0xff; - n--; + err = gpg_error (GPG_ERR_INV_BER); /* Not PBKDF2. */ + goto bailout; } + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_sequence (tlv)) + goto bailout; + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) + goto bailout; + if (datalen < 8 || datalen > sizeof salt) + { + log_info ("bad length of salt (%zu)\n", datalen); + err = gpg_error (GPG_ERR_INV_LENGTH); + goto bailout; + } + saltlen = datalen; + memcpy (salt, data, saltlen); + + if (tlv_next (tlv)) + goto bailout; + if ((err = tlv_expect_integer (tlv, &intval))) + goto bailout; + if (!intval) /* Not a valid iteration count. */ + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto bailout; + } + iter = intval; + /* Note: We don't support the optional parameters but assume that the algorithmIdentifier follows. */ - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (!(!ti.class && ti.tag == TAG_OBJECT_ID - && ti.length == DIM(oid_aes128_CBC) - && !memcmp (p, oid_aes128_CBC, ti.length))) - goto bailout; /* Not AES-128. */ - p += ti.length; - n -= ti.length; - if (parse_tag (&p, &n, &ti)) + if (tlv_expect_object_id (tlv, &oid, &oidlen)) goto bailout; - if (!(!ti.class && ti.tag == TAG_OCTET_STRING && ti.length == sizeof iv)) - goto bailout; /* Bad IV. */ - memcpy (iv, p, sizeof iv); - p += sizeof iv; - n -= sizeof iv; + + if (oidlen == DIM(oid_aes128_CBC) + && !memcmp (oid, oid_aes128_CBC, oidlen)) + ; + else if (oidlen == DIM(oid_aes256_CBC) + && !memcmp (oid, oid_aes256_CBC, oidlen)) + is_aes256 = 1; + else + { + gpgrt_log_printhex (oid, oidlen, "cipher algo:"); + err = gpg_error (GPG_ERR_CIPHER_ALGO); + goto bailout; + } + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) + goto bailout; + if (datalen != sizeof iv) + { + err = gpg_error (GPG_ERR_INV_LENGTH); + goto bailout; /* Bad IV. */ + } + memcpy (iv, data, datalen); } else { where = "rc2or3des-params"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING - || ti.length < 8 || ti.length > 20 ) + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; - saltlen = ti.length; - memcpy (salt, p, saltlen); - p += saltlen; - n -= saltlen; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_INTEGER || !ti.length ) - goto bailout; - for (iter=0; ti.length; ti.length--) + if (datalen < 8 || datalen > 20) { - iter <<= 8; - iter |= (*p++) & 0xff; - n--; + log_info ("bad length of salt (%zu) for 3DES\n", datalen); + err = gpg_error (GPG_ERR_INV_LENGTH); + goto bailout; } + saltlen = datalen; + memcpy (salt, data, saltlen); + + if (tlv_next (tlv)) + goto bailout; + if ((err = tlv_expect_integer (tlv, &intval))) + goto bailout; + if (!intval) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto bailout; + } + iter = intval; } where = "rc2or3desoraes-ciphertext"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - consumed = p - p_start; - if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef) - { - /* Mozilla exported certs now come with single byte chunks of - octet strings. (Mozilla Firefox 1.0.4). Arghh. */ - where = "cram-rc2or3des-ciphertext"; - cram_buffer = cram_octet_string ( p, &n, &consumed); - if (!cram_buffer) - goto bailout; - p = p_start = cram_buffer; - if (r_consumed) - *r_consumed = consumed; - r_consumed = NULL; /* Donot update that value on return. */ - ti.length = n; - } - else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed) - { - where = "octets-rc2or3des-ciphertext"; - n = ti.length; - cram_buffer = cram_octet_string ( p, &n, &consumed); - if (!cram_buffer) - goto bailout; - p = p_start = cram_buffer; - if (r_consumed) - *r_consumed = consumed; - r_consumed = NULL; /* Do not update that value on return. */ - ti.length = n; - } - else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.length ) - ; - else + /* consumed = p - p_start; */ + /* if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef) */ + /* { */ + /* /\* Mozilla exported certs now come with single byte chunks of */ + /* octet strings. (Mozilla Firefox 1.0.4). Arghh. *\/ */ + /* where = "cram-rc2or3des-ciphertext"; */ + /* cram_buffer = cram_octet_string ( p, &n, &consumed); */ + /* if (!cram_buffer) */ + /* goto bailout; */ + /* p = p_start = cram_buffer; */ + /* if (r_consumed) */ + /* *r_consumed = consumed; */ + /* r_consumed = NULL; /\* Donot update that value on return. *\/ */ + /* ti.length = n; */ + /* } */ + /* else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed) */ + /* { */ + /* where = "octets-rc2or3des-ciphertext"; */ + /* n = ti.length; */ + /* cram_buffer = cram_octet_string ( p, &n, &consumed); */ + /* if (!cram_buffer) */ + /* goto bailout; */ + /* p = p_start = cram_buffer; */ + /* if (r_consumed) */ + /* *r_consumed = consumed; */ + /* r_consumed = NULL; /\* Do not update that value on return. *\/ */ + /* ti.length = n; */ + /* } */ + /* else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.length ) */ + /* ; */ + /* else */ + /* goto bailout; */ + if (tlv_expect_object (tlv, CLASS_CONTEXT, 0, &data, &datalen)) goto bailout; if (opt_verbose) - log_info ("%lu bytes of %s encrypted text\n",ti.length, - is_pbes2?"AES128":is_3des?"3DES":"RC2"); + log_info ("%zu bytes of %s encrypted text\n", datalen, + is_pbes2?(is_aes256?"AES256":"AES128"):is_3des?"3DES":"RC2"); - plain = gcry_malloc_secure (ti.length); + plain = gcry_malloc_secure (datalen); if (!plain) { + err = gpg_error_from_syserror (); log_error ("error allocating decryption buffer\n"); goto bailout; } - decrypt_block (p, plain, ti.length, salt, saltlen, iter, + decrypt_block (data, plain, datalen, salt, saltlen, iter, iv, is_pbes2?16:0, ctx->password, - is_pbes2 ? GCRY_CIPHER_AES128 : + is_pbes2 ? (is_aes256?GCRY_CIPHER_AES256:GCRY_CIPHER_AES128) : is_3des ? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40, bag_decrypted_data_p); - n = ti.length; - startoffset = 0; - p_start = p = plain; - where = "outer.outer.seq"; - if (parse_tag (&p, &n, &ti)) + /* We do not need the TLV anymore and allocated a new one. */ + where = "bag.encryptedData.decrypted-text"; + tlv = tlv_new (plain, datalen); + if (!tlv) + { + err = gpg_error_from_syserror (); + goto bailout; + } + renewed_tlv = 1; + + if (tlv_next (tlv)) { ctx->badpass = 1; goto bailout; } - if (ti.class || ti.tag != TAG_SEQUENCE) - { - ctx->badpass = 1; - goto bailout; - } - - if (parse_tag (&p, &n, &ti)) + if (tlv_expect_top_sequence (tlv)) { ctx->badpass = 1; goto bailout; } /* Loop over all certificates inside the bag. */ - while (n) + loopcount = 0; + startlevel = tlv_level (tlv); + while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) { int iscrlbag = 0; int iskeybag = 0; + loopcount++; where = "certbag.nextcert"; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - where = "certbag.objectidentifier"; - if (parse_tag (&p, &n, &ti)) + where = "certbag.oid"; + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_OBJECT_ID) + if (tlv_expect_object_id (tlv, &oid, &oidlen)) goto bailout; - if ( ti.length == DIM(oid_pkcs_12_CertBag) - && !memcmp (p, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag))) - { - p += DIM(oid_pkcs_12_CertBag); - n -= DIM(oid_pkcs_12_CertBag); - } - else if ( ti.length == DIM(oid_pkcs_12_CrlBag) - && !memcmp (p, oid_pkcs_12_CrlBag, DIM(oid_pkcs_12_CrlBag))) - { - p += DIM(oid_pkcs_12_CrlBag); - n -= DIM(oid_pkcs_12_CrlBag); - iscrlbag = 1; - } - else if ( ti.length == DIM(oid_pkcs_12_keyBag) - && !memcmp (p, oid_pkcs_12_keyBag, DIM(oid_pkcs_12_keyBag))) + if (oidlen == DIM(oid_pkcs_12_CertBag) + && !memcmp (oid, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag))) + ; + else if (oidlen == DIM(oid_pkcs_12_CrlBag) + && !memcmp (oid, oid_pkcs_12_CrlBag, DIM(oid_pkcs_12_CrlBag))) + iscrlbag = 1; + else if (oidlen == DIM(oid_pkcs_12_keyBag) + && !memcmp (oid, oid_pkcs_12_keyBag, DIM(oid_pkcs_12_keyBag))) { /* The TrustedMIME plugin for MS Outlook started to create files with just one outer 3DES encrypted container and inside the certificates as well as the key. */ - p += DIM(oid_pkcs_12_keyBag); - n -= DIM(oid_pkcs_12_keyBag); iskeybag = 1; } else - goto bailout; + { + gpgrt_log_printhex (oid, oidlen, "cert bag type OID:"); + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto bailout; + } where = "certbag.before.certheader"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class != CLASS_CONTEXT || ti.tag) + if (tlv_expect_context_tag (tlv, &intval) || intval != 0 ) goto bailout; + if (iscrlbag) { log_info ("skipping unsupported crlBag\n"); - p += ti.length; - n -= ti.length; } else if (iskeybag && ctx->privatekey) { log_info ("one keyBag already processed; skipping this one\n"); - p += ti.length; - n -= ti.length; } else if (iskeybag) { - int len; - if (opt_verbose) log_info ("processing simple keyBag\n"); - /* Fixme: This code is duplicated from parse_bag_data. */ - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_next (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER - || ti.length != 1 || *p) + if (tlv_expect_sequence (tlv)) goto bailout; - p++; n--; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - len = ti.length; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (len < ti.nhdr) - goto bailout; - len -= ti.nhdr; - if (ti.class || ti.tag != TAG_OBJECT_ID - || ti.length != DIM(oid_rsaEncryption) - || memcmp (p, oid_rsaEncryption, - DIM(oid_rsaEncryption))) - goto bailout; - p += DIM (oid_rsaEncryption); - n -= DIM (oid_rsaEncryption); - if (len < ti.length) - goto bailout; - len -= ti.length; - if (n < len) - goto bailout; - p += len; - n -= len; - if ( parse_tag (&p, &n, &ti) - || ti.class || ti.tag != TAG_OCTET_STRING) - goto bailout; - if ( parse_tag (&p, &n, &ti) - || ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - len = ti.length; - log_assert (!ctx->privatekey); + if (tlv_next (tlv)) + goto bailout; + if ((err = tlv_expect_integer (tlv, &intval))) + goto bailout; + if (intval) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto bailout; + } + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_sequence (tlv)) + goto bailout; + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + if (oidlen != DIM(oid_rsaEncryption) + || memcmp (oid, oid_rsaEncryption, oidlen)) + { + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + goto bailout; + } + + /* We ignore the next octet string. */ + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) + goto bailout; + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_sequence (tlv)) + goto bailout; + + if (ctx->privatekey) + { + err = gpg_error (GPG_ERR_DUP_VALUE); + log_error ("a private key has already been received\n"); + goto bailout; + } ctx->privatekey = gcry_calloc (10, sizeof *ctx->privatekey); if (!ctx->privatekey) { + err = gpg_error_from_syserror (); log_error ("error allocating private key element array\n"); goto bailout; } - keyelem_count = 0; where = "reading.keybag.key-parameters"; - for (keyelem_count = 0; len && keyelem_count < 9;) + keyelem_count = 0; + while (!(err = tlv_next (tlv)) && !tlv_popped (tlv)) { - if ( parse_tag (&p, &n, &ti) - || ti.class || ti.tag != TAG_INTEGER) - goto bailout; - if (len < ti.nhdr) - goto bailout; - len -= ti.nhdr; - if (len < ti.length) - goto bailout; - len -= ti.length; - if (!keyelem_count && ti.length == 1 && !*p) - ; /* ignore the very first one if it is a 0 */ - else + if (keyelem_count >= 9) { - int rc; - - rc = gcry_mpi_scan (ctx->privatekey+keyelem_count, - GCRYMPI_FMT_USG, p, - ti.length, NULL); - if (rc) - { - log_error ("error parsing key parameter: %s\n", - gpg_strerror (rc)); - goto bailout; - } - keyelem_count++; + err = gpg_error (GPG_ERR_TOO_MANY); + goto bailout; } - p += ti.length; - n -= ti.length; + + err = tlv_expect_mpinteger (tlv, !keyelem_count, + ctx->privatekey+keyelem_count); + if (!keyelem_count && gpg_err_code (err) == GPG_ERR_FALSE) + ; /* Ignore the first value iff it is zero. */ + else if (err) + { + log_error ("error parsing RSA key parameter %d: %s\n", + keyelem_count, gpg_strerror (err)); + goto bailout; + } + log_debug ("RSA key parameter %d found\n", keyelem_count); + keyelem_count++; } - if (len) + if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; + err = 0; } else { if (opt_verbose) log_info ("processing certBag\n"); - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_OBJECT_ID - || ti.length != DIM(oid_x509Certificate_for_pkcs_12) - || memcmp (p, oid_x509Certificate_for_pkcs_12, + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + if (oidlen != DIM(oid_x509Certificate_for_pkcs_12) + || memcmp (oid, oid_x509Certificate_for_pkcs_12, DIM(oid_x509Certificate_for_pkcs_12))) - goto bailout; - p += DIM(oid_x509Certificate_for_pkcs_12); - n -= DIM(oid_x509Certificate_for_pkcs_12); + { + err = gpg_error (GPG_ERR_UNSUPPORTED_CERT); + goto bailout; + } where = "certbag.before.octetstring"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class != CLASS_CONTEXT || ti.tag) + if (tlv_expect_context_tag (tlv, &intval)) goto bailout; - if (parse_tag (&p, &n, &ti)) + if (intval) + { + err = gpg_error (GPG_ERR_BAD_BER); + goto bailout; + } + + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING || ti.ndef) + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; /* Return the certificate. */ if (ctx->certcb) - ctx->certcb (ctx->certcbarg, p, ti.length); - - p += ti.length; - n -= ti.length; + ctx->certcb (ctx->certcbarg, data, datalen); } - /* Ugly hack to cope with the padding: Forget about the rest if - that is less or equal to the cipher's block length. We can - reasonable assume that all valid data will be longer than - just one block. */ - if (n <= (is_pbes2? 16:8)) - n = 0; - /* Skip the optional SET with the pkcs12 cert attributes. */ - if (n) - { - where = "bag.attributes"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (!ti.class && ti.tag == TAG_SEQUENCE) - ; /* No attributes. */ - else if (!ti.class && ti.tag == TAG_SET && !ti.ndef) - { /* The optional SET. */ - p += ti.length; - n -= ti.length; - if (n <= (is_pbes2?16:8)) - n = 0; - if (n && parse_tag (&p, &n, &ti)) - goto bailout; - } - else - goto bailout; + where = "bag.attribute_set"; + err = tlv_next (tlv); + if (gpg_err_code (err) == GPG_ERR_EOF) + break; + if (err) + goto bailout; + err = tlv_expect_set (tlv); + if (!err) + { /* This is the optional set of attributes. Skip it. */ + tlv_skip (tlv); + if (opt_verbose) + log_info ("skipping bag.attribute_set\n"); } + else if (gpg_err_code (err) == GPG_ERR_INV_OBJ) + tlv_set_pending (tlv); /* The next tlv_next will be skipped. */ + else + goto bailout; } + if (err && gpg_err_code (err) != GPG_ERR_EOF) + { + if (!loopcount) /* The first while(tlv_next) failed. */ + ctx->badpass = 1; + goto bailout; + } + err = 0; - if (r_consumed) - *r_consumed = consumed; + leave: + if (renewed_tlv) + tlv_release (tlv); gcry_free (plain); - gcry_free (cram_buffer); - return 0; - - bailout: - if (r_consumed) - *r_consumed = consumed; - gcry_free (plain); - gcry_free (cram_buffer); - log_error ("encryptedData error at \"%s\", offset %u\n", - where, (unsigned int)((p - p_start)+startoffset)); if (ctx->badpass) { /* Note, that the following string might be used by other programs @@ -1191,7 +1626,19 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, translated or changed. */ log_error ("possibly bad passphrase given\n"); } - return -1; + return err; + + bailout: + if (!err) + err = gpg_error (GPG_ERR_GENERAL); + log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + __func__, where, + tlv? tlv->stacklen : 0, + tlv? tlv->offset : 0, + tlv? tlv->lastfunc : "", + tlv ? gpg_strerror (tlv->lasterr) : "init failed", + gpg_strerror (err)); + goto leave; } @@ -1223,363 +1670,403 @@ bag_data_p (const void *plaintext, size_t length) static gpg_error_t -parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, - const unsigned char *buffer, size_t length, - int startoffset, - size_t *r_consumed) +parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) { gpg_error_t err = 0; - struct tag_info ti; - const unsigned char *p = buffer; - const unsigned char *p_start = buffer; - size_t n = length; const char *where; + const unsigned char *oid; + size_t oidlen; + const unsigned char *data; + size_t datalen; + int intval; char salt[20]; size_t saltlen; char iv[16]; unsigned int iter; - int len; + int renewed_tlv = 0; /* True if the TLV must be released. */ unsigned char *plain = NULL; - unsigned char *cram_buffer = NULL; - size_t consumed = 0; /* Number of bytes consumed from the original buffer. */ int is_pbes2 = 0; - int keyelem_count = 0; + int is_aes256 = 0; where = "shrouded_key_bag"; - if (parse_tag (&p, &n, &ti)) + if (opt_verbose) + log_info ("processing %s\n", where); + + if (tlv_next (tlv)) goto bailout; - if (ti.class != CLASS_CONTEXT || ti.tag) + if (tlv_expect_context_tag (tlv, &intval) || intval != 0 ) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) + + where = "shrouded_key_bag.cipherinfo"; + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (ti.class == 0 && ti.tag == TAG_OBJECT_ID - && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC) - && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC, + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + + if (oidlen == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC) + && !memcmp (oid, oid_pbeWithSHAAnd3_KeyTripleDES_CBC, DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC))) - { - p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); - n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); - } - else if (ti.class == 0 && ti.tag == TAG_OBJECT_ID - && ti.length == DIM(oid_pkcs5PBES2) - && !memcmp (p, oid_pkcs5PBES2, DIM(oid_pkcs5PBES2))) - { - p += DIM(oid_pkcs5PBES2); - n -= DIM(oid_pkcs5PBES2); - is_pbes2 = 1; - } + ; /* Standard cipher. */ + else if (oidlen == DIM(oid_pkcs5PBES2) + && !memcmp (oid, oid_pkcs5PBES2, DIM(oid_pkcs5PBES2))) + is_pbes2 = 1; else - goto bailout; + { + err = gpg_error (GPG_ERR_UNKNOWN_ALGORITHM); + goto bailout; + } if (is_pbes2) { where = "shrouded_key_bag.pkcs5PBES2-params"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (!(!ti.class && ti.tag == TAG_OBJECT_ID - && ti.length == DIM(oid_pkcs5PBKDF2) - && !memcmp (p, oid_pkcs5PBKDF2, ti.length))) - goto bailout; /* Not PBKDF2. */ - p += ti.length; - n -= ti.length; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (!(!ti.class && ti.tag == TAG_OCTET_STRING - && ti.length >= 8 && ti.length < sizeof salt)) - goto bailout; /* No salt or unsupported length. */ - saltlen = ti.length; - memcpy (salt, p, saltlen); - p += saltlen; - n -= saltlen; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (!(!ti.class && ti.tag == TAG_INTEGER && ti.length)) - goto bailout; /* No valid iteration count. */ - for (iter=0; ti.length; ti.length--) + if (tlv_expect_sequence (tlv)) + goto bailout; + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + if (!(oidlen == DIM(oid_pkcs5PBKDF2) + && !memcmp (oid, oid_pkcs5PBKDF2, oidlen))) + goto bailout; /* Not PBKDF2. */ + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_sequence (tlv)) + goto bailout; + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) + goto bailout; + if (datalen < 8 || datalen > sizeof salt) { - iter <<= 8; - iter |= (*p++) & 0xff; - n--; + log_info ("bad length of salt (%zu) for AES\n", datalen); + err = gpg_error (GPG_ERR_INV_LENGTH); + goto bailout; } + saltlen = datalen; + memcpy (salt, data, saltlen); + + if (tlv_next (tlv)) + goto bailout; + if ((err = tlv_expect_integer (tlv, &intval))) + goto bailout; + if (!intval) /* Not a valid iteration count. */ + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto bailout; + } + iter = intval; + /* Note: We don't support the optional parameters but assume that the algorithmIdentifier follows. */ - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (!(!ti.class && ti.tag == TAG_OBJECT_ID - && ti.length == DIM(oid_aes128_CBC) - && !memcmp (p, oid_aes128_CBC, ti.length))) - goto bailout; /* Not AES-128. */ - p += ti.length; - n -= ti.length; - if (parse_tag (&p, &n, &ti)) + if (tlv_expect_object_id (tlv, &oid, &oidlen)) goto bailout; - if (!(!ti.class && ti.tag == TAG_OCTET_STRING && ti.length == sizeof iv)) + if (oidlen == DIM(oid_aes128_CBC) + && !memcmp (oid, oid_aes128_CBC, oidlen)) + ; + else if (oidlen == DIM(oid_aes256_CBC) + && !memcmp (oid, oid_aes256_CBC, oidlen)) + is_aes256 = 1; + else + { + gpgrt_log_printhex (oid, oidlen, "cipher is:"); + err = gpg_error (GPG_ERR_CIPHER_ALGO); + goto bailout; + } + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) + goto bailout; + if (datalen != sizeof iv) goto bailout; /* Bad IV. */ - memcpy (iv, p, sizeof iv); - p += sizeof iv; - n -= sizeof iv; + memcpy (iv, data, datalen); } else { where = "shrouded_key_bag.3des-params"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING - || ti.length < 8 || ti.length > 20) + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; - saltlen = ti.length; - memcpy (salt, p, saltlen); - p += saltlen; - n -= saltlen; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_INTEGER || !ti.length ) - goto bailout; - for (iter=0; ti.length; ti.length--) + if (datalen < 8 || datalen > 20) { - iter <<= 8; - iter |= (*p++) & 0xff; - n--; + log_info ("bad length of salt (%zu) for 3DES\n", datalen); + err = gpg_error (GPG_ERR_INV_LENGTH); + goto bailout; } + saltlen = datalen; + memcpy (salt, data, saltlen); + + if (tlv_next (tlv)) + goto bailout; + if ((err = tlv_expect_integer (tlv, &intval))) + goto bailout; + if (!intval) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto bailout; + } + iter = intval; } where = "shrouded_key_bag.3desoraes-ciphertext"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length ) + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; if (opt_verbose) - log_info ("%lu bytes of %s encrypted text\n", - ti.length, is_pbes2? "AES128":"3DES"); + log_info ("%zu bytes of %s encrypted text\n", + datalen, is_pbes2? (is_aes256?"AES256":"AES128"):"3DES"); + + plain = gcry_malloc_secure (datalen); - plain = gcry_malloc_secure (ti.length); if (!plain) { + err = gpg_error_from_syserror (); log_error ("error allocating decryption buffer\n"); goto bailout; } - consumed += p - p_start + ti.length; - decrypt_block (p, plain, ti.length, salt, saltlen, iter, + decrypt_block (data, plain, datalen, salt, saltlen, iter, iv, is_pbes2? 16:0, ctx->password, - is_pbes2? GCRY_CIPHER_AES128 : GCRY_CIPHER_3DES, + is_pbes2 ? (is_aes256?GCRY_CIPHER_AES256:GCRY_CIPHER_AES128) + : GCRY_CIPHER_3DES, bag_data_p); - n = ti.length; - startoffset = 0; - p_start = p = plain; + /* We do not need the TLV anymore and allocated a new one. */ where = "shrouded_key_bag.decrypted-text"; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER - || ti.length != 1 || *p) - goto bailout; - p++; n--; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - len = ti.length; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (len < ti.nhdr) - goto bailout; - len -= ti.nhdr; - if (ti.class || ti.tag != TAG_OBJECT_ID) - goto bailout; - /* gpgrt_log_printhex (p, ti.length, "OID:"); */ - if (ti.length == DIM(oid_rsaEncryption) - && !memcmp (p, oid_rsaEncryption, DIM(oid_rsaEncryption))) + tlv = tlv_new (plain, datalen); + if (!tlv) { - p += DIM (oid_rsaEncryption); - n -= DIM (oid_rsaEncryption); + err = gpg_error_from_syserror (); + goto bailout; } - else if (ti.length == DIM(oid_pcPublicKey) - && !memcmp (p, oid_pcPublicKey, DIM(oid_pcPublicKey))) + renewed_tlv = 1; + + if (tlv_next (tlv)) + { + ctx->badpass = 1; + goto bailout; + } + if (tlv_expect_top_sequence (tlv)) + { + ctx->badpass = 1; + goto bailout; + } + + if (tlv_next (tlv)) + { + ctx->badpass = 1; + goto bailout; + } + if ((err = tlv_expect_integer (tlv, &intval))) + { + ctx->badpass = 1; + goto bailout; + } + if (intval) + { + ctx->badpass = 1; + err = gpg_error (GPG_ERR_INV_VALUE); + goto bailout; + } + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_sequence (tlv)) + goto bailout; + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + if (oidlen == DIM(oid_rsaEncryption) + && !memcmp (oid, oid_rsaEncryption, oidlen)) + { + if (opt_verbose > 1) + log_debug ("RSA parameters\n"); + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_null (tlv)) + tlv_set_pending (tlv); /* NULL tag missing - ignore this. */ + } + else if (oidlen == DIM(oid_pcPublicKey) + && !memcmp (oid, oid_pcPublicKey, oidlen)) { /* See RFC-5915 for the format. */ - p += DIM (oid_pcPublicKey); - n -= DIM (oid_pcPublicKey); - if (len < ti.length) + if (tlv_next (tlv)) goto bailout; - len -= ti.length; - if (n < len) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - /* gpgrt_log_debug ("ti=%d/%lu len=%lu\n",ti.class,ti.tag,ti.length); */ - if (len < ti.nhdr) - goto bailout; - len -= ti.nhdr; - if (ti.class || ti.tag != TAG_OBJECT_ID) + if (tlv_expect_object_id (tlv, &oid, &oidlen)) goto bailout; ksba_free (ctx->curve); - ctx->curve = ksba_oid_to_str (p, ti.length); + ctx->curve = ksba_oid_to_str (oid, oidlen); if (!ctx->curve) - goto bailout; - /* log_debug ("OID of curve is: %s\n", curve); */ - p += ti.length; - n -= ti.length; + { + err = gpg_error (GPG_ERR_INV_OID_STRING); + goto bailout; + } + if (opt_verbose > 1) + log_debug ("OID of curve is: %s\n", ctx->curve); } - else + else /* Unknown key format */ + { + gpgrt_log_printhex (oid, oidlen, "key format OID:"); + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto bailout; + } + + /* An octet string to encapsulate the key elements. */ + if (tlv_next (tlv)) goto bailout; - if (len < ti.length) + if (tlv_expect_octet_string (tlv, 1, &data, &datalen)) goto bailout; - len -= ti.length; - if (n < len) + + if (tlv_next (tlv)) goto bailout; - p += len; - n -= len; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - len = ti.length; if (ctx->privatekey) { - log_error ("a key has already been received\n"); + err = gpg_error (GPG_ERR_DUP_VALUE); + log_error ("a private key has already been received\n"); goto bailout; } ctx->privatekey = gcry_calloc (10, sizeof *ctx->privatekey); if (!ctx->privatekey) { - + err = gpg_error_from_syserror (); log_error ("error allocating privatekey element array\n"); goto bailout; } - keyelem_count = 0; where = "shrouded_key_bag.reading.key-parameters"; if (ctx->curve) /* ECC case. */ { - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER) + if (tlv_next (tlv)) goto bailout; - if (len < ti.nhdr) + if ((err = tlv_expect_integer (tlv, &intval))) goto bailout; - len -= ti.nhdr; - if (len < ti.length) - goto bailout; - len -= ti.length; - if (ti.length != 1 && *p != 1) + if (intval != 1) { + err = gpg_error (GPG_ERR_INV_VALUE); log_error ("error parsing private ecPublicKey parameter: %s\n", "bad version"); goto bailout; } - p += ti.length; - n -= ti.length; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_OCTET_STRING) + + if (tlv_next (tlv)) goto bailout; - if (len < ti.nhdr) + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; - len -= ti.nhdr; - if (len < ti.length) - goto bailout; - len -= ti.length; - /* log_printhex (p, ti.length, "ecc q="); */ + if (opt_verbose > 1) + log_printhex (data, datalen, "ecc q="); err = gcry_mpi_scan (ctx->privatekey, GCRYMPI_FMT_USG, - p, ti.length, NULL); + data, datalen, NULL); if (err) { log_error ("error parsing key parameter: %s\n", gpg_strerror (err)); goto bailout; } - p += ti.length; - n -= ti.length; - - len = 0; /* Skip the rest. */ } else /* RSA case */ { - for (keyelem_count=0; len && keyelem_count < 9;) + int keyelem_count = 0; + int firstparam = 1; + + while (!(err = tlv_next (tlv)) && !tlv_popped (tlv)) { - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER) - goto bailout; - if (len < ti.nhdr) - goto bailout; - len -= ti.nhdr; - if (len < ti.length) - goto bailout; - len -= ti.length; - if (!keyelem_count && ti.length == 1 && !*p) - ; /* ignore the very first one if it is a 0 */ + if (keyelem_count >= 9) + { + err = gpg_error (GPG_ERR_TOO_MANY); + goto bailout; + } + + err = tlv_expect_mpinteger (tlv, firstparam, + ctx->privatekey+keyelem_count); + if (firstparam && gpg_err_code (err) == GPG_ERR_FALSE) + ; /* Ignore the first value iff it is zero. */ + else if (err) + { + log_error ("error parsing RSA key parameter %d: %s\n", + keyelem_count, gpg_strerror (err)); + goto bailout; + } else { - err = gcry_mpi_scan (ctx->privatekey+keyelem_count, - GCRYMPI_FMT_USG, p, ti.length, NULL); - if (err) - { - log_error ("error parsing key parameter: %s\n", - gpg_strerror (err)); - goto bailout; - } + if (opt_verbose > 1) + log_debug ("RSA key parameter %d found\n", keyelem_count); keyelem_count++; } - p += ti.length; - n -= ti.length; + firstparam = 0; } + if (err && gpg_err_code (err) != GPG_ERR_EOF) + goto bailout; + err = 0; } - if (len) - goto bailout; - - goto leave; - - bailout: - gcry_free (plain); - log_error ("data error at \"%s\", offset %zu\n", - where, (size_t)((p - p_start) + startoffset)); - if (!err) - err = gpg_error (GPG_ERR_GENERAL); leave: - gcry_free (cram_buffer); - if (r_consumed) - *r_consumed = consumed; + gcry_free (plain); + if (renewed_tlv) + tlv_release (tlv); return err; + + bailout: + if (!err) + err = gpg_error (GPG_ERR_GENERAL); + log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + __func__, where, + tlv? tlv->stacklen : 0, + tlv? tlv->offset : 0, + tlv? tlv->lastfunc : "", + tlv ? gpg_strerror (tlv->lasterr) : "init failed", + gpg_strerror (err)); + goto leave; } static gpg_error_t -parse_cert_bag (struct p12_parse_ctx_s *ctx, - const unsigned char *buffer, size_t length, - int startoffset, - size_t *r_consumed) +parse_cert_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) { gpg_error_t err = 0; - struct tag_info ti; - const unsigned char *p = buffer; - const unsigned char *p_start = buffer; - size_t n = length; const char *where; - size_t consumed = 0; /* Number of bytes consumed from the original buffer. */ + int intval; + const unsigned char *oid; + size_t oidlen; + const unsigned char *data; + size_t datalen; if (opt_verbose) log_info ("processing certBag\n"); @@ -1590,181 +2077,182 @@ parse_cert_bag (struct p12_parse_ctx_s *ctx, * OBJECT IDENTIFIER pkcs-12-certBag */ where = "certbag.before.certheader"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class != CLASS_CONTEXT || ti.tag) + if (tlv_expect_context_tag (tlv, &intval)) goto bailout; - if (parse_tag (&p, &n, &ti)) + if (intval) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto bailout; + } + + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_OBJECT_ID - || ti.length != DIM(oid_x509Certificate_for_pkcs_12) - || memcmp (p, oid_x509Certificate_for_pkcs_12, - DIM(oid_x509Certificate_for_pkcs_12))) + if (tlv_expect_object_id (tlv, &oid, &oidlen)) goto bailout; - p += DIM(oid_x509Certificate_for_pkcs_12); - n -= DIM(oid_x509Certificate_for_pkcs_12); + if (oidlen != DIM(oid_x509Certificate_for_pkcs_12) + || memcmp (oid, oid_x509Certificate_for_pkcs_12, oidlen)) + goto bailout; + /* Expect: * [0] * OCTET STRING encapsulates -- the certificates */ where = "certbag.before.octetstring"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class != CLASS_CONTEXT || ti.tag) + if (tlv_expect_context_tag (tlv, &intval) || intval != 0 ) goto bailout; - if (parse_tag (&p, &n, &ti)) + + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING || ti.ndef) + if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; /* Return the certificate from the octet string. */ if (ctx->certcb) - ctx->certcb (ctx->certcbarg, p, ti.length); + ctx->certcb (ctx->certcbarg, data, datalen); - p += ti.length; - n -= ti.length; - - if (!n) - goto leave; /* ready. */ - - /* Expect: + /* Expect optional: * SET * SEQUENCE -- we actually ignore this. */ where = "certbag.attribute_set"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (!ti.class && ti.tag == TAG_SET && !ti.ndef) - { /* Comsume the optional SET. */ - p += ti.length; - n -= ti.length; - if (parse_tag (&p, &n, &ti)) - goto bailout; + err = tlv_expect_set (tlv); + if (!err) + { /* This is the optional set of attributes. Skip it. */ + tlv_skip (tlv); + if (opt_verbose) + log_info ("skipping certbag.attribute_set\n"); } - - goto leave; - - bailout: - log_error ( "data error at \"%s\", offset %u\n", - where, (unsigned int)((p - p_start) + startoffset)); - err = gpg_error (GPG_ERR_GENERAL); + else if (gpg_err_code (err) == GPG_ERR_INV_OBJ) + tlv_set_pending (tlv); /* The next tlv_next will be skipped. */ + else + goto bailout; leave: - if (r_consumed) - *r_consumed = consumed; return err; + + bailout: + log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + __func__, where, + tlv? tlv->stacklen : 0, + tlv? tlv->offset : 0, + tlv? tlv->lastfunc : "", + tlv ? gpg_strerror (tlv->lasterr) : "init failed", + gpg_strerror (err)); + if (!err) + err = gpg_error (GPG_ERR_GENERAL); + goto leave; } static gpg_error_t -parse_bag_data (struct p12_parse_ctx_s *ctx, - const unsigned char *buffer, size_t length, int startoffset, - size_t *r_consumed) +parse_bag_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) { gpg_error_t err = 0; - struct tag_info ti; - const unsigned char *p = buffer; - const unsigned char *p_start = buffer; - size_t n = length; const char *where; - unsigned char *cram_buffer = NULL; - size_t consumed = 0; /* Number of bytes consumed from the original buffer. */ + int intval; + const unsigned char *oid; + size_t oidlen; + unsigned int startlevel; + + if (opt_verbose) + log_info ("processing bag data\n"); /* Expect: * [0] * OCTET STRING, encapsulates */ where = "data"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class != CLASS_CONTEXT || ti.tag) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING) + if (tlv_expect_context_tag (tlv, &intval) || intval != 0 ) goto bailout; + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_octet_string (tlv, 1, NULL, NULL)) + goto bailout; - consumed = p - p_start; - if (ti.is_constructed && ti.ndef) - { - /* Mozilla exported certs now come with single byte chunks of - octet strings. (Mozilla Firefox 1.0.4). Arghh. */ - where = "data.cram_os"; - cram_buffer = cram_octet_string ( p, &n, &consumed); - if (!cram_buffer) - goto bailout; - p = p_start = cram_buffer; - if (r_consumed) - *r_consumed = consumed; - r_consumed = NULL; /* Ugly hack to not update that value on return. */ - } /* Expect: * SEQUENCE - * SEQUENCE */ - where = "data.2seqs"; - if (parse_tag (&p, &n, &ti)) + where = "data.outerseqs"; + if (tlv_next (tlv)) goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - /* Expect: - * OBJECT IDENTIFIER - */ - where = "data.oid"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_OBJECT_ID) - goto bailout; - - /* Now divert to the actual parser. */ - if (ti.length == DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag) - && !memcmp (p, oid_pkcs_12_pkcs_8ShroudedKeyBag, - DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag))) + startlevel = tlv_level (tlv); + while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) { - p += DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag); - n -= DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag); - - if (parse_shrouded_key_bag (ctx, p, n, - startoffset + (p - p_start), r_consumed)) + /* Expect: + * SEQUENCE + */ + where = "data.innerseqs"; + if (tlv_expect_sequence (tlv)) goto bailout; - } - else if ( ti.length == DIM(oid_pkcs_12_CertBag) - && !memcmp (p, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag))) - { - p += DIM(oid_pkcs_12_CertBag); - n -= DIM(oid_pkcs_12_CertBag); - if (parse_cert_bag (ctx, p, n, - startoffset + (p - p_start), r_consumed)) + /* Expect: + * OBJECT IDENTIFIER + */ + where = "data.oid"; + if (tlv_next (tlv)) goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + + /* Divert to the actual parser. */ + if (oidlen == DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag) + && !memcmp (oid, oid_pkcs_12_pkcs_8ShroudedKeyBag, + DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag))) + { + if ((err = parse_shrouded_key_bag (ctx, tlv))) + goto bailout; + } + else if (oidlen == DIM(oid_pkcs_12_CertBag) + && !memcmp (oid, oid_pkcs_12_CertBag, DIM(oid_pkcs_12_CertBag))) + { + if ((err = parse_cert_bag (ctx, tlv))) + goto bailout; + } + else + { + tlv_skip (tlv); + log_info ("unknown inner data type - skipped\n"); + } } - else + if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; - - goto leave; - - bailout: - log_error ( "data error at \"%s\", offset %u\n", - where, (unsigned int)((p - p_start) + startoffset)); - err = gpg_error (GPG_ERR_GENERAL); + err = 0; + if (tlv_popped (tlv)) + tlv_set_pending (tlv); leave: - gcry_free (cram_buffer); - if (r_consumed) /* Store the number of consumed bytes unless already done. */ - *r_consumed = consumed; return err; + + bailout: + if (!err) + err = gpg_error (GPG_ERR_GENERAL); + log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + __func__, where, + tlv? tlv->stacklen : 0, + tlv? tlv->offset : 0, + tlv? tlv->lastfunc : "", + tlv ? gpg_strerror (tlv->lasterr) : "init failed", + gpg_strerror (err)); + goto leave; } @@ -1772,7 +2260,7 @@ parse_bag_data (struct p12_parse_ctx_s *ctx, secret key parameters. This is a very limited implementation in that it is only able to look for 3DES encoded encryptedData and tries to extract the first private key object it finds. In case of - an error NULL is returned. CERTCB and CERRTCBARG are used to pass + an error NULL is returned. CERTCB and CERTCBARG are used to pass X.509 certificates back to the caller. If R_CURVE is not NULL and an ECC key was found the OID of the curve is stored there. */ gcry_mpi_t * @@ -1780,16 +2268,14 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, void (*certcb)(void*, const unsigned char*, size_t), void *certcbarg, int *r_badpass, char **r_curve) { - struct tag_info ti; - const unsigned char *p = buffer; - const unsigned char *p_start = buffer; - size_t n = length; + gpg_error_t err; const char *where; - int bagseqlength, len; - int bagseqndef, lenndef; - unsigned char *cram_buffer = NULL; - size_t consumed; + struct tlv_ctx_s *tlv; struct p12_parse_ctx_s ctx = { NULL }; + const unsigned char *oid; + size_t oidlen; + int intval; + unsigned int startlevel; *r_badpass = 0; @@ -1797,146 +2283,111 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, ctx.certcbarg = certcbarg; ctx.password = pw; + tlv = tlv_new (buffer, length); + if (!tlv) + { + err = gpg_error_from_syserror (); + goto bailout; + } where = "pfx"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; where = "pfxVersion"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.tag != TAG_INTEGER || ti.length != 1 || *p != 3) + if (tlv_expect_integer (tlv, &intval) || intval != 3) goto bailout; - p++; n--; where = "authSave"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.tag != TAG_OBJECT_ID || ti.length != DIM(oid_data) - || memcmp (p, oid_data, DIM(oid_data))) - goto bailout; - p += DIM(oid_data); - n -= DIM(oid_data); - - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class != CLASS_CONTEXT || ti.tag) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class != CLASS_UNIVERSAL || ti.tag != TAG_OCTET_STRING) + if (tlv_expect_sequence (tlv)) goto bailout; - if (ti.is_constructed && ti.ndef) + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + if (oidlen != DIM(oid_data) || memcmp (oid, oid_data, DIM(oid_data))) + goto bailout; + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_context_tag (tlv, &intval) || intval != 0 ) + goto bailout; + + if (tlv_next (tlv)) + goto bailout; + if (tlv->ti.is_constructed && tlv->ti.ndef) { - /* Mozilla exported certs now come with single byte chunks of - octet strings. (Mozilla Firefox 1.0.4). Arghh. */ - where = "cram-bags"; - cram_buffer = cram_octet_string ( p, &n, NULL); - if (!cram_buffer) - goto bailout; - p = p_start = cram_buffer; + log_debug ("FIXME Put this into our TLV machinery.\n"); + /* /\* Mozilla exported certs now come with single byte chunks of */ + /* octet strings. (Mozilla Firefox 1.0.4). Arghh. *\/ */ + /* where = "cram-bags"; */ + /* cram_buffer = cram_octet_string ( p, &n, NULL); */ + /* if (!cram_buffer) */ + /* goto bailout; */ + /* p = p_start = cram_buffer; */ } + if (tlv_expect_octet_string (tlv, 1, NULL, NULL)) + goto bailout; + where = "bags"; - if (parse_tag (&p, &n, &ti)) + if (tlv_next (tlv)) goto bailout; - if (ti.class != CLASS_UNIVERSAL || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - bagseqndef = ti.ndef; - bagseqlength = ti.length; - while (bagseqlength || bagseqndef) + + startlevel = tlv_level (tlv); + while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) { - /* log_debug ("p12_parse: at offset %ld\n", (p - p_start)); */ where = "bag-sequence"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (bagseqndef && ti.class == CLASS_UNIVERSAL - && !ti.tag && !ti.is_constructed) - break; /* Ready */ - if (ti.class != CLASS_UNIVERSAL || ti.tag != TAG_SEQUENCE) + if (tlv_expect_sequence (tlv)) goto bailout; - if (!bagseqndef) + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + + if (oidlen == DIM(oid_encryptedData) + && !memcmp (oid, oid_encryptedData, DIM(oid_encryptedData))) { - if (bagseqlength < ti.nhdr) - goto bailout; - bagseqlength -= ti.nhdr; - if (bagseqlength < ti.length) - goto bailout; - bagseqlength -= ti.length; - } - lenndef = ti.ndef; - len = ti.length; - - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (lenndef) - len = ti.nhdr; - else - len -= ti.nhdr; - - if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_encryptedData) - && !memcmp (p, oid_encryptedData, DIM(oid_encryptedData))) - { - - p += DIM(oid_encryptedData); - n -= DIM(oid_encryptedData); - if (!lenndef) - len -= DIM(oid_encryptedData); where = "bag.encryptedData"; - consumed = 0; - if (parse_bag_encrypted_data (&ctx, p, n, (p - p_start), &consumed)) - { - *r_badpass = ctx.badpass; - goto bailout; - } - if (lenndef) - len += consumed; - } - else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data) - && !memcmp (p, oid_data, DIM(oid_data))) - { - p += DIM(oid_data); - n -= DIM(oid_data); - if (!lenndef) - len -= DIM(oid_data); - - where = "bag.data"; - consumed = 0; - if (parse_bag_data (&ctx, p, n, (p - p_start), &consumed)) + if ((err=parse_bag_encrypted_data (&ctx, tlv))) + goto bailout; + } + else if (oidlen == DIM(oid_data) + && !memcmp (oid, oid_data, DIM(oid_data))) + { + where = "bag.data"; + if ((err=parse_bag_data (&ctx, tlv))) + goto bailout; + } + else if (oidlen == DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag) + && !memcmp (oid, oid_pkcs_12_pkcs_8ShroudedKeyBag, + DIM(oid_pkcs_12_pkcs_8ShroudedKeyBag))) + { + where = "bag.shroudedkeybag"; + if ((err = parse_shrouded_key_bag (&ctx, tlv))) goto bailout; - if (lenndef) - len += consumed; } else { + tlv_skip (tlv); log_info ("unknown outer bag type - skipped\n"); - p += ti.length; - n -= ti.length; - } - - if (len < 0 || len > n) - goto bailout; - p += len; - n -= len; - if (lenndef) - { - /* Need to skip the Null Tag. */ - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (!(ti.class == CLASS_UNIVERSAL && !ti.tag && !ti.is_constructed)) - goto bailout; } } + if (err && gpg_err_code (err) != GPG_ERR_EOF) + goto bailout; + err = 0; - gcry_free (cram_buffer); + tlv_release (tlv); if (r_curve) *r_curve = ctx.curve; else @@ -1945,8 +2396,14 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, return ctx.privatekey; bailout: - log_error ("error at \"%s\", offset %u\n", - where, (unsigned int)(p - p_start)); + *r_badpass = ctx.badpass; + log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + __func__, where, + tlv? tlv->stacklen : 0, + tlv? tlv->offset : 0, + tlv? tlv->lastfunc : "", + tlv ? gpg_strerror (tlv->lasterr) : "init failed", + gpg_strerror (err)); if (ctx.privatekey) { int i; @@ -1956,7 +2413,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, gcry_free (ctx.privatekey); ctx.privatekey = NULL; } - gcry_free (cram_buffer); + tlv_release (tlv); gcry_free (ctx.curve); if (r_curve) *r_curve = NULL; diff --git a/sm/minip12.h b/sm/minip12.h index 84c5f5f79..654cab0e6 100644 --- a/sm/minip12.h +++ b/sm/minip12.h @@ -23,7 +23,7 @@ #include -void p12_set_verbosity (int verbose); +void p12_set_verbosity (int verbose, int debug); gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length, const char *pw, diff --git a/sm/t-minip12.c b/sm/t-minip12.c index 97bbcb9dc..80ba4c69e 100644 --- a/sm/t-minip12.c +++ b/sm/t-minip12.c @@ -1,5 +1,5 @@ /* t-minip12.c - Test driver for minip12.c - * Copyright (C) 2020 g10 Code GmbH + * Copyright (C) 2020, 2023 g10 Code GmbH * * This file is part of GnuPG. * @@ -15,6 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . + * SPDX-License-Identifier: GPL-3.0-or-later */ #include @@ -22,6 +23,8 @@ #include #include #include +#include +#include #include "../common/util.h" #include "minip12.h" @@ -31,7 +34,336 @@ static int verbose; static int debug; +static int any_error; +static void die (const char *format, ...) GPGRT_ATTR_NR_PRINTF(1,2); +static void err (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); +static void inf (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); +/* static void dbg (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); */ +static void printresult (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); +static char *my_xstrconcat (const char *s1, ...) GPGRT_ATTR_SENTINEL(0); + +#define xstrconcat my_xstrconcat +#define trim_spaces(a) my_trim_spaces ((a)) +#define my_isascii(c) (!((c) & 0x80)) + + + + + +/* Print diagnostic message and exit with failure. */ +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + if (!*format || format[strlen(format)-1] != '\n') + putc ('\n', stderr); + + exit (1); +} + + +/* Print diagnostic message. */ +static void +err (const char *format, ...) +{ + va_list arg_ptr; + + any_error = 1; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + if (!*format || format[strlen(format)-1] != '\n') + putc ('\n', stderr); +} + + +/* Print an info message. */ +static void +inf (const char *format, ...) +{ + va_list arg_ptr; + + if (verbose) + { + fprintf (stderr, "%s: ", PGM); + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + if (!*format || format[strlen(format)-1] != '\n') + putc ('\n', stderr); + } +} + + +/* Print a debug message. */ +/* static void */ +/* dbg (const char *format, ...) */ +/* { */ +/* va_list arg_ptr; */ + +/* if (debug) */ +/* { */ +/* fprintf (stderr, "%s: DBG: ", PGM); */ + +/* va_start (arg_ptr, format); */ +/* vfprintf (stderr, format, arg_ptr); */ +/* va_end (arg_ptr); */ +/* if (!*format || format[strlen(format)-1] != '\n') */ +/* putc ('\n', stderr); */ +/* } */ +/* } */ + + +/* Print a result line to stdout. */ +static void +printresult (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); +#ifdef HAVE_FLOCKFILE + flockfile (stdout); +#endif + va_start (arg_ptr, format); + vfprintf (stdout, format, arg_ptr); + if (*format && format[strlen(format)-1] != '\n') + putc ('\n', stdout); + va_end (arg_ptr); + fflush (stdout); +#ifdef HAVE_FLOCKFILE + funlockfile (stdout); +#endif +} + + +/* Helper for xstrconcat and strconcat. */ +static char * +do_strconcat (int xmode, const char *s1, va_list arg_ptr) +{ + const char *argv[48]; + size_t argc; + size_t needed; + char *buffer, *p; + + argc = 0; + argv[argc++] = s1; + needed = strlen (s1); + while (((argv[argc] = va_arg (arg_ptr, const char *)))) + { + needed += strlen (argv[argc]); + if (argc >= DIM (argv)-1) + die ("too may args for strconcat\n"); + argc++; + } + needed++; + buffer = xmode? xmalloc (needed) : malloc (needed); + for (p = buffer, argc=0; argv[argc]; argc++) + p = stpcpy (p, argv[argc]); + + return buffer; +} + + +/* Concatenate the string S1 with all the following strings up to a + NULL. Returns a malloced buffer with the new string or dies on error. */ +static char * +my_xstrconcat (const char *s1, ...) +{ + va_list arg_ptr; + char *result; + + if (!s1) + result = xstrdup (""); + else + { + va_start (arg_ptr, s1); + result = do_strconcat (1, s1, arg_ptr); + va_end (arg_ptr); + } + return result; +} + + +static char * +my_trim_spaces (char *str ) +{ + char *string, *p, *mark; + + string = str; + for (p=string; *p && isspace (*(unsigned char *)p) ; p++) + ; + for (mark=NULL; (*string = *p); string++, p++ ) + if (isspace (*(unsigned char *)p)) + { + if (!mark) + mark = string; + } + else + mark = NULL; + if (mark) + *mark = '\0'; + + return str ; +} + + +/* Prepend FNAME with the srcdir environment variable's value and + * return an allocated filename. */ +static char * +prepend_srcdir (const char *fname) +{ + static const char *srcdir; + + if (!srcdir && !(srcdir = getenv ("srcdir"))) + return xstrdup (fname); + else + return xstrconcat (srcdir, "/", fname, NULL); +} + + +/* (BUFFER,BUFLEN) and return a malloced hexstring. */ +static char * +hash_buffer (const void *buffer, size_t buflen) +{ + unsigned char hash[20]; + char *result; + int i; + + gcry_md_hash_buffer (GCRY_MD_SHA1, hash, buffer, buflen); + result = xmalloc (41); + for (i=0; i < 20; i++) + snprintf (result + 2*i, 3, "%02x", hash[i]); + return result; +} + + +/* Read next line but skip over empty and comment lines. Caller must + xfree the result. */ +static char * +read_textline (FILE *fp, int *lineno) +{ + char line[4096]; + char *p; + + do + { + if (!fgets (line, sizeof line, fp)) + { + if (feof (fp)) + return NULL; + die ("error reading input line: %s\n", strerror (errno)); + } + ++*lineno; + p = strchr (line, '\n'); + if (!p) + die ("input line %d not terminated or too long\n", *lineno); + *p = 0; + for (p--;p > line && my_isascii (*p) && isspace (*p); p--) + *p = 0; + } + while (!*line || *line == '#'); + return xstrdup (line); +} + + +/* Copy the data after the tag to BUFFER. BUFFER will be allocated as + needed. */ +static void +copy_data (char **buffer, const char *line, int lineno) +{ + const char *s; + + xfree (*buffer); + *buffer = NULL; + + s = strchr (line, ':'); + if (!s) + { + err ("syntax error at input line %d", lineno); + return; + } + for (s++; my_isascii (*s) && isspace (*s); s++) + ; + *buffer = xstrdup (s); +} + + +static void +hexdowncase (char *string) +{ + char *p; + + if (string) + for (p=string; *p; p++) + if (my_isascii (*p)) + *p = tolower (*p); +} + + +/* Return the value of the variable VARNAME from ~/.gnupg-autogen.rc + * or NULL if it does not exists or is empty. */ +static char * +value_from_gnupg_autogen_rc (const char *varname) +{ + const char *home; + char *fname; + FILE *fp; + char *line = NULL; + char *p; + int lineno = 0; + + if (!(home = getenv ("HOME"))) + home = ""; + fname = xstrconcat (home, "/.gnupg-autogen.rc", NULL); + fp = fopen (fname, "r"); + if (!fp) + goto leave; + + while ((line = read_textline (fp, &lineno))) + { + p = strchr (line, '='); + if (p) + { + *p++ = 0; + trim_spaces (line); + if (!strcmp (line, varname)) + { + trim_spaces (p); + if (*p) + { + memmove (line, p, strlen (p)+1); + if (*line == '~' && line[1] == '/') + { + p = xstrconcat (home, line+1, NULL); + xfree (line); + line = p; + } + break; /* found. */ + } + } + } + xfree (line); + } + + leave: + if (fp) + fclose (fp); + xfree (fname); + return line; +} static void @@ -45,13 +377,10 @@ cert_cb (void *opaque, const unsigned char *cert, size_t certlen) } - -int -main (int argc, char **argv) +/* Parse one PKCS#12 file. Returns zero on success. */ +static int +one_file (const char *name, const char *pass) { - int last_argc = -1; - char const *name = NULL; - char const *pass = NULL; FILE *fp; struct stat st; unsigned char *buf; @@ -60,63 +389,6 @@ main (int argc, char **argv) int badpass; char *curve = NULL; - 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 " []\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; - debug++; - argc--; argv++; - } - else if (!strncmp (*argv, "--", 2)) - { - fprintf (stderr, PGM ": unknown option '%s'\n", *argv); - exit (1); - } - } - - if (argc == 1) - { - name = argv[0]; - pass = ""; - } - else if (argc == 2) - { - name = argv[0]; - pass = argv[1]; - } - else - { - fprintf (stderr, "usage: " PGM " []\n"); - exit (1); - } - - gcry_control (GCRYCTL_DISABLE_SECMEM, NULL); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL); - - fp = fopen (name, "rb"); if (!fp) { @@ -131,8 +403,8 @@ main (int argc, char **argv) } buflen = st.st_size; - buf = gcry_malloc (buflen+1); - if (!buf || fread (buf, buflen, 1, fp) != 1) + buf = xmalloc (buflen+1); + if (fread (buf, buflen, 1, fp) != 1) { fprintf (stderr, "error reading '%s': %s\n", name, strerror (errno)); return 1; @@ -160,6 +432,344 @@ main (int argc, char **argv) } } } + if (badpass) + log_error ("Bad password given?\n"); + xfree (buf); return 0; } + + +static void +cert_collect_cb (void *opaque, const unsigned char *cert, size_t certlen) +{ + char **certstr = opaque; + char *hash; + + hash = hash_buffer (cert, certlen); + if (*certstr) + { + *certstr = xstrconcat (*certstr, ",", hash, NULL); + xfree (hash); + } + else + *certstr = hash; +} + + +static int +run_one_test (const char *name, const char *desc, const char *pass, + const char *certexpected, const char *keyexpected) +{ + FILE *fp; + struct stat st; + unsigned char *buf; + size_t buflen; + gcry_mpi_t *result; + int badpass; + char *curve = NULL; + char *resulthash = NULL; + char *p; + char *certstr = NULL; + int ret; + + inf ("testing '%s' (%s)", name , desc? desc:""); + fp = fopen (name, "rb"); + if (!fp) + { + err ("can't open '%s': %s\n", name, strerror (errno)); + printresult ("FAIL: %s - test file not found\n", name); + return 1; + } + + if (fstat (fileno (fp), &st)) + { + err ("can't stat '%s': %s\n", name, strerror (errno)); + printresult ("FAIL: %s - error stating test file\n", name); + fclose (fp); + return 1; + } + + buflen = st.st_size; + buf = xmalloc (buflen+1); + if (fread (buf, buflen, 1, fp) != 1) + { + err ("error reading '%s': %s\n", name, strerror (errno)); + printresult ("FAIL: %s - error reading test file\n", name); + fclose (fp); + xfree (buf); + return 1; + } + fclose (fp); + + result = p12_parse (buf, buflen, pass? pass:"", cert_collect_cb, &certstr, + &badpass, &curve); + if (result) + { + int i, rc; + char *tmpstring; + unsigned char *tmpbuf; + char numbuf[20]; + + if (curve) + { + if (verbose > 1) + inf ("curve: %s\n", curve); + tmpstring = xstrconcat ("curve:", curve, "\n", NULL); + } + else + tmpstring = xstrdup ("\n"); + for (i=0; result[i]; i++) + { + rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &tmpbuf, NULL, result[i]); + if (rc) + die ("result %d: [error printing number: %s]\n", + i, gpg_strerror (rc)); + else + { + if (verbose > 1) + inf ("result %d: %s\n", i, tmpbuf); + snprintf (numbuf, sizeof numbuf, "%d:", i); + p = xstrconcat (tmpstring, numbuf, tmpbuf, "\n", NULL); + xfree (tmpstring); + tmpstring = p; + gcry_free (tmpbuf); + } + } + + resulthash = hash_buffer (tmpstring, strlen (tmpstring)); + xfree (tmpstring); + } + + if (verbose > 1) + { + inf ("cert(exp)=%s", certexpected); + inf ("cert(got)=%s", certstr? certstr:"[null]"); + inf ("key(exp)=%s", keyexpected); + inf ("key(got)=%s", resulthash? resulthash:"[null]"); + } + + ret = 1; + if (!result) + printresult ("FAIL: %s - error from parser\n", name); + else if (certexpected && !certstr) + printresult ("FAIL: %s - expected certs but got none\n", name); + else if (!certexpected && certstr) + printresult ("FAIL: %s - no certs expected but got one\n", name); + else if (certexpected && certstr && strcmp (certexpected, certstr)) + printresult ("FAIL: %s - certs not as expected\n", name); + else if (keyexpected && !resulthash) + printresult ("FAIL: %s - expected key but got none\n", name); + else if (!keyexpected && resulthash) + printresult ("FAIL: %s - key not expected but got one\n", name); + else if (keyexpected && resulthash && strcmp (keyexpected, resulthash)) + printresult ("FAIL: %s - keys not as expected\n", name); + else + { + printresult ("PASS: %s\n", name); + ret = 0; + } + + if (result) + { + int i; + for (i=0; result[i]; i++) + gcry_mpi_release (result[i]); + gcry_free (result); + } + xfree (certstr); + xfree (resulthash); + xfree (curve); + xfree (buf); + return ret; +} + + +/* Run a regression test using the Info take from DESCFNAME. */ +static int +run_tests_from_file (const char *descfname) +{ + FILE *fp; + char *descdir; + int lineno, ntests; + char *line; + char *name = NULL; + char *desc = NULL; + char *pass = NULL; + char *cert = NULL; + char *key = NULL; + int ret = 0; + char *p; + + inf ("Running tests from '%s'", descfname); + descdir = xstrdup (descfname); + p = strrchr (descdir, '/'); + if (p) + *p = 0; + else + { + xfree (descdir); + descdir = xstrdup ("."); + } + + fp = fopen (descfname, "r"); + if (!fp) + die ("error opening '%s': %s\n", descfname, strerror (errno)); + + lineno = ntests = 0; + while ((line = read_textline (fp, &lineno))) + { + if (!strncmp (line, "Name:", 5)) + { + if (name) + ret |= run_one_test (name, desc, pass, cert, key); + xfree (cert); cert = NULL; + xfree (desc); desc = NULL; + xfree (pass); pass = NULL; + xfree (key); key = NULL; + copy_data (&name, line, lineno); + if (name) + { + p = xstrconcat (descdir, "/", name, NULL); + xfree (name); + name = p; + } + } + else if (!strncmp (line, "Desc:", 5)) + copy_data (&desc, line, lineno); + else if (!strncmp (line, "Pass:", 5)) + copy_data (&pass, line, lineno); + else if (!strncmp (line, "Cert:", 5)) + { + p = NULL; + copy_data (&p, line, lineno); + hexdowncase (p); + if (p && cert) + cert = xstrconcat (cert, ",", p, NULL); + else + cert = p; + } + else if (!strncmp (line, "Key:", 4)) + { + copy_data (&key, line, lineno); + hexdowncase (key); + } + else + inf ("%s:%d: unknown tag ignored", descfname, lineno); + + xfree (line); + } + if (name) + ret |= run_one_test (name, desc, pass, cert, key); + xfree (name); + xfree (desc); + xfree (pass); + xfree (cert); + xfree (key); + + fclose (fp); + xfree (descdir); + return ret; +} + + + +int +main (int argc, char **argv) +{ + int last_argc = -1; + char const *name = NULL; + char const *pass = NULL; + int ret; + + 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 " []\n" + "Without a regression test is run\n" + "Options:\n" + " --verbose print timings etc.\n" + " given twice shows more\n" + " --debug flyswatter\n" + , stdout); + exit (0); + } + else if (!strcmp (*argv, "--verbose")) + { + verbose++; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose += 2; + debug++; + argc--; argv++; + } + else if (!strncmp (*argv, "--", 2)) + { + fprintf (stderr, PGM ": unknown option '%s'\n", *argv); + exit (1); + } + } + + if (!argc) + { + name = NULL; + pass = NULL; + } + else if (argc == 1) + { + name = argv[0]; + pass = ""; + } + else if (argc == 2) + { + name = argv[0]; + pass = argv[1]; + } + else + { + fprintf (stderr, "usage: " PGM " [ []]\n"); + exit (1); + } + + gcry_control (GCRYCTL_DISABLE_SECMEM, NULL); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL); + + if (name) + { + p12_set_verbosity (verbose, debug); + ret = one_file (name, pass); + } + else + { + char *descfname, *p; + + if (verbose > 1) + p12_set_verbosity (verbose > 1? (verbose - 1):0, debug); + descfname = prepend_srcdir ("../tests/cms/samplekeys/Description-p12"); + ret = run_tests_from_file (descfname); + xfree (descfname); + + /* Check whether we have non-public regression test cases. */ + p = value_from_gnupg_autogen_rc ("GNUPG_EXTRA_TESTS_DIR"); + if (p) + { + descfname = xstrconcat (p, "/pkcs12/Description", NULL); + xfree (p); + ret |= run_tests_from_file (descfname); + xfree (descfname); + } + } + + return ret; +} diff --git a/tests/cms/samplekeys/Description-p12 b/tests/cms/samplekeys/Description-p12 new file mode 100644 index 000000000..bd1e35c91 --- /dev/null +++ b/tests/cms/samplekeys/Description-p12 @@ -0,0 +1,20 @@ +# Description-p12 - Machine readable description of our P12 test vectors + +Name: ov-user.p12 +Desc: Private test key from www.openvalidation.org +Pass: start +Cert: 4753a910e0c8b4caa8663ca0e4273a884eb5397d +Key: 93be89edd11214ab74280d988a665b6beef876c5 + +Name: ov-server.p12 +Desc: Private test key from www.openvalidation.org +Pass: start +Cert: 1997fadf6cc1af03e4845c4cba38fb2397315143 +Key: 63b1d7233e75c3a462cb4b8ea3ad285e8ecba91c + +Name: opensc-test.p12 +Desc: PKCS#12 key and certificates taken from OpenSC (RC2+3DES,PKCS#8) +Pass: password +Cert: 115abfc3ae554092a57ade74177fedf9459af5d2 +Cert: a0d6d318952c313ff8c33cd3f629647ff1de76b3 +Key: 5a36c61706367ecdb52e8779e3a32bbac1069fa1 diff --git a/tests/cms/samplekeys/README b/tests/cms/samplekeys/README index 65255cb61..14bbf2bdc 100644 --- a/tests/cms/samplekeys/README +++ b/tests/cms/samplekeys/README @@ -1,10 +1,5 @@ This is a collection of keys we use with the regression tests. - -opensc-tests.p12 PKCS#12 key and certificates taken from OpenSC. - Passphrase is "password" - -ov-user.p12 Private tests keys from www.openvalidation.org. -ov-server.p12 Passphrase for both is "start" +For the *.p12 files see Description-p12 ossl-rentec-user.pem An OpenSSL generated user certificate using a bunch of attributes and DC RDNs. @@ -21,4 +16,3 @@ steed-self-signing-nonthority.pem The STEED Self-Signing Nonthority. 68A638998DFABAC510EA645CE34F9686B2EDF7EA.key The private Key of The STEED Self-Signing Nonthority. - From 3672c29156e3678014b16875ba8895cf5f02cafe Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 29 Jun 2023 14:01:40 +0900 Subject: [PATCH 095/869] common: Raise an error correctly in check_special_filename. * common/sysutils.c (check_special_filename): Use gnupg_parse_fdstr to check an error. -- GnuPG-bug-id: 6551 Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/common/sysutils.c b/common/sysutils.c index 5dfbb72e7..a780d564f 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -656,8 +656,27 @@ check_special_filename (const char *fname, int for_write, int notranslate) for (i=0; digitp (fname+i); i++ ) ; if (!fname[i]) - return notranslate? atoi (fname) - /**/ : translate_sys2libc_fd_int (atoi (fname), for_write); + { + if (notranslate) + return atoi (fname); + else + { + es_syshd_t syshd; + + if (gnupg_parse_fdstr (fname, &syshd)) + return -1; + +#ifdef HAVE_W32_SYSTEM + if (syshd.type == ES_SYSHD_FD) + return syshd.u.fd; + else + return translate_sys2libc_fd ((gnupg_fd_t)syshd.u.handle, for_write); +#else + (void)for_write; + return syshd.u.fd; +#endif + } + } } return -1; } From 6049d61991a1802e06d5b4aa4906c572ea00a871 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 29 Jun 2023 14:04:32 +0900 Subject: [PATCH 096/869] common: Fix the cast for 64-bit Windows. * common/sysutils.c (translate_sys2libc_fd_int): Fix the cast. -- FD should have a valid value here. For erroneous cases, it must be rejected by argparse handling. GnuPG-bug-id: 6551 Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/common/sysutils.c b/common/sysutils.c index a780d564f..8a1554a28 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -557,17 +557,15 @@ translate_sys2libc_fd (gnupg_fd_t fd, int for_write) } /* This is the same as translate_sys2libc_fd but takes an integer - which is assumed to be such an system handle. On WindowsCE the - passed FD is a rendezvous ID and the function finishes the pipe - creation. */ + which is assumed to be such an system handle. */ int translate_sys2libc_fd_int (int fd, int for_write) { #ifdef HAVE_W32_SYSTEM if (fd <= 2) - return fd; /* Do not do this for error, stdin, stdout, stderr. */ + return fd; /* Do not do this for stdin, stdout, and stderr. */ - return translate_sys2libc_fd ((void*)fd, for_write); + return translate_sys2libc_fd ((void*)(intptr_t)fd, for_write); #else (void)for_write; return fd; From 5f694dc0be994e8cd3bc009139d1349f3b1fcf62 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 29 Jun 2023 16:33:03 +0200 Subject: [PATCH 097/869] sm: Adding missing stuff to the PKCS#12 parser rewrite. * sm/minip12.c (struct bufferlist_s): New. (struct tlv_ctx_s): Add bufferlist. (tlv_register_buffer): New. (tlv_release): Release bufferlist. (tlv_expect_object): Handle octet string cramming. (tlv_expect_octet_string): Ditto. (cram_octet_string): Changed interface. We don't need the input_consumed value anymore. * sm/minip12.c (parse_shrouded_key_bag): Also parse the attribute set. * sm/t-minip12.c (main): Add option --no-extra. (cert_collect_cb, run_tests_from_file): Fix memory leak * tests/cms/samplekeys/t5793-openssl.pfx: New from T5793. * tests/cms/samplekeys/t5793-test.pfx: Ditto. * tests/cms/samplekeys/Description-p12: Add them. * tests/cms/Makefile.am (EXTRA_DIST): Add samplekeys. -- This should finish the rewrite of the pkcsc#12 parser for now. More fun is likely to come. GnuPG-bug-id: 6536, 5793 --- sm/minip12.c | 238 ++++++++++++++++--------- sm/t-minip12.c | 22 ++- tests/cms/Makefile.am | 8 +- tests/cms/samplekeys/Description-p12 | 12 ++ tests/cms/samplekeys/t5793-openssl.pfx | Bin 0 -> 4285 bytes tests/cms/samplekeys/t5793-test.pfx | Bin 0 -> 4328 bytes 6 files changed, 190 insertions(+), 90 deletions(-) create mode 100644 tests/cms/samplekeys/t5793-openssl.pfx create mode 100644 tests/cms/samplekeys/t5793-test.pfx diff --git a/sm/minip12.c b/sm/minip12.c index 69e23455a..eafebfe67 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -148,6 +148,14 @@ struct tag_info #define TLV_MAX_DEPTH 20 + +struct bufferlist_s +{ + struct bufferlist_s *next; + char *buffer; +}; + + /* An object to control the ASN.1 parsing. */ struct tlv_ctx_s { @@ -163,6 +171,8 @@ struct tlv_ctx_s gpg_error_t lasterr; /* Last error from tlv function. */ const char *lastfunc;/* Name of last called function. */ + struct bufferlist_s *bufferlist; /* To keep track of amlloced buffers. */ + unsigned int pop_count;/* Number of pops by tlv_next. */ unsigned int stacklen; /* Used size of the stack. */ struct { @@ -198,6 +208,12 @@ struct p12_parse_ctx_s static int opt_verbose; +static unsigned char *cram_octet_string (const unsigned char *input, + size_t length, size_t *r_newlength); + + + + void p12_set_verbosity (int verbose, int debug) { @@ -354,9 +370,36 @@ tlv_new (const unsigned char *buffer, size_t bufsize) } +/* This function can be used to store a malloced buffer into the TLV + * object. Ownership of BUFFER is thus transferred to TLV. This + * buffer will then only be released by tlv_release. */ +static gpg_error_t +tlv_register_buffer (struct tlv_ctx_s *tlv, char *buffer) +{ + struct bufferlist_s *item; + + item = xtrycalloc (1, sizeof *item); + if (!item) + return gpg_error_from_syserror (); + item->buffer = buffer; + item->next = tlv->bufferlist; + tlv->bufferlist = item; + return 0; +} + + static void tlv_release (struct tlv_ctx_s *tlv) { + if (!tlv) + return; + while (tlv->bufferlist) + { + struct bufferlist_s *save = tlv->bufferlist->next; + xfree (tlv->bufferlist->buffer); + xfree (tlv->bufferlist); + tlv->bufferlist = save; + } xfree (tlv); } @@ -457,7 +500,8 @@ tlv_next (struct tlv_ctx_s *tlv) /* End tag while in ndef container. Skip the tag, and pop. */ tlv->offset += n - (tlv->bufsize - tlv->offset); err = _tlv_pop (tlv); - // FIXME see above and run peek again. + /* FIXME: We need to peek whether there is another end tag and + * pop again. We can't modify the TLV object, though. */ if (err) return (tlv->lasterr = err); } @@ -558,24 +602,42 @@ tlv_expect_set (struct tlv_ctx_s *tlv) /* Expect an object of CLASS with TAG and store its value at * (R_DATA,R_DATALEN). Then skip over its value to the next tag. - * Note that the stored value are not allocated but point into + * Note that the stored value is not allocated but points into * TLV. */ static gpg_error_t tlv_expect_object (struct tlv_ctx_s *tlv, int class, int tag, unsigned char const **r_data, size_t *r_datalen) { + gpg_error_t err; const unsigned char *p; tlv->lastfunc = __func__; - if (!(tlv->ti.class == class && tlv->ti.tag == tag - && !tlv->ti.is_constructed)) + if (!(tlv->ti.class == class && tlv->ti.tag == tag)) return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); p = tlv->buffer + tlv->offset; if (!tlv->ti.length) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - *r_data = p; - *r_datalen = tlv->ti.length; + if (class == CLASS_CONTEXT && tag == 0 && tlv->ti.is_constructed) + { + char *newbuffer; + + newbuffer = cram_octet_string (p, tlv->ti.length, r_datalen); + if (!newbuffer) + return (tlv->lasterr = gpg_error (GPG_ERR_BAD_BER)); + err = tlv_register_buffer (tlv, newbuffer); + if (err) + { + xfree (newbuffer); + return (tlv->lasterr = err); + } + *r_data = newbuffer; + } + else + { + *r_data = p; + *r_datalen = tlv->ti.length; + } tlv->offset += tlv->ti.length; return 0; @@ -591,21 +653,40 @@ static gpg_error_t tlv_expect_octet_string (struct tlv_ctx_s *tlv, int encapsulates, unsigned char const **r_data, size_t *r_datalen) { + gpg_error_t err; const unsigned char *p; size_t n; tlv->lastfunc = __func__; if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_OCTET_STRING - && !tlv->ti.is_constructed)) + && (!tlv->ti.is_constructed || encapsulates))) return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); p = tlv->buffer + tlv->offset; if (!(n=tlv->ti.length)) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - if (r_data) - *r_data = p; - if (r_datalen) - *r_datalen = tlv->ti.length; + if (encapsulates && tlv->ti.is_constructed) + { + char *newbuffer; + + newbuffer = cram_octet_string (p, n, r_datalen); + if (!newbuffer) + return (tlv->lasterr = gpg_error (GPG_ERR_BAD_BER)); + err = tlv_register_buffer (tlv, newbuffer); + if (err) + { + xfree (newbuffer); + return (tlv->lasterr = err); + } + *r_data = newbuffer; + } + else + { + if (r_data) + *r_data = p; + if (r_datalen) + *r_datalen = tlv->ti.length; + } if (encapsulates) return _tlv_push (tlv); @@ -716,37 +797,37 @@ tlv_expect_object_id (struct tlv_ctx_s *tlv, /* Given an ASN.1 chunk of a structure like: - - 24 NDEF: OCTET STRING -- This is not passed to us - 04 1: OCTET STRING -- INPUT point s to here - : 30 - 04 1: OCTET STRING - : 80 - [...] - 04 2: OCTET STRING - : 00 00 - : } -- This denotes a Null tag and are the last - -- two bytes in INPUT. - - Create a new buffer with the content of that octet string. INPUT - is the original buffer with a length as stored at LENGTH. Returns - NULL on error or a new malloced buffer with the length of this new - buffer stored at LENGTH and the number of bytes parsed from input - are added to the value stored at INPUT_CONSUMED. INPUT_CONSUMED is - allowed to be passed as NULL if the caller is not interested in - this value. */ + * + * 24 NDEF: OCTET STRING -- This is not passed to us + * 04 1: OCTET STRING -- INPUT point s to here + * : 30 + * 04 1: OCTET STRING + * : 80 + * [...] + * 04 2: OCTET STRING + * : 00 00 + * : } -- This denotes a Null tag and are the last + * -- two bytes in INPUT. + * + * The example is from Mozilla Firefox 1.0.4 which actually exports + * certs as single byte chunks of octet strings. + * + * Create a new buffer with the content of that octet string. INPUT + * is the original buffer with a LENGTH. Returns + * NULL on error or a new malloced buffer with its actual used length + * stored at R_NEWLENGTH. */ static unsigned char * -cram_octet_string (const unsigned char *input, size_t *length, - size_t *input_consumed) +cram_octet_string (const unsigned char *input, size_t length, + size_t *r_newlength) { const unsigned char *s = input; - size_t n = *length; + size_t n = length; unsigned char *output, *d; struct tag_info ti; /* Allocate output buf. We know that it won't be longer than the input buffer. */ - d = output = gcry_malloc (n); + d = output = gcry_malloc (length); if (!output) goto bailout; @@ -769,20 +850,15 @@ cram_octet_string (const unsigned char *input, size_t *length, } - *length = d - output; - if (input_consumed) - *input_consumed += s - input; + *r_newlength = d - output; return output; bailout: - if (input_consumed) - *input_consumed += s - input; gcry_free (output); return NULL; } - static int string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw, int req_keylen, unsigned char *keybuf) @@ -1331,38 +1407,6 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) if (tlv_next (tlv)) goto bailout; - /* consumed = p - p_start; */ - /* if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef) */ - /* { */ - /* /\* Mozilla exported certs now come with single byte chunks of */ - /* octet strings. (Mozilla Firefox 1.0.4). Arghh. *\/ */ - /* where = "cram-rc2or3des-ciphertext"; */ - /* cram_buffer = cram_octet_string ( p, &n, &consumed); */ - /* if (!cram_buffer) */ - /* goto bailout; */ - /* p = p_start = cram_buffer; */ - /* if (r_consumed) */ - /* *r_consumed = consumed; */ - /* r_consumed = NULL; /\* Donot update that value on return. *\/ */ - /* ti.length = n; */ - /* } */ - /* else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed) */ - /* { */ - /* where = "octets-rc2or3des-ciphertext"; */ - /* n = ti.length; */ - /* cram_buffer = cram_octet_string ( p, &n, &consumed); */ - /* if (!cram_buffer) */ - /* goto bailout; */ - /* p = p_start = cram_buffer; */ - /* if (r_consumed) */ - /* *r_consumed = consumed; */ - /* r_consumed = NULL; /\* Do not update that value on return. *\/ */ - /* ti.length = n; */ - /* } */ - /* else if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.length ) */ - /* ; */ - /* else */ - /* goto bailout; */ if (tlv_expect_object (tlv, CLASS_CONTEXT, 0, &data, &datalen)) goto bailout; @@ -1538,7 +1582,8 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) keyelem_count, gpg_strerror (err)); goto bailout; } - log_debug ("RSA key parameter %d found\n", keyelem_count); + if (opt_verbose > 1) + log_debug ("RSA key parameter %d found\n", keyelem_count); keyelem_count++; } if (err && gpg_err_code (err) != GPG_ERR_EOF) @@ -1683,6 +1728,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) size_t saltlen; char iv[16]; unsigned int iter; + struct tlv_ctx_s *saved_tlv = NULL; int renewed_tlv = 0; /* True if the TLV must be released. */ unsigned char *plain = NULL; int is_pbes2 = 0; @@ -1865,8 +1911,10 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) : GCRY_CIPHER_3DES, bag_data_p); + /* We do not need the TLV anymore and allocated a new one. */ where = "shrouded_key_bag.decrypted-text"; + saved_tlv = tlv; tlv = tlv_new (plain, datalen); if (!tlv) { @@ -1874,6 +1922,8 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; } renewed_tlv = 1; + if (opt_verbose > 1) + log_debug ("new parser context\n"); if (tlv_next (tlv)) { @@ -2037,10 +2087,39 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) err = 0; } + if (opt_verbose > 1) + log_debug ("restoring parser context\n"); + tlv_release (tlv); + renewed_tlv = 0; + tlv = saved_tlv; + + where = "shrouded_key_bag.attribute_set"; + err = tlv_next (tlv); + if (gpg_err_code (err) == GPG_ERR_EOF) + goto leave; + if (err) + goto bailout; + err = tlv_expect_set (tlv); + if (!err) + { /* This is the optional set of attributes. Skip it. */ + tlv_skip (tlv); + if (opt_verbose) + log_info ("skipping %s\n", where); + } + else if (gpg_err_code (err) == GPG_ERR_INV_OBJ) + tlv_set_pending (tlv); /* The next tlv_next will be skipped. */ + else /* Other error. */ + goto bailout; + + leave: gcry_free (plain); if (renewed_tlv) - tlv_release (tlv); + { + tlv_release (tlv); + if (opt_verbose > 1) + log_debug ("parser context released\n"); + } return err; bailout: @@ -2322,17 +2401,6 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, if (tlv_next (tlv)) goto bailout; - if (tlv->ti.is_constructed && tlv->ti.ndef) - { - log_debug ("FIXME Put this into our TLV machinery.\n"); - /* /\* Mozilla exported certs now come with single byte chunks of */ - /* octet strings. (Mozilla Firefox 1.0.4). Arghh. *\/ */ - /* where = "cram-bags"; */ - /* cram_buffer = cram_octet_string ( p, &n, NULL); */ - /* if (!cram_buffer) */ - /* goto bailout; */ - /* p = p_start = cram_buffer; */ - } if (tlv_expect_octet_string (tlv, 1, NULL, NULL)) goto bailout; diff --git a/sm/t-minip12.c b/sm/t-minip12.c index 80ba4c69e..de6b7e5cc 100644 --- a/sm/t-minip12.c +++ b/sm/t-minip12.c @@ -444,12 +444,14 @@ static void cert_collect_cb (void *opaque, const unsigned char *cert, size_t certlen) { char **certstr = opaque; - char *hash; + char *hash, *save; hash = hash_buffer (cert, certlen); if (*certstr) { - *certstr = xstrconcat (*certstr, ",", hash, NULL); + save = *certstr; + *certstr = xstrconcat (save, ",", hash, NULL); + xfree (save); xfree (hash); } else @@ -645,7 +647,12 @@ run_tests_from_file (const char *descfname) copy_data (&p, line, lineno); hexdowncase (p); if (p && cert) - cert = xstrconcat (cert, ",", p, NULL); + { + char *save = cert; + cert = xstrconcat (save, ",", p, NULL); + xfree (save); + xfree (p); + } else cert = p; } @@ -681,6 +688,7 @@ main (int argc, char **argv) char const *name = NULL; char const *pass = NULL; int ret; + int no_extra = 0; if (argc) { argc--; argv++; } @@ -697,12 +705,18 @@ main (int argc, char **argv) fputs ("usage: " PGM " []\n" "Without a regression test is run\n" "Options:\n" + " --no-extra do not run extra tests\n" " --verbose print timings etc.\n" " given twice shows more\n" " --debug flyswatter\n" , stdout); exit (0); } + else if (!strcmp (*argv, "--no-extra")) + { + no_extra = 1; + argc--; argv++; + } else if (!strcmp (*argv, "--verbose")) { verbose++; @@ -761,7 +775,7 @@ main (int argc, char **argv) xfree (descfname); /* Check whether we have non-public regression test cases. */ - p = value_from_gnupg_autogen_rc ("GNUPG_EXTRA_TESTS_DIR"); + p = no_extra? NULL:value_from_gnupg_autogen_rc ("GNUPG_EXTRA_TESTS_DIR"); if (p) { descfname = xstrconcat (p, "/pkcs12/Description", NULL); diff --git a/tests/cms/Makefile.am b/tests/cms/Makefile.am index 60fdf0281..7efdf37b1 100644 --- a/tests/cms/Makefile.am +++ b/tests/cms/Makefile.am @@ -86,13 +86,19 @@ TEST_FILES = plain-1.cms.asc \ testscripts = sm-sign+verify sm-verify EXTRA_DIST = $(XTESTS) $(KEYS) $(CERTS) $(TEST_FILES) \ + samplemsgs/README \ + samplekeys/Description-p12 \ samplekeys/steed-self-signing-nonthority.pem \ samplekeys/68A638998DFABAC510EA645CE34F9686B2EDF7EA.key \ samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key \ samplekeys/cert_g10code_pete1.pem \ samplekeys/cert_g10code_test1.pem \ samplekeys/cert_g10code_theo1.pem \ - samplemsgs/README \ + samplekeys/ov-user.p12 \ + samplekeys/ov-server.p12 \ + samplekeys/opensc-test.p12 \ + samplekeys/t5793-openssl.pfx \ + samplekeys/t5793-test.pfx \ samplemsgs/pwri-sample.cbc.p7m \ samplemsgs/pwri-sample.cbc-2.p7m \ samplemsgs/pwri-sample.gcm.p7m \ diff --git a/tests/cms/samplekeys/Description-p12 b/tests/cms/samplekeys/Description-p12 index bd1e35c91..f882de9ea 100644 --- a/tests/cms/samplekeys/Description-p12 +++ b/tests/cms/samplekeys/Description-p12 @@ -18,3 +18,15 @@ Pass: password Cert: 115abfc3ae554092a57ade74177fedf9459af5d2 Cert: a0d6d318952c313ff8c33cd3f629647ff1de76b3 Key: 5a36c61706367ecdb52e8779e3a32bbac1069fa1 + +Name: t5793-openssl.pfx +Desc: self-signed key issued keys +Pass: test +Cert: 80348a438e4b803b99e708da0b7fdd0659dedd15 +Key: c271e44ab4fb19ca1aae71102ea4d7292ccc981d + +Name: t5793-test.pfx +Desc: QuaVadis format of t5793-openssl +Pass: test +Cert: 80348a438e4b803b99e708da0b7fdd0659dedd15 +Key: c271e44ab4fb19ca1aae71102ea4d7292ccc981d diff --git a/tests/cms/samplekeys/t5793-openssl.pfx b/tests/cms/samplekeys/t5793-openssl.pfx new file mode 100644 index 0000000000000000000000000000000000000000..0f1beed0fb3edbcec8a8298096fac4c333606496 GIT binary patch literal 4285 zcmY+GWmFW5vxkY@r9(=(L8MbbS}8$+mu`urV+nx;=?0NlQjkuGrE^881qtb1N>WOe zMqrogd(OT0fA5DmbI$WSGau&}(Fn>8JY0Oy2+B|p5r2$E%oQ0f0d8Rgr6(YQ((NyH z5{&>A{3ikxMu1ZOqC`AgoWCvlKMAfVGl=-VH<03jM9Be!y4(ZunJSghczA?3VG$sc z#uv4MPwPBKfoEU_re)y>VU{l*_7}$6*I9clKx>=#YdhDz1jkPWRpp)p4ErDeye!mk zDJ*o8H!L-oS32SCTX%Va^3PO>%`@MIu8DEWo18idhW8kD7WHPyaeze|5)>J>V;&OK zKGXBfsl-~K@1Bw|)6wI*9uSWy3@@rG$s||4jTDy! z-x~VIj_5E+RZM+`nlUEwCGOd3LnCCt>tW#MCfghy>o(^)on(%bBZyXTRJ-7X%fiwwWAiRcpC0XplF1ee-T{^|Fdm!FK) z^BfnOqFg>)5gw`;!1j@PnszwoWH1GooY;D4(&YB`O$tF1>_I=+FR*W*Pu_8ikT#Jm z)Q1V=_V3OySx5iw%Spxze$u-b!dg-ve+9jHuU|3SE>mzctaq3VQ}qXEptl%eauUXI zbJn=M&K3Z>NcE>X8uy6G%C5aZ9Boq|!ka+^t9zflTGOA$5WrgSb*8OFHy z6@gnn6U?*l4@5Ntl8>+Ky&!RHU01SFN6(%B^_UK9t6(@q0$JAMibp?D)nyF;r6=L} z(W{(ox}Qu3LRMwMo3E+rw0}p5!OR^WJYw5fvUuS(B;f3b;@3}6ZH~O&dlpFG1^Gn% zZB6YJLE@pA7_d3rEBiO+2jIrjj1SUn)es7)Yq z`iiu5YE1`&M$<0<8|)$N!aj=nE@O$(`n(%-St$zQ0eLsA&s!q)Qbh}tPP5FhX!h=U zSk2Ox5-Q?4Rjns9>w2esjJB0Gx~^=`E(UaS1CS@Bb5rr)BHu7pQPe13&wD5Ma<5Tm z=05n~ax|6Q`vDaZ_sOmJnoo!MuV3ZPicK%6Q9na0D+k`dIiWf@nQ=!<^;3+6qUlme zR9E~K13;H~4L)#(vD%}o`fd-u8{2%ZKttS9fvW6kI_vflMsioJSbC(qM3?NPhOI&? z`@rCb;rjl&tF2|5khc;stT@3H(7kA+HFuoOXqU=#CB95brzv8F4W}92VaQ#N^Ji)+vZWgO@@wX*;C&i;x}*< zYM2yIWBj zcODJoQr_$Ht|MG_Wvy}*x?>w?Wofe>YqorR6H%^xd1v|&H?w6cqw+zews1mAPi`AmTEUD3G3uTics}k;wKAxba=lem!grOUDL_cLyZ&V zI%HZNu=)I2yN00&hrTd}<}7Y=@V>qDKMYkt*dCF=6S(w0a`>jcO|9RAPorS&h8*on ztDX~dngtyV%nk@+$yc4YU^3)SW;~19-A@t*(r(tpvAyP)dIQr7g60erTG`S4u5f-* zo@sl2X@iy;UeO4mp8q4F!U&>9Km-x|FRuDqs?upx|46l zNfC>{X^rB`FD`_ryR3=)Hf=n? z@hZsL%ket~A69J?;iyNFdzsyj8*H-)<_uyKs=15ZcnC#H;V*0nIFMiTs86a^LvIz* zn*4q?!(9VbQyDgKZH(_Et@61*iAEfd04`%o_-M!4QFH~)O8%ze)eHAF`tZFIQ@G)9 zg}wpOqK%}?Z&_FZNCnesHupyx!NNzy+(VP6UyY4r9ixL_+M8w9n4{T!;wI0C{aPnp zzv9TJGFjd3wLvIP2c<6PSf=%JCRFTvkajEaX^BUl;(q)0&=1w?UWok^u~g!L`U6P% zP_3Rc@amD0aDjgIYbEJ*^#m@q@k|5kWAEb*C-X=G_4f~YeU|gS736qVbenv^7Q21H zlK7g9!`6aJk1yhA%VIKahKA`t2-Zm%rXKImKqLY)MmbO`)u z^-ez6AEN73Y3NDZ<$fOBUoz=SkTdO7sF?bgB@Yroexl2ab7aw<`2Gx@ze3I~-Z7v@h9u?rb;X8{;J}L?g-A&YW zOL=>)bY7!K>u}hh`)Fdvpw(wzU#D^s@#U*DEu@X|1`KGm zti{new(UNJ9_Lj=GVdq9c_%x@JiC-)E^HsJE42K~`gd^FSM#=ig2>$h8a;OVMJ$WC z1Qd$Q1wra&1To_`o zo@@Ssg~y7{;=ok)tj;{{Id)wqv}Yx_Uu<(k=csq2^X^jzvM+41)hp~^^X9YNW8jn_ z`nC&K?)gRTgV5?T4vwT_sfgnE*mY4gxZqd+WM?5nlNC*`8RakhkAC;)jgYH)q}w4X zI6mGyc5~aYv?H#Xs2=`8A{3X!kBux=CKPUP^E=*GRRFVZPyDV~_d3mwI)|$yl_Q@l zQrcVE7y;9ld%~L1X#O&u8a%k>9TYT}cPFc4JI3jA*>a5|w9PKdeCjIe&=ti#HGpD1 zFMEFgEa$X7bAZ#ut%rLliNsKxU0<%>Vdi+|_)ODvc-DkZ*c#^ob$rpOl^P^n zHYH^YOg$P&1vjr>S#y4|$EgBRe*co?M&ODjTN3D&s8!p&U_FfkMmE~@PoIo+*SwAq zdp616>`eYE)^XOq%?9E3Xcr_B!r@1L2$TFdCfYx9_jguawF8D4)wf zxDjPMlf~n9DcjM66%$`w^LR-60%o+omvtnYNQ{2Rxe@&6XVqC~w)l|h*fJ|lAS#2u ziYcSQOn)$I7MvDHyEZ$*w?tB|v`(tda`$wBkvGAI0RyJ_-NwZ@x;+vmIfLVxMnZ+I zgLX%6hs(K!z?NzqD{t>D3N+tlf`uM_q3GK_LNig0Ln0<>Zpfk`I!-`6SJSfB(J)E_ z2xmG~L2%og#q?Vx*Y1nWewfkKH94;!a^kD$)z3%+@`C2)p0#2eqdZ9u0SGlClfcZa zD-l0pE=$}WWiN(#H3Y?^Vul-blFrsouo9V=QX$L#B`>6_Dxb3azM^D2FH!2q-{~kH-ka0nkX>9QPB{ox8C_ cujDZ|LX+opIQ||~Ct}N@Gm9v{f4{W<0(8!4BvoPr1^#q9z|b*-q;!Kw3@J#bbk~Sd0}|3bl%$jl zjljU=uJyk6uKQu1eb(>U&;ELzBN9rnfs2DD5=v1HCgh8RL|%~M;N#?lQe*)`Dbnw8 zvPdZ5#{Wo!)4))|@q7I9z6QX=|K}nh!okf8C3Lxm4kAooqW{PD%gKNQdpks4%pwH)o;yg7J^b2!eg`RE^_KYyUHcZ4#bTzruSJ9`?>!4d;Y-TEdDZP} zxA9z(2nXRf!pM?(@VBn~x9%>F19C?12y*TOwLUd@NTan&$9K4mWj@rK?4<5QmBoFIY%VMy zvnLr-+Pa89mQO#B9(7N7IX_O^ow06+Q8kKAoIRMTv9J0lkOgLTdtdCYYUi1Hl+Vn6 zT&XbDZ`l7`G4hY#-k1{K;qvMHf?vVb+!)uQ_?`VZUK`(Ovel`$d-PI;5ZjZXp0xu# zAqc7Mc8Taq!}*^%m^@2xZbC?{8*j>w4cF(3#1`SXwyUuAvok@e4k)45x`it&MhR7Q zK6*p%!J>gC7~UF+mM}gsg5gG_*}~;H+cPO ztakKWPNHAOu`sxiFwfxx$LX`feK`%xs)yTF4kAhcOF8Qb7cZS#=t6dmjH>kpOLcTn zrY*$9UW-EFAWDRKqlq_09}zMv>Kv3X`Fdm|{Sf1i&{!|N#2!rV5;eGn?pE3Hcol>_ zl}_(;uJT8_+9-DTjHE$dFruSo{WY42jtgCS6n0yG1bwVnbwlnZiY5{D)$YMl2CB5B zKo^e`g>rQ=-Y80~s>X7%j;86}K6XEBvoi_9SN-sy+hZ~Ndv2zCX{X`W+XAPrx5S>t zqllG&qQkRjn&QaRtARmUFp_0lnz740$Pb0Yj!^WO~Kh>-MZ5MP%UD~vpSGZ%=|G3xiavE-VoWkSLp$i=TQ-d3PF?NO3+R}} zqea#S9G~o!94Qj}NRV~ArpwQ_IS)btIS+De!fUS7;f(cPOQ4np1>rG~lWVIJQ;^`@0* zTHBWGr#^?-rD06F32)!aj4(|vB$^0WhiC~dK7;-VNdIQi@{d26lW)DtcCWBm0jFGh zOY1%?&SH{}1dJB!)Z){K(DRR_9Wz?PUq#aIX4}!F<=d)R!nY3hUo1KjeJ5JIQic`& z4T;~^G5?@n{#!^;q06VK-pcl|mn8wwzH7;l`r(D2^iA35S9sB}prw2#p_9d>cnYTx z>W$P~H18ddARjWAr@LI?Rc>AoyM~u)N&~~T@n1+fIMsY)*r;OdpoCV4dON~ zWC37dxDWQD7puph2|dhp z2afEEv#bX}6({WM@rRP31u;>pA}ZAa-@Fs-1(6Nr)ZNAuzwthK-C@=OFKSUv`{;m} z7?Y^=P1~Zj=nBHx>X+g{ILuzGq*2mA)w)-IVmy`kvAfnp?;Eu)lf9@iISZ56b4bIa z+@%bV2p!ocEQ$3duVScR{VVSN{{7iEGK!WX93JOQmjJ;{HW{X4M;V)raJGp)G}CGE zhdodU2lT|Inl^eh#7$8+lKkZIeDwx9!{hY4YY)O}l%mPKB6P%BKjWwAiAgGh5O-J< z7Sl6!LE>|--n@o#e6rVcZyf3Y@e|lM}xxZt$HVqMmj6sM2bEe z=WDbldpp+Yn`L=7?vAh0?VR4J8e~z))V!3u6os|s4Bq!LwozFfE_8@0`H_r$&sm!0 zN3$s4tMn0%(Uw0;Hb`SAhrhCO1UgMAL`_>KaYiY>kaA12abtAHX3(HE1d-;}lT1)C z@ZQFoHg}~Y^RU6h7y%==SeP1cODtFBH?*pmV>9ECojEI1)3qRmiiwz8lYV`ViW^UC zL=>d%wZ1-Nf`yJVpIweo{tF59SkSFU0g)IN@8n-;tH_5<`CAjMJ%$FS-V_uGE@gpX zr7xvwjD_^1OreRA>+0IsO26XAzg^3z!l~R2JE}p|>oEvwz~Z|P7bzFd$#^MVNW;01 z#oXfsqgIKV5d@`U-yE~KNqT&zG=3DfB^Zhi{{UPGeDX4H&oiEXNO@?M9?c(~%2&>q zT57D*pFRys_M=&u9^zdfE>T=1QDwe)I>*2h>p_o&QU7V-WEkEY3YM4xI3^QQVrqOk zBQ`^19Rm>yRkmfU zg)%pwWyW;!ouXss*?KQR|KgI2M*ubU&FJD+m@Zjv;|td+QTAc(_=iBGioT&=+Qx;j z7ZIl!&d=hPgFFxcQOU@`x~=$=)uUVSH0|VS@lxoUYJGak8t?i76EY4_VFbhPp^uA`IRxR+Emv~|@BKGV%+i-lU zkD^bZ>8BgG#G@|!3LfMFf6iS4s$1LLm;RSM4U=rA_FT0Thy8wQ)^#Iq06;F$WpP;| zM{qZrB+6O-lM{{pmJ?`cE&a8Ea5F?Yk2q~NGMx){rT8?z&m`KXoB&r8BEtEfbVf)c zN(-b8mWX{BuO2M(X`5hyIA{rMw7f(k!v5bOYEfzyO29jSHNfNk6a-k^-`oN3L_)!( z{~5vu=Y@hZ?okRZ4&c6h{I7!ZKj9Ai?{KHZ)hCyxR2K2?aCh&60z+|5>t9w0JgspZ z2A#m@85e~@g_ys(Sf3eeUZ(FffuI&2R<phsFZn_l*Esck;F1WZq`|H&cW{S(YhHVr3;@bs6DLo#9B~n^@R*!!Od?VT z|8SLvoQxRVc7eN0V0qBx@rGG)H4H`buM(TLRy_Qm;gXt`DdLJ~FSRs?t$lBR|6@VjUxV~#qnz`S)749j zZMid}pFaoK*r^DP2rUMiJ{F~6qwb9e^-j}LHOAcjOC1@i9R`dOIh{RH6&`$T5!xZJ1+v#74k)ss_}l9>D>ojc?K&ztL9w{M zBs5UjciThaYSd<8YYqO%c6R&L=gE8aA(95tx!Pd(MeFu5eUaWw8Hrd0U?>oF;WQPudZp-}oG4<CQZ%7-<7 z!JlR3>kF^*BO6`Xc}Z;BysBufikUtFX*2FwmLmZ9{OQn9g@a${isCw;;**e^h-Hoz zte%jhB=)8h^q?5hk_|9YVwVf_rSC%<$etI~^{N))Hw9wW<1~NzWC_0p!c!$h6#8SSQt*`&% zU~TWs#m1sV;5+e17C=A)01Ft~WE@N*{GI}>U=N6~U)Sh4GPFq~;=7 z!stAoFyN5v{J~9^%f&oQ8ry-i<+nAXN$Wyl;X0oTRqiJJ;xg2`;f>@VAX9J`et}@8 zsrY_4a!VzIqzKdeI; z;Y12Fu(NCX&XJWP6X`u#zEYwAi0}-`xvGgV<$^%DDKW5o5+LXG4;$@#=E)ti7+PV* z&Ix1GqA8+vs~r`cl%q`H7MzhCPp(PsUH%6au(wa6>%N~?z2*oyaWd$(!Y%?7H zhW@abR(>zf>AZ=*v}Rhyvg$tiO4&gHglFJHJ`@~DriX@ql`1sF<6 z<4q7e8n6CS?2&ax Date: Fri, 30 Jun 2023 15:56:43 +0900 Subject: [PATCH 098/869] common:iobuf: Avoid losing bits of HANDLE on Windows 64-bit. * common/iobuf.c (translate_file_handle): Change the return type to gnupg_fd_t, not to lose the bits for HANDLE silently. (do_iobuf_fdopen): Use the type gnupg_fd_t for the first argument. (do_open): Use do_iobuf_fdopen instead of iobuf_fdopen. (iobuf_fdopen, iobuf_fdopen_nc): Follow the change of API. -- GnuPG-bug-id: 6508 Signed-off-by: NIIBE Yutaka --- common/iobuf.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index 8da591046..2adf61e3c 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -166,7 +166,9 @@ block_filter_ctx_t; /* Local prototypes. */ static int underflow (iobuf_t a, int clear_pending_eof); static int underflow_target (iobuf_t a, int clear_pending_eof, size_t target); -static int translate_file_handle (int fd, int for_write); +static gnupg_fd_t translate_file_handle (int fd, int for_write); +static iobuf_t do_iobuf_fdopen (gnupg_fd_t fp, const char *mode, int keep_open); + /* Sends any pending data to the filter's FILTER function. Note: this works on the filter and not on the whole pipeline. That is, @@ -1444,8 +1446,8 @@ do_open (const char *fname, int special_filenames, return NULL; else if (special_filenames && (fd = check_special_filename (fname, 0, 1)) != -1) - return iobuf_fdopen (translate_file_handle (fd, use == IOBUF_INPUT ? 0 : 1), - opentype); + return do_iobuf_fdopen (translate_file_handle (fd, use == IOBUF_INPUT + ? 0 : 1), opentype, 0); else { if (use == IOBUF_INPUT) @@ -1493,22 +1495,19 @@ iobuf_openrw (const char *fname) static iobuf_t -do_iobuf_fdopen (int fd, const char *mode, int keep_open) +do_iobuf_fdopen (gnupg_fd_t fp, const char *mode, int keep_open) { iobuf_t a; - gnupg_fd_t fp; file_filter_ctx_t *fcx; size_t len = 0; - fp = INT2FD (fd); - a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT, iobuf_buffer_size); fcx = xmalloc (sizeof *fcx + 20); fcx->fp = fp; fcx->print_only_name = 1; fcx->keep_open = keep_open; - sprintf (fcx->fname, "[fd %d]", fd); + sprintf (fcx->fname, "[fd %d]", (int)(intptr_t)fp); a->filter = file_filter; a->filter_ov = fcx; file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); @@ -1523,13 +1522,15 @@ do_iobuf_fdopen (int fd, const char *mode, int keep_open) iobuf_t iobuf_fdopen (int fd, const char *mode) { - return do_iobuf_fdopen (fd, mode, 0); + gnupg_fd_t fp = INT2FD (fd); + return do_iobuf_fdopen (fp, mode, 0); } iobuf_t iobuf_fdopen_nc (int fd, const char *mode) { - return do_iobuf_fdopen (fd, mode, 1); + gnupg_fd_t fp = INT2FD (fd); + return do_iobuf_fdopen (fp, mode, 1); } @@ -2985,34 +2986,34 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, return nbytes; } -static int +static gnupg_fd_t translate_file_handle (int fd, int for_write) { #if defined(HAVE_W32_SYSTEM) { - int x; + gnupg_fd_t x; (void)for_write; if (fd == 0) - x = (int) GetStdHandle (STD_INPUT_HANDLE); + x = GetStdHandle (STD_INPUT_HANDLE); else if (fd == 1) - x = (int) GetStdHandle (STD_OUTPUT_HANDLE); + x = GetStdHandle (STD_OUTPUT_HANDLE); else if (fd == 2) - x = (int) GetStdHandle (STD_ERROR_HANDLE); + x = GetStdHandle (STD_ERROR_HANDLE); else - x = fd; + x = (gnupg_fd_t)(intptr_t)fd; - if (x == -1) + if (x == INVALID_HANDLE_VALUE) log_debug ("GetStdHandle(%d) failed: ec=%d\n", fd, (int) GetLastError ()); - fd = x; + return x; } #else (void)for_write; -#endif return fd; +#endif } From 5377226ec0b9d725a308e1b5690b3485fef586a1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 30 Jun 2023 10:59:06 +0200 Subject: [PATCH 099/869] Prepare NEWS for the next release -- --- NEWS | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 14c2251bf..a30440b47 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,45 @@ Noteworthy changes in version 2.4.3 (unreleased) ------------------------------------------------ - Release-info: https://dev.gnupg.org/T6506 + * gpg: Set default expiration date to 3 years. [T2701] + + * gpg: Add --list-filter properties "key_expires" and + "key_expires_d". [T6529] + + * gpg: Emit status line and proper diagnostics for write errors. + [T6528] + + * gpg: Make progress work for large files on Windows. [T6534] + + * gpg: New option --no-compress as alias for -z0. + + * gpgsm: Print PROGRESS status lines. Add new --input-size-hint. + [T6534] + + * gpgsm: Support SENDCERT_SKI for --call-dirmngr. [rG701a8b30f0] + + * gpgsm: Major rewrite of the PKCS#12 parser. [T6536] + + * gpgtar: New option --no-compress. + + * dirmngr: Extend the AD_QUERY command. [rG207c99567c] + + * dirmngr: Disable the HTTP redirect rewriting. [T6477] + + * dirmngr: New option --compatibility-flags. [rGbf04b07327] + + * dirmngr: New option --ignore-crl-extensions. [T6545] + + * wkd: Use export-clean for gpg-wks-client's --mirror and --create + commands. [rG2c7f7a5a27] + + * wkd: Make --add-revocs the default in gpg-wks-client. New option + --no-add-revocs. [rG10c937ee68] + + * scd: Fix authentication with Administration Key for PIV. + [rG25b59cf6ce] + + Release-info: https://dev.gnupg.org/T6509 Noteworthy changes in version 2.4.2 (2023-05-30) From a0ff2919f710a7d5b55ac1cc9106de71229b7c56 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 3 Jul 2023 10:20:06 +0900 Subject: [PATCH 100/869] tools:gpg-connect-agent: Fix use of HANDLE on Windows. * tools/gpg-connect-agent.c [HAVE_W32_SYSTEM] (do_open): Use %p to format the HANDLE. [HAVE_W32_SYSTEM] (do_close): Use gnupg_parse_fdstr to parse the string representation of the HANDLE. Use %p. -- GnuPG-bug-id: 6508 Signed-off-by: NIIBE Yutaka --- tools/gpg-connect-agent.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index 4dfb57896..6be401c4f 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -1038,6 +1038,7 @@ do_open (char *line) #if defined(HAVE_W32_SYSTEM) { HANDLE prochandle, handle, newhandle; + char numbuf[35]; handle = (void*)_get_osfhandle (fd); @@ -1060,11 +1061,13 @@ do_open (char *line) } CloseHandle (prochandle); open_fd_table[fd].handle = newhandle; + + snprintf (numbuf, sizeof numbuf, "%p", open_fd_table[fd].handle); + set_var (varname, numbuf); } if (opt.verbose) log_info ("file '%s' opened in \"%s\" mode, fd=%p (libc=%d)\n", name, mode, open_fd_table[fd].handle, fd); - set_int_var (varname, (int)open_fd_table[fd].handle); #else /* Unix */ if (opt.verbose) log_info ("file '%s' opened in \"%s\" mode, fd=%d\n", @@ -1085,13 +1088,28 @@ do_open (char *line) static void do_close (char *line) { - int fd = atoi (line); + int fd; #ifdef HAVE_W32_SYSTEM int i; + gpg_error_t err; + es_syshd_t syshd; + + err = gnupg_parse_fdstr (line, &syshd); + if (err) + { + log_error ("given fd (system handle) is not valid\n"); + return; + } + + if (syshd.type == ES_SYSHD_FD) + { + log_error ("given fd is stdin/out/err\n"); + return; + } for (i=0; i < DIM (open_fd_table); i++) - if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd) + if (open_fd_table[i].inuse && open_fd_table[i].handle == syshd.u.handle) break; if (i < DIM (open_fd_table)) fd = i; @@ -1100,6 +1118,8 @@ do_close (char *line) log_error ("given fd (system handle) has not been opened\n"); return; } +#else + fd = atoi (line); #endif if (fd < 0 || fd >= DIM (open_fd_table)) @@ -1130,7 +1150,7 @@ do_showopen (void) if (open_fd_table[i].inuse) { #ifdef HAVE_W32_SYSTEM - printf ("%-15d (libc=%d)\n", (int)open_fd_table[i].handle, i); + printf ("%p (libc=%d)\n", open_fd_table[i].handle, i); #else printf ("%-15d\n", i); #endif From b5efb52d4320ee9e7ea03a6f7e63ff140a1df846 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 3 Jul 2023 10:46:46 +0900 Subject: [PATCH 101/869] agent: Fix formatting thread ID of nPth. * agent/call-pinentry.c (agent_query_dump_state): Use %lx to format thread ID. -- Fixes-commit: ba6f8b3d9ec83b35c4f3839853567491fee2f99c Signed-off-by: NIIBE Yutaka --- agent/call-pinentry.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 656d5f623..2369dffc2 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -128,8 +128,9 @@ initialize_module_call_pinentry (void) void agent_query_dump_state (void) { - log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n", - entry_ctx, (long)assuan_get_pid (entry_ctx), (void*)popup_tid); + log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%lx\n", + entry_ctx, (long)assuan_get_pid (entry_ctx), + (unsigned long)popup_tid); } /* Called to make sure that a popup window owned by the current From 5e94470d053ec93f79acb03635e67839a5a1e6a8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 4 Jul 2023 09:19:05 +0200 Subject: [PATCH 102/869] common,w32: Add missing GetLastError->errno mapping. * common/iobuf.c (file_filter, sock_filter): Add missing mapping. -- GnuPG-bug-id: 6528 --- common/iobuf.c | 7 ++++--- common/sysutils.c | 5 +++-- common/sysutils.h | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index 627d33900..161769a35 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -572,8 +572,8 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, { if (size && !WriteFile (f, p, nbytes, &n, NULL)) { - int ec = (int) GetLastError (); - rc = gpg_error_from_errno (ec); + int ec = gnupg_w32_set_errno (-1); + rc = gpg_error_from_syserror (); log_error ("%s: write error: %s (ec=%d)\n", a->fname, gpg_strerror (rc), ec); break; @@ -884,7 +884,8 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf, if (n == SOCKET_ERROR) { int ec = (int) WSAGetLastError (); - rc = gpg_error_from_errno (ec); + gnupg_w32_set_errno (ec); + rc = gpg_error_from_syserror (); log_error ("socket write error: ec=%d\n", ec); break; } diff --git a/common/sysutils.c b/common/sysutils.c index 231565177..f8e6d86fc 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -327,9 +327,10 @@ map_w32_to_errno (DWORD w32_err) #endif /*HAVE_W32_SYSTEM*/ -/* Set ERRNO from the Windows error. EC may be -1 to use the last error. */ +/* Set ERRNO from the Windows error. EC may be -1 to use the last + * error. Returns the Windows error code. */ #ifdef HAVE_W32_SYSTEM -void +int gnupg_w32_set_errno (int ec) { /* FIXME: Replace by gpgrt_w32_set_errno. */ diff --git a/common/sysutils.h b/common/sysutils.h index 7063da067..a78a81c64 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -110,7 +110,7 @@ int gnupg_inotify_has_name (int fd, const char *name); #ifdef HAVE_W32_SYSTEM -void gnupg_w32_set_errno (int ec); +int gnupg_w32_set_errno (int ec); void *w32_get_user_sid (void); #include "../common/w32help.h" From 7a2831bc0ef00559d2a2b938e0f2401f0e35d30a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 4 Jul 2023 09:26:10 +0200 Subject: [PATCH 103/869] gpgsm: Init a diagnostic var. * sm/minip12.c (p12_parse): Init where. -- --- sm/minip12.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sm/minip12.c b/sm/minip12.c index eafebfe67..265243f3e 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -2348,7 +2348,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, void *certcbarg, int *r_badpass, char **r_curve) { gpg_error_t err; - const char *where; + const char *where = ""; struct tlv_ctx_s *tlv; struct p12_parse_ctx_s ctx = { NULL }; const unsigned char *oid; From b83d86b988bbb05b25dba250a5f01b33b3dbb824 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 4 Jul 2023 14:32:08 +0200 Subject: [PATCH 104/869] scd:p15: Make signing work for Nexus cards. * scd/app-p15.c (CARD_PRODUCT_NEXUS): New. (read_p15_info): Detect Nexus cards. (get_dispserialno): Use product_id instead of comparing the manufacturer_id. (do_sign): Handle Nexus like BELPIC. --- scd/app-p15.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 92628b926..4338a623e 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -87,7 +87,8 @@ typedef enum CARD_PRODUCT_UNKNOWN, CARD_PRODUCT_RSCS, /* Rohde&Schwarz Cybersecurity */ CARD_PRODUCT_DTRUST, /* D-Trust GmbH (bundesdruckerei.de) */ - CARD_PRODUCT_GENUA /* GeNUA mbH */ + CARD_PRODUCT_GENUA, /* GeNUA mbH */ + CARD_PRODUCT_NEXUS /* Technology Nexus */ } card_product_t; @@ -550,6 +551,7 @@ cardproduct2str (card_product_t cardproduct) case CARD_PRODUCT_RSCS: return "R&S"; case CARD_PRODUCT_DTRUST: return "D-Trust"; case CARD_PRODUCT_GENUA: return "GeNUA"; + case CARD_PRODUCT_NEXUS: return "Nexus"; } return ""; } @@ -3605,14 +3607,20 @@ read_p15_info (app_t app) release_lists (app); - if (IS_CARDOS_5 (app) - && app->app_local->manufacturer_id - && !ascii_strcasecmp (app->app_local->manufacturer_id, "GeNUA mbH")) + /* Set a product type from the manufacturer_id. */ + if (IS_CARDOS_5 (app) && app->app_local->manufacturer_id) { - if (!app->app_local->card_product) + const char *manu = app->app_local->manufacturer_id; + + if (app->app_local->card_product) + ; /* Already set. */ + else if (!ascii_strcasecmp (manu, "GeNUA mbH")) app->app_local->card_product = CARD_PRODUCT_GENUA; + else if (!ascii_strcasecmp (manu, "Technology Nexus")) + app->app_local->card_product = CARD_PRODUCT_NEXUS; } + /* Read the ODF so that we know the location of all directory files. */ /* Fixme: We might need to get a non-standard ODF FID from TokenInfo. */ @@ -5079,9 +5087,7 @@ get_dispserialno (app_t app, prkdf_object_t prkdf) if (serial && (n=strlen (serial)) > 8) memmove (serial, serial + n - 8, 9); } - else if (IS_CARDOS_5 (app) && app->app_local->manufacturer_id - && !ascii_strcasecmp (app->app_local->manufacturer_id, - "Technology Nexus") + else if (app->app_local->card_product == CARD_PRODUCT_NEXUS && APP_CARD(app)->serialno && APP_CARD(app)->serialnolen == 4+9 && !memcmp (APP_CARD(app)->serialno, "\xff\x00\x00\xff", 4) && !any_control_or_space_mem (APP_CARD(app)->serialno + 4, 9)) @@ -5615,11 +5621,12 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, err = gpg_error_from_syserror (); goto leave; } - if (app->app_local->card_type == CARD_TYPE_BELPIC) + if (app->app_local->card_type == CARD_TYPE_BELPIC + || app->app_local->card_product == CARD_PRODUCT_NEXUS) { - /* This card wants only the plain hash w/o any prefix. */ - /* FIXME: We may want to remove this code because it is unlikely - * that such cards are still in use. */ + /* The default for these cards is to use a plain hash. We + * assume that due to the used certificate the correct hash + * algo is used. */ memcpy (frame, indata, indatalen); framelen = indatalen; } From 7f8ea1c9be120b0a78eb6c04551277747f711d56 Mon Sep 17 00:00:00 2001 From: Emir SARI Date: Tue, 4 Jul 2023 15:52:05 +0200 Subject: [PATCH 105/869] po: Update Turkish translation -- --- po/tr.po | 73 ++++++++++++++++---------------------------------------- 1 file changed, 20 insertions(+), 53 deletions(-) diff --git a/po/tr.po b/po/tr.po index b7730c7ae..24313f22a 100644 --- a/po/tr.po +++ b/po/tr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg 2.4.0\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-02-05 18:00+0300\n" +"PO-Revision-Date: 2023-05-30 23:45+0300\n" "Last-Translator: Emir SARI \n" "Language-Team: Turkish\n" "Language: tr\n" @@ -123,10 +123,8 @@ msgstr "Anahtar Parolası:" msgid "does not match - try again" msgstr "eşleşmiyor - yeniden deneyin" -#, fuzzy -#| msgid "Passphrase Entry" msgid "Passphrases match." -msgstr "Anahtar Parolası Girişi" +msgstr "Anahtar parolaları eşleşiyor." #. TRANSLATORS: The string is appended to an error message in #. the pinentry. The %s is the actual error message, the @@ -733,6 +731,10 @@ msgstr "Doğru" msgid "Wrong" msgstr "Yanlış" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "'%s > '%s' olarak yeniden adlandırırken hata: %s\n" + #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -1409,7 +1411,7 @@ msgstr "zorlandı" #, c-format msgid "Please try command \"%s\" if the listing does not look correct\n" -msgstr "" +msgstr "Listeleme doğru görünmüyorsa lütfen \"%s\" komutunu deneyin\n" msgid "Error: Only plain ASCII is currently allowed.\n" msgstr "Hata: Şimdilik yalnızca US-ASCII mümkün.\n" @@ -1674,7 +1676,7 @@ msgid "change the User Interaction Flag" msgstr "Kullanıcı etkileşim bayrağını değiştir" msgid "switch to the OpenPGP app" -msgstr "" +msgstr "OpenPGP uygulamasına geç" msgid "gpg/card> " msgstr "gpg/card> " @@ -2304,10 +2306,8 @@ msgstr "" "anahtar listelerinde yürürlükten kaldırılmış ve zaman aşımına uğramış " "yardımcı anahtarlar göster" -#, fuzzy -#| msgid "show expiration dates during signature listings" msgid "show signatures with invalid algorithms during signature listings" -msgstr "imza listelemesi sırasında zaman aşımı tarihleri göster" +msgstr "imza listelemesi sırasında geçersiz algoritmalı imzaları göster" msgid "show the keyring name in key listings" msgstr "anahtar zinciri adını anahtar listelerinde göster" @@ -2927,6 +2927,7 @@ msgstr "%s anahtarı: Aracıya gönderirken hata: %s\n" #, c-format msgid "key %s: card reference is overridden by key material\n" msgstr "" +"%s anahtarı: Kart başvurusu, anahtar malzemesi tarafından geçersiz kılındı\n" #. TRANSLATORS: For a smartcard, each private key on host has a #. * reference (stub) to a smartcard and actual private key data @@ -3449,10 +3450,8 @@ msgstr "seçili yardımcı anahtarları sil" msgid "add a revocation key" msgstr "bir yürürlükten kaldırma anahtarı ekle" -#, fuzzy -#| msgid "Data decryption succeeded" msgid "add an additional decryption subkey" -msgstr "Veri şifresi çözülmesi başarılı" +msgstr "ek bir şifre çözümü alt anahtarı ekle" msgid "delete signatures from the selected user IDs" msgstr "seçili kullanıcı kimliklerinden imzaları sile" @@ -3519,11 +3518,10 @@ msgstr "Gizli anahtar mevcut.\n" msgid "Secret subkeys are available.\n" msgstr "Gizli yardımcı anahtarlar mevcut.\n" -#, fuzzy -#| msgid "Note: Only the secret part of the shown subkey will be deleted.\n" msgid "" "Note: the local copy of the secret key will only be deleted with \"save\".\n" -msgstr "Not: Yalnızca gösterilen yardımcı anahtarın gizli kısmı silinecek.\n" +msgstr "" +"Not: Gizli anahtarın yerel kopyası yalnızca \"save\" ile silinir.\n" msgid "Need the secret key to do this.\n" msgstr "Bunu yapmak için gizli anahtar gerekli.\n" @@ -3639,10 +3637,9 @@ msgstr "Değişiklikler kaydedilsin mi? (e/H) " msgid "Quit without saving? (y/N) " msgstr "Kaydetmeden çıkılsın mı? (e/H) " -#, fuzzy, c-format -#| msgid "deleting secret %s failed: %s\n" +#, c-format msgid "deleting copy of secret key failed: %s\n" -msgstr "gizli %s silinmesi başarısız: %s\n" +msgstr "gizli anahtarın kopyasının silinmesi başarısız: %s\n" #, c-format msgid "Key not changed so no update needed.\n" @@ -3783,11 +3780,6 @@ msgstr "UYARI: Şifreleme yardımcı anahtarının yakın zamanda süresi dolaca msgid "You may want to change its expiration date too.\n" msgstr "Son kullanma tarihini de değiştirmek isteyebilirsiniz.\n" -#, fuzzy, c-format -#| msgid "WARNING: Your encryption subkey expires soon.\n" -msgid "WARNING: No valid encryption subkey left over.\n" -msgstr "UYARI: Şifreleme yardımcı anahtarının yakın zamanda süresi dolacak.\n" - msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -3894,17 +3886,15 @@ msgstr "" "misiniz? (e/H) " msgid "Enter the fingerprint of the additional decryption subkey: " -msgstr "" +msgstr "Ek şifre çözümü alt anahtarının parmak izini gir: " -#, fuzzy, c-format -#| msgid "(unless you specify the key by fingerprint)\n" +#, c-format msgid "Did you specify the fingerprint of a subkey?\n" -msgstr "(anahtar parmak izi ile belirtilmedikçe)\n" +msgstr "Bir alt anahtarın parmak izini mi belirttiniz?\n" -#, fuzzy, c-format -#| msgid "Subkey %s is already revoked.\n" +#, c-format msgid "key \"%s\" is already on this keyblock\n" -msgstr "%s yardımcı anahtarı zaten yürürlükten kaldırılmış.\n" +msgstr "\"%s\" anahtarı halihazırda bu anahtar blokunda\n" msgid "" "Are you sure you want to change the expiration time for multiple subkeys? (y/" @@ -7770,10 +7760,6 @@ msgstr "lütfen nedenini denetleyin ve o dosyayı el ile silin\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "geçici önbellek dizin dosyası '%s' oluşturulamadı: %s\n" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "'%s > '%s' olarak yeniden adlandırırken hata: %s\n" - #, c-format msgid "can't hash '%s': %s\n" msgstr "'%s' sağlaması yapılamıyor: %s\n" @@ -8925,22 +8911,3 @@ msgstr "Yubikey yönetim konsolu" msgid "manage the command history" msgstr "komut geçmişini yönet" - -#~ msgid "continuing verification anyway due to option %s\n" -#~ msgstr "%s seçeneğinden dolayı doğrulama yine de sürdürülüyor\n" - -#~ msgid "selected AEAD algorithm is invalid\n" -#~ msgstr "seçili AEAD algoritması geçersiz\n" - -#~ msgid "invalid personal AEAD preferences\n" -#~ msgstr "geçersiz kişisel AEAD tercihler\n" - -#~ msgid "AEAD algorithm '%s' may not be used in %s mode\n" -#~ msgstr "'%s' AEAD algoritması, %s kipinde kullanılamayabilir\n" - -#~ msgid "run in supervised mode" -#~ msgstr "yönetilen kipte çalıştır" - -#~ msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" -#~ msgstr "" -#~ "simetrik şifreleme %s (%d) zorlamak alıcı tercihlerine karşı geliyor\n" From 7c04a6a28409f8fbf49a27703ad9955d8a04ce6f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 4 Jul 2023 16:06:48 +0200 Subject: [PATCH 106/869] po: msgmerge -- --- po/cs.po | 90 +++++--------------------------------------------------- po/de.po | 3 +- po/tr.po | 16 ++++++---- 3 files changed, 19 insertions(+), 90 deletions(-) diff --git a/po/cs.po b/po/cs.po index a05a18e84..7506778cd 100644 --- a/po/cs.po +++ b/po/cs.po @@ -157,10 +157,10 @@ msgstr "neshodují se – zkuste to znovu" msgid "Passphrases match." msgstr "Heslo se shoduje." +# TODO: Pluralize #. TRANSLATORS: The string is appended to an error message in #. the pinentry. The %s is the actual error message, the #. two %d give the current and maximum number of tries. -# TODO: Pluralize #, c-format msgid "SETERROR %s (try %d of %d)" msgstr "SETERROR %s (pokus %d z %d)" @@ -786,8 +786,8 @@ msgstr "Vyžádáno použití klíče%%0A %s%%0A %s%%0APřejete si to povolit? #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A " -"%%C%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" +"%%0A?" msgstr "" "Opravdu chcete smazat klíč určený pomocí keygripu%%0A %s%%0A %%C%%0A?" @@ -8980,30 +8980,24 @@ msgstr "Příkazy pro správu Yubikey" msgid "manage the command history" msgstr "spravuje historii příkazů" -#, c-format #~ msgid "selected AEAD algorithm is invalid\n" #~ msgstr "vybraný algoritmus AEAD je neplatný\n" -#, c-format #~ msgid "invalid personal AEAD preferences\n" #~ msgstr "neplatné uživatelské předvolby pro AEAD\n" -#, c-format #~ msgid "AEAD algorithm '%s' may not be used in %s mode\n" #~ msgstr "AEAD algoritmus „%s“ se nesmí používat v režimu %s\n" -#, c-format #~ msgid "continuing verification anyway due to option %s\n" #~ msgstr "přesto se pokračuje v ověřování kvůli volbě %s\n" -#, c-format #~ msgid "error writing to temporary file: %s\n" #~ msgstr "chyba při zápisu do dočasného souboru: %s\n" #~ msgid "run in supervised mode" #~ msgstr "poběží v režimu dohledu" -#, c-format #~ msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" #~ msgstr "vyžádaná symetrická šifra %s (%d) nevyhovuje předvolbám příjemce\n" @@ -9019,15 +9013,12 @@ msgstr "spravuje historii příkazů" #~ msgid "Configuration of LDAP servers to use" #~ msgstr "Nastavení používaných LDAP serverů" -#, c-format #~ msgid "selfsigned certificate has a BAD signature" #~ msgstr "sám sebou podepsaný certifikát má CHYBNÝ podpis" -#, c-format #~ msgid "detected card with S/N: %s\n" #~ msgstr "nalezena karta se sériovým číslem: %s\n" -#, c-format #~ msgid "no authentication key for ssh on card: %s\n" #~ msgstr "na kartě není autentizační klíč pro SSH: %s\n" @@ -9037,19 +9028,15 @@ msgstr "spravuje historii příkazů" #~ msgid "use a log file for the server" #~ msgstr "použít pro server soubor s protokolem" -#, c-format #~ msgid "Note: no default option file '%s'\n" #~ msgstr "Poznámka: neexistuje implicitní soubor s možnostmi „%s“\n" -#, c-format #~ msgid "option file '%s': %s\n" #~ msgstr "soubor s možnostmi „%s“: %s\n" -#, c-format #~ msgid "connection to %s established\n" #~ msgstr "spojení k programu %s ustanoveno\n" -#, c-format #~ msgid "no running gpg-agent - starting '%s'\n" #~ msgstr "gpg-agent neběží – spouští se „%s“\n" @@ -9080,43 +9067,33 @@ msgstr "spravuje historii příkazů" #~ msgid "invalid option" #~ msgstr "neplatný parametr" -#, c-format #~ msgid "missing argument for option \"%.50s\"\n" #~ msgstr "postrádám argument u volby „%.50s“\n" -#, c-format #~ msgid "option \"%.50s\" does not expect an argument\n" #~ msgstr "volba „%.50s“ nečeká argument\n" -#, c-format #~ msgid "invalid command \"%.50s\"\n" #~ msgstr "neplatný příkaz „%.50s“\n" -#, c-format #~ msgid "option \"%.50s\" is ambiguous\n" #~ msgstr "volba „%.50s“ není jednoznačná\n" -#, c-format #~ msgid "command \"%.50s\" is ambiguous\n" #~ msgstr "příkaz „%.50s“ není jednoznačný\n" -#, c-format #~ msgid "invalid option \"%.50s\"\n" #~ msgstr "neplatný parametr „%.50s“\n" -#, c-format #~ msgid "unable to execute program '%s': %s\n" #~ msgstr "nelze spustit program „%s“: %s\n" -#, c-format #~ msgid "unable to execute external program\n" #~ msgstr "nelze spustit externí program\n" -#, c-format #~ msgid "unable to read external program response: %s\n" #~ msgstr "nelze přečíst odpověď externího programu: %s\n" -#, c-format #~ msgid "Note: old default options file '%s' ignored\n" #~ msgstr "Poznámka: starý implicitní soubor s možnostmi „%s“ ignorován\n" @@ -9126,42 +9103,34 @@ msgstr "spravuje historii příkazů" #~ msgid "elevate the trust of signatures with valid PKA data" #~ msgstr "vyzvednout důvěru podpisů s platnými daty PKA" -#, c-format #~ msgid " (%d) ECC and ECC\n" #~ msgstr " (%d) ECC a ECC\n" #~ msgid "honor the PKA record set on a key when retrieving keys" #~ msgstr "respektovat PKA záznamy klíče při získávání klíčů" -#, c-format #~ msgid "requesting key %s from %s server %s\n" #~ msgstr "požaduji klíč %s z %s serveru %s\n" -#, c-format #~ msgid "Note: Verified signer's address is '%s'\n" #~ msgstr "Poznámka: Podepisovatelova ověřená adresa je „%s“\n" -#, c-format #~ msgid "Note: Signer's address '%s' does not match DNS entry\n" #~ msgstr "" #~ "Poznámka: Podepisovatelova adresa „%s“ se neshoduje s DNS záznamem\n" -#, c-format #~ msgid "trustlevel adjusted to FULL due to valid PKA info\n" #~ msgstr "úroveň důvěry opravena na PLNOU, kvůli platné PKA informaci\n" -#, c-format #~ msgid "trustlevel adjusted to NEVER due to bad PKA info\n" #~ msgstr "úroveň důvěry opravena na ŽÁDNOU, kvůli špatné PKA informaci\n" #~ msgid "|FILE|write a server mode log to FILE" #~ msgstr "|SOUBOR|zapisovat protokol režimu server do SOUBORU" -#, c-format #~ msgid "%s:%u: no hostname given\n" #~ msgstr "%s:%u: nebyl zadán název stroje\n" -#, c-format #~ msgid "could not parse keyserver\n" #~ msgstr "nelze rozebrat serveru klíčů\n" @@ -9210,87 +9179,66 @@ msgstr "spravuje historii příkazů" #~ "Vnitřní LDAP pomůcka pro pro Dirmngr.\n" #~ "Rozhraní a volby se mohou bez upozornění změnit.\n" -#, c-format #~ msgid "invalid port number %d\n" #~ msgstr "neplatné číslo portu %d\n" -#, c-format #~ msgid "scanning result for attribute '%s'\n" #~ msgstr "ve výsledku se hledá atribut „%s“\n" -#, c-format #~ msgid "error writing to stdout: %s\n" #~ msgstr "chyba při zápisu na standardní výstup: %s\n" -#, c-format #~ msgid " available attribute '%s'\n" #~ msgstr " dostupný atribut „%s“\n" -#, c-format #~ msgid "attribute '%s' not found\n" #~ msgstr "atribut „%s“ nenalezen\n" -#, c-format #~ msgid "found attribute '%s'\n" #~ msgstr "nalezen atribut „%s“\n" -#, c-format #~ msgid "processing url '%s'\n" #~ msgstr "zpracovává se URL „%s“\n" -#, c-format #~ msgid " user '%s'\n" #~ msgstr " uživatel „%s“\n" -#, c-format #~ msgid " pass '%s'\n" #~ msgstr " heslo „%s“\n" -#, c-format #~ msgid " host '%s'\n" #~ msgstr " stroj „%s“\n" -#, c-format #~ msgid " port %d\n" #~ msgstr " port %d\n" -#, c-format #~ msgid " DN '%s'\n" #~ msgstr " DN „%s“\n" -#, c-format #~ msgid " filter '%s'\n" #~ msgstr " filtr „%s“\n" -#, c-format #~ msgid " attr '%s'\n" #~ msgstr " atribut „%s“\n" -#, c-format #~ msgid "no host name in '%s'\n" #~ msgstr "v „%s“ chybí název stroje\n" -#, c-format #~ msgid "no attribute given for query '%s'\n" #~ msgstr "u dotazu „%s“ nezadán žádný atribut\n" -#, c-format #~ msgid "WARNING: using first attribute only\n" #~ msgstr "POZOR: použije se pouze první atribut\n" -#, c-format #~ msgid "LDAP init to '%s:%d' failed: %s\n" #~ msgstr "Inicializace LDAP u „%s:%d“ selhala: %s\n" -#, c-format #~ msgid "binding to '%s:%d' failed: %s\n" #~ msgstr "napojení k „%s:%d“ selhalo: %s\n" -#, c-format #~ msgid "searching '%s' failed: %s\n" #~ msgstr "hledávání „%s“ neuspělo: %s\n" -#, c-format #~ msgid "start_cert_fetch: invalid pattern '%s'\n" #~ msgstr "start_cert_fetch: chybný vzor „%s“\n" @@ -9347,95 +9295,72 @@ msgstr "spravuje historii příkazů" #~ "Syntaxe: symcryptrun --class TŘÍDA --program PROGRAM --keyfile SOUBOR " #~ "[VOLBY…] PŘÍKAZ [VSTUPNÍ_SOUBOR]\n" -#, c-format #~ msgid "%s on %s aborted with status %i\n" #~ msgstr "%s nad %s byl ukončen s kódem %i\n" -#, c-format #~ msgid "%s on %s failed with status %i\n" #~ msgstr "%s nad %s selhal s kódem %i\n" -#, c-format #~ msgid "can't create temporary directory '%s': %s\n" #~ msgstr "nelze vytvořit dočasný adresář „%s“: %s\n" -#, c-format #~ msgid "could not open %s for writing: %s\n" #~ msgstr "%s nelze otevřít pro zápis: %s\n" -#, c-format #~ msgid "error closing %s: %s\n" #~ msgstr "chyba při zavírání chyba %s: %s\n" -#, c-format #~ msgid "no --program option provided\n" #~ msgstr "nebyla zadána volba --program\n" -#, c-format #~ msgid "only --decrypt and --encrypt are supported\n" #~ msgstr "pouze --decrypt a --encrypt jsou podporovány\n" -#, c-format #~ msgid "no --keyfile option provided\n" #~ msgstr "nebyla zadána volba --keyfile\n" -#, c-format #~ msgid "cannot allocate args vector\n" #~ msgstr "nelze alokovat pole argumentů\n" -#, c-format #~ msgid "could not create pipe: %s\n" #~ msgstr "nelze vytvořit rouru: %s\n" -#, c-format #~ msgid "could not create pty: %s\n" #~ msgstr "nelze vytvořit PTY: %s\n" -#, c-format #~ msgid "could not fork: %s\n" #~ msgstr "nelze se rozdvojit (fork): %s\n" -#, c-format #~ msgid "execv failed: %s\n" #~ msgstr "execv selhalo: %s\n" -#, c-format #~ msgid "select failed: %s\n" #~ msgstr "služba select() selhala: %s\n" -#, c-format #~ msgid "read failed: %s\n" #~ msgstr "čtení selhalo: %s\n" -#, c-format #~ msgid "pty read failed: %s\n" #~ msgstr "čtení z PTY selhalo: %s\n" -#, c-format #~ msgid "waitpid failed: %s\n" #~ msgstr "služba waitpid() selhala: %s\n" -#, c-format #~ msgid "child aborted with status %i\n" #~ msgstr "potomek byl ukončen s kódem %i\n" -#, c-format #~ msgid "cannot allocate infile string: %s\n" #~ msgstr "nelze alokovat řetězec infile: %s\n" -#, c-format #~ msgid "cannot allocate outfile string: %s\n" #~ msgstr "nelze alokovat řetězec outfile: %s\n" -#, c-format #~ msgid "either %s or %s must be given\n" #~ msgstr "musí být zadáno buď %s, nebo %s\n" -#, c-format #~ msgid "no class provided\n" #~ msgstr "nezadána žádná třída\n" -#, c-format #~ msgid "class %s is not supported\n" #~ msgstr "třída %s není podporována\n" @@ -9451,7 +9376,6 @@ msgstr "spravuje historii příkazů" #~ msgid "Sex ((M)ale, (F)emale or space): " #~ msgstr "Zadejte pohlaví: M – mužské, F – ženské, nebo stiskněte mezerník: " -#, c-format #~ msgid " using certificate ID 0x%08lX\n" #~ msgstr " pomocí certifikátu s ID 0x%08lX\n" @@ -10644,8 +10568,8 @@ msgstr "spravuje historii příkazů" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and " -#~ "\"extensive\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" +#~ "\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -10692,8 +10616,8 @@ msgstr "spravuje historii příkazů" #~ "Answer \"yes\" if you really want to delete this user ID.\n" #~ "All certificates are then also lost!" #~ msgstr "" -#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte " -#~ "\"ano\".\n" +#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte \"ano" +#~ "\".\n" #~ "Všechny certifikáty budou také ztraceny!" #~ msgid "Answer \"yes\" if it is okay to delete the subkey" diff --git a/po/de.po b/po/de.po index bf4bda4a0..04ed2a697 100644 --- a/po/de.po +++ b/po/de.po @@ -3832,7 +3832,8 @@ msgstr "Bitte erwägen Sie, dessen Verfallsdatum auch zu ändern.\n" #, c-format msgid "WARNING: No valid encryption subkey left over.\n" -msgstr "WARNUNG: Es sind keine Unterschlüssel zum Verschlüsseln mehr vorhanden.\n" +msgstr "" +"WARNUNG: Es sind keine Unterschlüssel zum Verschlüsseln mehr vorhanden.\n" msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " diff --git a/po/tr.po b/po/tr.po index 24313f22a..27f15bc61 100644 --- a/po/tr.po +++ b/po/tr.po @@ -731,10 +731,6 @@ msgstr "Doğru" msgid "Wrong" msgstr "Yanlış" -#, c-format -msgid "error renaming '%s' to '%s': %s\n" -msgstr "'%s > '%s' olarak yeniden adlandırırken hata: %s\n" - #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" @@ -3520,8 +3516,7 @@ msgstr "Gizli yardımcı anahtarlar mevcut.\n" msgid "" "Note: the local copy of the secret key will only be deleted with \"save\".\n" -msgstr "" -"Not: Gizli anahtarın yerel kopyası yalnızca \"save\" ile silinir.\n" +msgstr "Not: Gizli anahtarın yerel kopyası yalnızca \"save\" ile silinir.\n" msgid "Need the secret key to do this.\n" msgstr "Bunu yapmak için gizli anahtar gerekli.\n" @@ -3780,6 +3775,11 @@ msgstr "UYARI: Şifreleme yardımcı anahtarının yakın zamanda süresi dolaca msgid "You may want to change its expiration date too.\n" msgstr "Son kullanma tarihini de değiştirmek isteyebilirsiniz.\n" +#, fuzzy, c-format +#| msgid "WARNING: Your encryption subkey expires soon.\n" +msgid "WARNING: No valid encryption subkey left over.\n" +msgstr "UYARI: Şifreleme yardımcı anahtarının yakın zamanda süresi dolacak.\n" + msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -7760,6 +7760,10 @@ msgstr "lütfen nedenini denetleyin ve o dosyayı el ile silin\n" msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "geçici önbellek dizin dosyası '%s' oluşturulamadı: %s\n" +#, c-format +msgid "error renaming '%s' to '%s': %s\n" +msgstr "'%s > '%s' olarak yeniden adlandırırken hata: %s\n" + #, c-format msgid "can't hash '%s': %s\n" msgstr "'%s' sağlaması yapılamıyor: %s\n" From d073f26d81ff51afc94c908c8736eb31a31892d1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 4 Jul 2023 15:55:19 +0200 Subject: [PATCH 107/869] Release 2.4.3 --- NEWS | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index a30440b47..f7b447160 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -Noteworthy changes in version 2.4.3 (unreleased) +Noteworthy changes in version 2.4.3 (2023-07-04) ------------------------------------------------ * gpg: Set default expiration date to 3 years. [T2701] @@ -34,11 +34,14 @@ Noteworthy changes in version 2.4.3 (unreleased) commands. [rG2c7f7a5a27] * wkd: Make --add-revocs the default in gpg-wks-client. New option - --no-add-revocs. [rG10c937ee68] + --no-add-revocs. [rG10c937ee68] + + * scd: Make signing work for Nexus cards. [rGb83d86b988] * scd: Fix authentication with Administration Key for PIV. [rG25b59cf6ce] + See-also: gnupg-announce/2023q3/000480.html Release-info: https://dev.gnupg.org/T6509 From 2378ccf97c65d2f1122f7900a5232049d13e7bd8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 4 Jul 2023 16:44:01 +0200 Subject: [PATCH 108/869] Post release updates -- --- NEWS | 6 ++++++ configure.ac | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f7b447160..94cd00c9f 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +Noteworthy changes in version 2.4.4 (unreleased) +------------------------------------------------ + + Release-info: https://dev.gnupg.org/T6578 + + Noteworthy changes in version 2.4.3 (2023-07-04) ------------------------------------------------ diff --git a/configure.ac b/configure.ac index e68b779c5..953e2616f 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ min_automake_version="1.16.3" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [4]) -m4_define([mym4_micro], [3]) +m4_define([mym4_micro], [4]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release From 2c5a93e66e3e0f15b17e5dc92b503b708ce9b58f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 5 Jul 2023 09:24:40 +0900 Subject: [PATCH 109/869] gpg:card: Remove the code for GnuPG version 1. * g10/card-util.c [GNUPG_MAJOR_VERSION == 1] (get_data_from_file): Remove the old code. (put_data_to_file): Likewise. -- Signed-off-by: NIIBE Yutaka --- g10/card-util.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/g10/card-util.c b/g10/card-util.c index d680c4d0a..631f48d9d 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -28,9 +28,7 @@ # include #endif /*HAVE_LIBREADLINE*/ -#if GNUPG_MAJOR_VERSION != 1 # include "gpg.h" -#endif /*GNUPG_MAJOR_VERSION != 1*/ #include "../common/util.h" #include "../common/i18n.h" #include "../common/ttyio.h" @@ -39,11 +37,7 @@ #include "main.h" #include "keyserver-internal.h" -#if GNUPG_MAJOR_VERSION == 1 -# include "cardglue.h" -#else /*GNUPG_MAJOR_VERSION!=1*/ -# include "call-agent.h" -#endif /*GNUPG_MAJOR_VERSION!=1*/ +#include "call-agent.h" #define CONTROL_D ('D' - 'A' + 1) @@ -942,14 +936,6 @@ get_data_from_file (const char *fname, char **r_buffer) *r_buffer = NULL; fp = es_fopen (fname, "rb"); -#if GNUPG_MAJOR_VERSION == 1 - if (fp && is_secured_file (fileno (fp))) - { - fclose (fp); - fp = NULL; - errno = EPERM; - } -#endif if (!fp) { tty_printf (_("can't open '%s': %s\n"), fname, strerror (errno)); @@ -985,14 +971,6 @@ put_data_to_file (const char *fname, const void *buffer, size_t length) estream_t fp; fp = es_fopen (fname, "wb"); -#if GNUPG_MAJOR_VERSION == 1 - if (fp && is_secured_file (fileno (fp))) - { - fclose (fp); - fp = NULL; - errno = EPERM; - } -#endif if (!fp) { tty_printf (_("can't create '%s': %s\n"), fname, strerror (errno)); From dc13361524c1477b2106c7385f2059f9ea111b84 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 5 Jul 2023 09:29:54 +0900 Subject: [PATCH 110/869] dirmngr: Enable the call of ks_ldap_help_variables when USE_LDAP. * dirmngr/server.c [USE_LDAP] (cmd_ad_query): Conditionalize. -- Signed-off-by: NIIBE Yutaka --- dirmngr/server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dirmngr/server.c b/dirmngr/server.c index 51a149cb2..ee61f63d6 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -2776,7 +2776,9 @@ cmd_ad_query (assuan_context_t ctx, char *line) if (opt_help) { +#if USE_LDAP ks_ldap_help_variables (ctrl); +#endif err = 0; goto leave; } From 68d3a73ea78769280650a839c11c6f34ae39dadc Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 5 Jul 2023 09:36:00 +0900 Subject: [PATCH 111/869] gpg: Use gnupg_fd_t for open_outfile. * g10/main.h (open_outfile): Use gnupg_fd_t instead of int. * g10/openfile.c (open_outfile): Likewise. Use GNUPG_INVALID_FD. * g10/dearmor.c (dearmor_file, enarmor_file): Follow the change. * g10/encrypt.c (encrypt_simple): Likewise. * g10/export.c (do_export): Likewise. * g10/revoke.c (gen_desig_revoke, create_revocation): Likewise. * g10/sign.c (sign_file, clearsign_file, sign_symencrypt_file): Likewise. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- g10/dearmor.c | 4 ++-- g10/encrypt.c | 3 ++- g10/export.c | 2 +- g10/main.h | 2 +- g10/openfile.c | 6 +++--- g10/revoke.c | 4 ++-- g10/sign.c | 6 +++--- 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/g10/dearmor.c b/g10/dearmor.c index c0bd9ecf6..f6bb59ef6 100644 --- a/g10/dearmor.c +++ b/g10/dearmor.c @@ -63,7 +63,7 @@ dearmor_file( const char *fname ) push_armor_filter ( afx, inp ); - if( (rc = open_outfile (-1, fname, 0, 0, &out)) ) + if( (rc = open_outfile (GNUPG_INVALID_FD, fname, 0, 0, &out)) ) goto leave; iobuf_copy (out, inp); @@ -107,7 +107,7 @@ enarmor_file( const char *fname ) } - if( (rc = open_outfile (-1, fname, 1, 0, &out )) ) + if( (rc = open_outfile (GNUPG_INVALID_FD, fname, 1, 0, &out )) ) goto leave; afx->what = 4; diff --git a/g10/encrypt.c b/g10/encrypt.c index b335b9797..9e42beb82 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -507,7 +507,8 @@ encrypt_simple (const char *filename, int mode, int use_seskey) /**/ : "CFB"); } - if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, 0, &out ))) + if (rc || (rc = open_outfile (GNUPG_INVALID_FD, filename, opt.armor? 1:0, + 0, &out ))) { iobuf_cancel (inp); xfree (cfx.dek); diff --git a/g10/export.c b/g10/export.c index b3ad69718..b05492b32 100644 --- a/g10/export.c +++ b/g10/export.c @@ -426,7 +426,7 @@ do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options, memset( &zfx, 0, sizeof zfx); - rc = open_outfile (-1, NULL, 0, !!secret, &out ); + rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, !!secret, &out); if (rc) return rc; diff --git a/g10/main.h b/g10/main.h index b29e23e51..6d4a7cbf6 100644 --- a/g10/main.h +++ b/g10/main.h @@ -340,7 +340,7 @@ gpg_error_t generate_card_subkeypair (ctrl_t ctrl, kbnode_t pub_keyblock, int overwrite_filep( const char *fname ); char *make_outfile_name( const char *iname ); char *ask_outfile_name( const char *name, size_t namelen ); -int open_outfile (int out_fd, const char *iname, int mode, +int open_outfile (gnupg_fd_t out_fd, const char *iname, int mode, int restrictedperm, iobuf_t *a); char *get_matching_datafile (const char *sigfilename); iobuf_t open_sigfile (const char *sigfilename, progress_filter_context_t *pfx); diff --git a/g10/openfile.c b/g10/openfile.c index 5ca168a13..810811c64 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -179,13 +179,13 @@ ask_outfile_name( const char *name, size_t namelen ) * be closed if the returned IOBUF is closed. This is used for gpg's * --server mode. */ int -open_outfile (int out_fd, const char *iname, int mode, int restrictedperm, - iobuf_t *a) +open_outfile (gnupg_fd_t out_fd, const char *iname, int mode, + int restrictedperm, iobuf_t *a) { int rc = 0; *a = NULL; - if (out_fd != -1) + if (out_fd != GNUPG_INVALID_FD) { char xname[64]; diff --git a/g10/revoke.c b/g10/revoke.c index d6cbf93cb..ef5bb4d78 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -333,7 +333,7 @@ gen_desig_revoke (ctrl_t ctrl, const char *uname, strlist_t locusr) if( !opt.armor ) tty_printf(_("ASCII armored output forced.\n")); - if( (rc = open_outfile (-1, NULL, 0, 1, &out )) ) + if( (rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, 1, &out )) ) goto leave; afx->what = 1; @@ -464,7 +464,7 @@ create_revocation (ctrl_t ctrl, afx = new_armor_context (); - if ((rc = open_outfile (-1, filename, suffix, 1, &out))) + if ((rc = open_outfile (GNUPG_INVALID_FD, filename, suffix, 1, &out))) goto leave; if (leadintext ) diff --git a/g10/sign.c b/g10/sign.c index d6ab396af..5588557c8 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1113,7 +1113,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, else if (opt.verbose) log_info (_("writing to '%s'\n"), outfile); } - else if ((rc = open_outfile (-1, fname, + else if ((rc = open_outfile (GNUPG_INVALID_FD, fname, opt.armor? 1 : detached? 2 : 0, 0, &out))) { goto leave; @@ -1459,7 +1459,7 @@ clearsign_file (ctrl_t ctrl, log_info (_("writing to '%s'\n"), outfile); } - else if ((rc = open_outfile (-1, fname, 1, 0, &out))) + else if ((rc = open_outfile (GNUPG_INVALID_FD, fname, 1, 0, &out))) { goto leave; } @@ -1637,7 +1637,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) /**/ : "CFB"); /* Now create the outfile. */ - rc = open_outfile (-1, fname, opt.armor? 1:0, 0, &out); + rc = open_outfile (GNUPG_INVALID_FD, fname, opt.armor? 1:0, 0, &out); if (rc) goto leave; From 2c2516f03a28156d58b8da4c05f716095eab8957 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 5 Jul 2023 09:57:10 +0900 Subject: [PATCH 112/869] gpg: Use gnupg_fd_t for encrypt_crypt and gpg_verify. * common/iobuf.h (iobuf_fdopen_nc): Use gnupg_t. * common/iobuf.c (iobuf_fdopen_nc): Use gnupg_t. * g10/main.h (encrypt_crypt, gpg_verify): Use gnupg_fd_t. * g10/encrypt.c (encrypt_crypt): Use gnupg_fd_t. (encrypt_crypt_files): Follow the change. * g10/gpg.c (main): Follow the change. * g10/verify.c (gpg_verify): Use gnupg_fd_t. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- common/iobuf.c | 3 +-- common/iobuf.h | 2 +- g10/encrypt.c | 18 ++++++++++-------- g10/gpg.c | 6 ++++-- g10/main.h | 7 ++++--- g10/verify.c | 3 ++- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index fb87ff65d..477a66874 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -1531,9 +1531,8 @@ iobuf_fdopen (int fd, const char *mode) } iobuf_t -iobuf_fdopen_nc (int fd, const char *mode) +iobuf_fdopen_nc (gnupg_fd_t fp, const char *mode) { - gnupg_fd_t fp = INT2FD (fd); return do_iobuf_fdopen (fp, mode, 1); } diff --git a/common/iobuf.h b/common/iobuf.h index 04e6b4421..c523b8c96 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -337,7 +337,7 @@ iobuf_t iobuf_fdopen (int fd, const char *mode); /* Like iobuf_fdopen, but doesn't close the file descriptor when the filter is destroyed. */ -iobuf_t iobuf_fdopen_nc (int fd, const char *mode); +iobuf_t iobuf_fdopen_nc (gnupg_fd_t fd, const char *mode); /* Create a filter using an existing estream. If MODE contains the letter 'w', creates an output filter. Otherwise, creates an input diff --git a/g10/encrypt.c b/g10/encrypt.c index 9e42beb82..42ee0b773 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -764,9 +764,9 @@ write_symkey_enc (STRING2KEY *symkey_s2k, aead_algo_t aead_algo, * not yet finished server.c. */ int -encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, +encrypt_crypt (ctrl_t ctrl, gnupg_fd_t filefd, const char *filename, strlist_t remusr, int use_symkey, pk_list_t provided_keys, - int outputfd) + gnupg_fd_t outputfd) { iobuf_t inp = NULL; iobuf_t out = NULL; @@ -784,7 +784,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, PK_LIST pk_list; int do_compress; - if (filefd != -1 && filename) + if (filefd != GNUPG_INVALID_FD && filename) return gpg_error (GPG_ERR_INV_ARG); /* Both given. */ do_compress = !!opt.compress_algo; @@ -815,7 +815,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, /* Prepare iobufs. */ #ifdef HAVE_W32_SYSTEM - if (filefd == -1) + if (filefd == GNUPG_INVALID_FD) inp = iobuf_open (filename); else { @@ -823,7 +823,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, gpg_err_set_errno (ENOSYS); } #else - if (filefd == -1) + if (filefd == GNUPG_INVALID_FD) inp = iobuf_open (filename); else inp = iobuf_fdopen_nc (filefd, "rb"); @@ -841,7 +841,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, char xname[64]; rc = gpg_error_from_syserror (); - if (filefd != -1) + if (filefd != GNUPG_INVALID_FD) snprintf (xname, sizeof xname, "[fd %d]", filefd); else if (!filename) strcpy (xname, "[stdin]"); @@ -1225,7 +1225,8 @@ encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr) } line[strlen(line)-1] = '\0'; print_file_status(STATUS_FILE_START, line, 2); - rc = encrypt_crypt (ctrl, -1, line, remusr, 0, NULL, -1); + rc = encrypt_crypt (ctrl, GNUPG_INVALID_FD, line, remusr, + 0, NULL, GNUPG_INVALID_FD); if (rc) log_error ("encryption of '%s' failed: %s\n", print_fname_stdin(line), gpg_strerror (rc) ); @@ -1237,7 +1238,8 @@ encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr) while (nfiles--) { print_file_status(STATUS_FILE_START, *files, 2); - if ( (rc = encrypt_crypt (ctrl, -1, *files, remusr, 0, NULL, -1)) ) + if ((rc = encrypt_crypt (ctrl, GNUPG_INVALID_FD, *files, remusr, + 0, NULL, GNUPG_INVALID_FD))) log_error("encryption of '%s' failed: %s\n", print_fname_stdin(*files), gpg_strerror (rc) ); write_status( STATUS_FILE_DONE ); diff --git a/g10/gpg.c b/g10/gpg.c index 2ae3750a9..d836ff072 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -4408,7 +4408,8 @@ main (int argc, char **argv) { if( argc > 1 ) wrong_args("--encrypt [filename]"); - if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 0, NULL, -1)) ) + if ((rc = encrypt_crypt (ctrl, GNUPG_INVALID_FD, fname, remusr, + 0, NULL, GNUPG_INVALID_FD))) { write_status_failure ("encrypt", rc); log_error("%s: encryption failed: %s\n", @@ -4433,7 +4434,8 @@ main (int argc, char **argv) gnupg_compliance_option_string (opt.compliance)); else { - if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 1, NULL, -1)) ) + if ((rc = encrypt_crypt (ctrl, GNUPG_INVALID_FD, fname, remusr, + 1, NULL, GNUPG_INVALID_FD))) { write_status_failure ("encrypt", rc); log_error ("%s: encryption failed: %s\n", diff --git a/g10/main.h b/g10/main.h index 6d4a7cbf6..dd86990df 100644 --- a/g10/main.h +++ b/g10/main.h @@ -242,9 +242,9 @@ aead_algo_t use_aead (pk_list_t pk_list, int algo); int use_mdc (pk_list_t pk_list,int algo); int encrypt_symmetric (const char *filename ); int encrypt_store (const char *filename ); -int encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, +int encrypt_crypt (ctrl_t ctrl, gnupg_fd_t filefd, const char *filename, strlist_t remusr, int use_symkey, pk_list_t provided_keys, - int outputfd); + gnupg_fd_t outputfd); void encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr); int encrypt_filter (void *opaque, int control, @@ -492,7 +492,8 @@ void print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret); void print_file_status( int status, const char *name, int what ); 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); +int gpg_verify (ctrl_t ctrl, gnupg_fd_t sig_fd, gnupg_fd_t data_fd, + estream_t out_fp); void check_assert_signer_list (const char *mainpkhex, const char *pkhex); /*-- decrypt.c --*/ diff --git a/g10/verify.c b/g10/verify.c index e9792939d..17134a281 100644 --- a/g10/verify.c +++ b/g10/verify.c @@ -240,7 +240,8 @@ verify_files (ctrl_t ctrl, int nfiles, char **files ) FIXME: OUTFP is not yet implemented. */ int -gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp) +gpg_verify (ctrl_t ctrl, gnupg_fd_t sig_fd, gnupg_fd_t data_fd, + estream_t out_fp) { int rc; iobuf_t fp; From 3fb69641e84d420ee331023a53ac2961d17fa8b6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 5 Jul 2023 10:21:23 +0900 Subject: [PATCH 113/869] gpg: Use gnupg_fd_t for decryption and sign. * g10/decrypt.c (decrypt_message_fd): Use gnupg_fd_t. * g10/plaintext.c (hash_datafile_by_fd): Use gnupg_fd_t. * g10/main.h: Fix the declarations. * g10/mainproc.c (struct mainproc_context): Use gnupg_fd_t for DATA_FD. (proc_compressed_cb, proc_signature_packets): Follow the change. (proc_signature_packets_by_fd): Use gnupg_fd_t. * g10/packet.h: Fix the declaration. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- g10/decrypt.c | 15 ++++++++++++--- g10/main.h | 7 ++++--- g10/mainproc.c | 18 ++++++++++-------- g10/packet.h | 4 ++-- g10/plaintext.c | 4 ++-- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/g10/decrypt.c b/g10/decrypt.c index cb9e36a93..26081ed1b 100644 --- a/g10/decrypt.c +++ b/g10/decrypt.c @@ -100,7 +100,8 @@ decrypt_message (ctrl_t ctrl, const char *filename) /* Same as decrypt_message but takes a file descriptor for input and output. */ gpg_error_t -decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd) +decrypt_message_fd (ctrl_t ctrl, gnupg_fd_t input_fd, + gnupg_fd_t output_fd) { #ifdef HAVE_W32_SYSTEM /* No server mode yet. */ @@ -113,6 +114,7 @@ decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd) IOBUF fp; armor_filter_context_t *afx = NULL; progress_filter_context_t *pfx; + es_syshd_t syshd; if (opt.outfp) return gpg_error (GPG_ERR_BUG); @@ -138,13 +140,20 @@ decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd) return err; } - opt.outfp = es_fdopen_nc (output_fd, "wb"); +#ifdef HAVE_W32_SYSTEM + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = output_fd; +#else + syshd.type = ES_SYSHD_FD; + syshd.u.fd = output_fd; +#endif + opt.outfp = es_sysopen_nc (&syshd, "w"); if (!opt.outfp) { char xname[64]; err = gpg_error_from_syserror (); - snprintf (xname, sizeof xname, "[fd %d]", output_fd); + snprintf (xname, sizeof xname, "[fd %d]", (int)(intprt_t)output_fd); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err)); iobuf_close (fp); release_progress_context (pfx); diff --git a/g10/main.h b/g10/main.h index dd86990df..38e6a9c22 100644 --- a/g10/main.h +++ b/g10/main.h @@ -498,14 +498,15 @@ void check_assert_signer_list (const char *mainpkhex, const char *pkhex); /*-- decrypt.c --*/ int decrypt_message (ctrl_t ctrl, const char *filename ); -gpg_error_t decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd); +gpg_error_t decrypt_message_fd (ctrl_t ctrl, gnupg_fd_t input_fd, + gnupg_fd_t output_fd); void decrypt_messages (ctrl_t ctrl, int nfiles, char *files[]); /*-- plaintext.c --*/ int hash_datafiles( gcry_md_hd_t md, gcry_md_hd_t md2, strlist_t files, const char *sigfilename, int textmode); -int hash_datafile_by_fd ( gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd, - int textmode ); +int hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, + gnupg_fd_t data_fd, int textmode); PKT_plaintext *setup_plaintext_name(const char *filename,IOBUF iobuf); /*-- server.c --*/ diff --git a/g10/mainproc.c b/g10/mainproc.c index 7dea49728..74c7430ec 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -81,7 +81,7 @@ struct mainproc_context struct { /* A file descriptor of the signed data. Only used if not -1. */ - int data_fd; + gnupg_fd_t data_fd; /* A list of filenames with the data files or NULL. This is only used if DATA_FD is -1. */ strlist_t data_names; @@ -1093,7 +1093,7 @@ static int proc_compressed_cb (iobuf_t a, void *info) { if ( ((CTX)info)->signed_data.used - && ((CTX)info)->signed_data.data_fd != -1) + && ((CTX)info)->signed_data.data_fd != GNUPG_INVALID_FD) return proc_signature_packets_by_fd (((CTX)info)->ctrl, info, a, ((CTX)info)->signed_data.data_fd); else @@ -1515,7 +1515,7 @@ proc_signature_packets (ctrl_t ctrl, void *anchor, iobuf_t a, c->anchor = anchor; c->sigs_only = 1; - c->signed_data.data_fd = -1; + c->signed_data.data_fd = GNUPG_INVALID_FD; c->signed_data.data_names = signedfiles; c->signed_data.used = !!signedfiles; @@ -1545,8 +1545,8 @@ proc_signature_packets (ctrl_t ctrl, void *anchor, iobuf_t a, int -proc_signature_packets_by_fd (ctrl_t ctrl, - void *anchor, iobuf_t a, int signed_data_fd ) +proc_signature_packets_by_fd (ctrl_t ctrl, void *anchor, iobuf_t a, + gnupg_fd_t signed_data_fd) { int rc; CTX c; @@ -1561,7 +1561,7 @@ proc_signature_packets_by_fd (ctrl_t ctrl, c->signed_data.data_fd = signed_data_fd; c->signed_data.data_names = NULL; - c->signed_data.used = (signed_data_fd != -1); + c->signed_data.used = (signed_data_fd != GNUPG_INVALID_FD); rc = do_proc_packets (c, a); @@ -2627,7 +2627,8 @@ proc_tree (CTX c, kbnode_t node) /* Ask for file and hash it. */ if (c->sigs_only) { - if (c->signed_data.used && c->signed_data.data_fd != -1) + if (c->signed_data.used + && c->signed_data.data_fd != GNUPG_INVALID_FD) rc = hash_datafile_by_fd (c->mfx.md, NULL, c->signed_data.data_fd, use_textmode); @@ -2771,7 +2772,8 @@ proc_tree (CTX c, kbnode_t node) if (c->sigs_only) { - if (c->signed_data.used && c->signed_data.data_fd != -1) + if (c->signed_data.used + && c->signed_data.data_fd != GNUPG_INVALID_FD) rc = hash_datafile_by_fd (c->mfx.md, c->mfx.md2, c->signed_data.data_fd, (sig->sig_class == 0x01)); diff --git a/g10/packet.h b/g10/packet.h index 39dab96c9..defd1005e 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -634,8 +634,8 @@ void reset_literals_seen(void); int proc_packets (ctrl_t ctrl, void *ctx, iobuf_t a ); int proc_signature_packets (ctrl_t ctrl, void *ctx, iobuf_t a, strlist_t signedfiles, const char *sigfile ); -int proc_signature_packets_by_fd (ctrl_t ctrl, - void *anchor, IOBUF a, int signed_data_fd ); +int proc_signature_packets_by_fd (ctrl_t ctrl, void *anchor, IOBUF a, + gnupg_fd_t signed_data_fd); int proc_encryption_packets (ctrl_t ctrl, void *ctx, iobuf_t a); int list_packets( iobuf_t a ); diff --git a/g10/plaintext.c b/g10/plaintext.c index e12c2bf79..3d54b843c 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -728,8 +728,8 @@ hash_datafiles (gcry_md_hd_t md, gcry_md_hd_t md2, strlist_t files, /* Hash the data from file descriptor DATA_FD and append the hash to hash contexts MD and MD2. */ int -hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd, - int textmode) +hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, + gnupg_fd_t data_fd, int textmode) { progress_filter_context_t *pfx = new_progress_context (); iobuf_t fp; From 9ae3cfcabec9252c22d67b7a15c36f0a8cf22f0f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 5 Jul 2023 09:29:54 +0900 Subject: [PATCH 114/869] dirmngr: Enable the call of ks_ldap_help_variables when USE_LDAP. * dirmngr/server.c [USE_LDAP] (cmd_ad_query): Conditionalize. -- Cherry-pick master commit of: dc13361524c1477b2106c7385f2059f9ea111b84 Signed-off-by: NIIBE Yutaka --- dirmngr/server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dirmngr/server.c b/dirmngr/server.c index 51a149cb2..ee61f63d6 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -2776,7 +2776,9 @@ cmd_ad_query (assuan_context_t ctx, char *line) if (opt_help) { +#if USE_LDAP ks_ldap_help_variables (ctrl); +#endif err = 0; goto leave; } From 577baf4af3009071ff9f4909f1f40a74ab735d68 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 5 Jul 2023 13:11:16 +0900 Subject: [PATCH 115/869] gpg: Format the value of type gnupg_fd_t by casting to int. * g10/openfile.c (open_outfile): Cast to int. * g10/encrypt.c (encrypt_crypt): Ditto. * g10/decrypt.c (decrypt_message_fd): Ditto. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- g10/decrypt.c | 2 +- g10/encrypt.c | 2 +- g10/openfile.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/g10/decrypt.c b/g10/decrypt.c index 26081ed1b..e000ac478 100644 --- a/g10/decrypt.c +++ b/g10/decrypt.c @@ -153,7 +153,7 @@ decrypt_message_fd (ctrl_t ctrl, gnupg_fd_t input_fd, char xname[64]; err = gpg_error_from_syserror (); - snprintf (xname, sizeof xname, "[fd %d]", (int)(intprt_t)output_fd); + snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)output_fd); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err)); iobuf_close (fp); release_progress_context (pfx); diff --git a/g10/encrypt.c b/g10/encrypt.c index 42ee0b773..a5b020736 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -842,7 +842,7 @@ encrypt_crypt (ctrl_t ctrl, gnupg_fd_t filefd, const char *filename, rc = gpg_error_from_syserror (); if (filefd != GNUPG_INVALID_FD) - snprintf (xname, sizeof xname, "[fd %d]", filefd); + snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)filefd); else if (!filename) strcpy (xname, "[stdin]"); else diff --git a/g10/openfile.c b/g10/openfile.c index 810811c64..80c33f094 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -193,12 +193,12 @@ open_outfile (gnupg_fd_t out_fd, const char *iname, int mode, if (!*a) { rc = gpg_error_from_syserror (); - snprintf (xname, sizeof xname, "[fd %d]", out_fd); + snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)out_fd); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (rc)); } else if (opt.verbose) { - snprintf (xname, sizeof xname, "[fd %d]", out_fd); + snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)out_fd); log_info (_("writing to '%s'\n"), xname); } } From f2dcd158a5fff746507a5bd94ad9f4c7aece0901 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 5 Jul 2023 13:22:16 +0900 Subject: [PATCH 116/869] gpg: Fix gpg --server mode on Windows. * g10/server.c (cmd_encrypt): Don't translate_sys2libc_fd, since it requires HANDLE on Windows. (cmd_decrypt): Likewise. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- g10/server.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/g10/server.c b/g10/server.c index 60b447c41..8ddfbba8e 100644 --- a/g10/server.c +++ b/g10/server.c @@ -265,7 +265,7 @@ cmd_encrypt (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; - int inp_fd, out_fd; + gnupg_fd_t inp_fd, out_fd; (void)line; /* LINE is not used. */ @@ -276,14 +276,14 @@ cmd_encrypt (assuan_context_t ctx, char *line) goto leave; } - inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); - if (inp_fd == -1) + inp_fd = assuan_get_input_fd (ctx); + if (inp_fd == GNUPG_INVALID_FD) { err = set_error (GPG_ERR_ASS_NO_INPUT, NULL); goto leave; } - out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); - if (out_fd == -1) + out_fd = assuan_get_output_fd (ctx); + if (out_fd == GNUPG_INVALID_FD) { err = set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); goto leave; @@ -327,15 +327,15 @@ cmd_decrypt (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; - int inp_fd, out_fd; + gnupg_fd_t inp_fd, out_fd; (void)line; /* LINE is not used. */ - inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); - if (inp_fd == -1) + inp_fd = assuan_get_input_fd (ctx); + if (inp_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); - if (out_fd == -1) + out_fd = assuan_get_output_fd (ctx); + if (out_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); glo_ctrl.lasterr = 0; From 2abea42d9ce482d5d7eb4e6ecaa2ae798ba519a1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 6 Jul 2023 10:25:15 +0900 Subject: [PATCH 117/869] kbx: Use es_sysopen_nc instead of es_fdopen_nc. * kbx/kbxserver.c (prepare_outstream): Use es_sysopen_nc and avoid the use of translate_sys2libc_fd. -- On Windows, it's better directly use the system HANDLE. Signed-off-by: NIIBE Yutaka --- kbx/kbxserver.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/kbx/kbxserver.c b/kbx/kbxserver.c index ae9ae5c75..cc122fad5 100644 --- a/kbx/kbxserver.c +++ b/kbx/kbxserver.c @@ -131,21 +131,34 @@ get_assuan_ctx_from_ctrl (ctrl_t ctrl) static gpg_error_t prepare_outstream (ctrl_t ctrl) { - int fd; + gnupg_fd_t fd; + estream_t out_fp = NULL; log_assert (ctrl && ctrl->server_local); if (ctrl->server_local->outstream) return 0; /* Already enabled. */ - fd = translate_sys2libc_fd - (assuan_get_output_fd (get_assuan_ctx_from_ctrl (ctrl)), 1); - if (fd == -1) + fd = assuan_get_output_fd (get_assuan_ctx_from_ctrl (ctrl)); + if (fd == GNUPG_INVALID_FD) return 0; /* No Output command active. */ + else + { + es_syshd_t syshd; - ctrl->server_local->outstream = es_fdopen_nc (fd, "w"); - if (!ctrl->server_local->outstream) - return gpg_err_code_from_syserror (); +#ifdef HAVE_W32_SYSTEM + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = fd; +#else + syshd.type = ES_SYSHD_FD; + syshd.u.fd = fd; +#endif + out_fp = es_sysopen_nc (&syshd, "w"); + if (!out_fp) + return gpg_err_code_from_syserror (); + } + + ctrl->server_local->outstream = out_fp; return 0; } From 8cacfce898f2fcacc08292592b4ccb74602fc83d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 6 Jul 2023 16:02:14 +0900 Subject: [PATCH 118/869] kbx: Fix memory leak at spawning a thread for data pipe. * kbx/kbx-client-util.c (prepare_data_pipe): Release the attribute for thread creation. -- Signed-off-by: NIIBE Yutaka --- kbx/kbx-client-util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kbx/kbx-client-util.c b/kbx/kbx-client-util.c index ca791d4a3..9c7b57f2f 100644 --- a/kbx/kbx-client-util.c +++ b/kbx/kbx-client-util.c @@ -167,6 +167,7 @@ prepare_data_pipe (kbx_client_data_t kcd) return err; } + npth_attr_destroy (&tattr); return 0; } From 9f39e4da29feba854fbbe4ab6b9f3c68d34c2058 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 7 Jul 2023 10:21:39 +0200 Subject: [PATCH 119/869] gpg: Add algo constants for PQC. * common/openpgpdefs.h (PUBKEY_ALGO_KY768_25519): New. (PUBKEY_ALGO_KY1024_448): New. (PUBKEY_ALGO_DIL3_25519): New. (PUBKEY_ALGO_DIL5_448): New. (PUBKEY_ALGO_SPHINX_SHA2): New. * g10/keygen.c (parse_key_parameter_part): Force v5 keys for these algos. * g10/keyid.c (pubkey_string): Add mapping. * g10/misc.c (openpgp_pk_algo_usage): Add standard key usage. -- See draft-wussler-openpgp-pqc-01.txt for the code points. To limit the number of algorithms, only MUST and SHOULD algorithms are considered. --- common/openpgpdefs.h | 7 ++++++- g10/keygen.c | 31 +++++++++++++++++++++++++++++-- g10/keyid.c | 5 +++++ g10/misc.c | 13 +++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index 625747983..8553a889f 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -168,7 +168,12 @@ typedef enum PUBKEY_ALGO_ECDSA = 19, /* RFC-6637 */ PUBKEY_ALGO_ELGAMAL = 20, /* Elgamal encrypt+sign (legacy). */ /* 21 reserved by OpenPGP. */ - PUBKEY_ALGO_EDDSA = 22, /* EdDSA (not yet assigned). */ + PUBKEY_ALGO_EDDSA = 22, /* EdDSA. */ + PUBKEY_ALGO_KY768_25519 = 29, /* Kyber768 + X25519 */ + PUBKEY_ALGO_KY1024_448 = 30, /* Kyber1024 + X448 */ + PUBKEY_ALGO_DIL3_25519 = 35, /* Dilithium3 + Ed25519 */ + PUBKEY_ALGO_DIL5_448 = 36, /* Dilithium5 + Ed448 */ + PUBKEY_ALGO_SPHINX_SHA2 = 41, /* SPHINX+-simple-SHA2 */ PUBKEY_ALGO_PRIVATE10 = 110 } pubkey_algo_t; diff --git a/g10/keygen.c b/g10/keygen.c index d5099dbb9..3cafc476d 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3278,6 +3278,7 @@ parse_key_parameter_part (ctrl_t ctrl, char *keygrip = NULL; u32 keytime = 0; int is_448 = 0; + int is_pqc = 0; if (!string || !*string) return 0; /* Success. */ @@ -3312,6 +3313,32 @@ parse_key_parameter_part (ctrl_t ctrl, return gpg_error (GPG_ERR_INV_VALUE); } } + else if (!ascii_strcasecmp (string, "ky768")) + { + algo = PUBKEY_ALGO_KY768_25519; + is_pqc = 1; + } + else if (!ascii_strcasecmp (string, "ky1024")) + { + algo = PUBKEY_ALGO_KY1024_448; + is_pqc = 1; + } + else if (!ascii_strcasecmp (string, "dil3")) + { + algo = PUBKEY_ALGO_DIL3_25519; + is_pqc = 1; + } + else if (!ascii_strcasecmp (string, "dil5")) + { + algo = PUBKEY_ALGO_DIL5_448; + is_pqc = 1; + } + else if (!ascii_strcasecmp (string, "sphinx") + || !ascii_strcasecmp (string, "sphinx_sha2")) + { + algo = PUBKEY_ALGO_SPHINX_SHA2; + is_pqc = 1; + } else if ((curve = openpgp_is_curve_supported (string, &algo, &size))) { if (!algo) @@ -3560,8 +3587,8 @@ parse_key_parameter_part (ctrl_t ctrl, return gpg_error (GPG_ERR_WRONG_KEY_USAGE); } - /* Ed448 and X448 must only be used as v5 keys. */ - if (is_448) + /* Ed448, X448 and the PQC algos must only be used as v5 keys. */ + if (is_448 || is_pqc) { if (keyversion == 4) log_info (_("WARNING: v4 is specified, but overridden by v5.\n")); diff --git a/g10/keyid.c b/g10/keyid.c index 9191fec92..7cf9803e2 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -115,6 +115,11 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize) case PUBKEY_ALGO_ECDH: case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_EDDSA: prefix = ""; break; + case PUBKEY_ALGO_KY768_25519: prefix = "ky768"; break; + case PUBKEY_ALGO_KY1024_448: prefix = "ky1024"; break; + case PUBKEY_ALGO_DIL3_25519: prefix = "dil3"; break; + case PUBKEY_ALGO_DIL5_448: prefix = "dil5"; break; + case PUBKEY_ALGO_SPHINX_SHA2: prefix = "sphinx_sha2"; break; } if (prefix && *prefix) diff --git a/g10/misc.c b/g10/misc.c index 2f4b452dd..d1f0efc6e 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -799,6 +799,19 @@ openpgp_pk_algo_usage ( int algo ) case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_EDDSA: use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; + break; + + case PUBKEY_ALGO_KY768_25519: + case PUBKEY_ALGO_KY1024_448: + use = PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC; + break; + + case PUBKEY_ALGO_DIL3_25519: + case PUBKEY_ALGO_DIL5_448: + case PUBKEY_ALGO_SPHINX_SHA2: + use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG; + break; + default: break; } From 5bc949d23040a50dd4aa87fb3fee9c69c3e9abe6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 10 Jul 2023 11:18:08 +0900 Subject: [PATCH 120/869] common:w32: Fix gnupg_w32_set_errno. * common/sysutils.c (gnupg_w32_set_errno): Return EC. -- Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/sysutils.c b/common/sysutils.c index fc60af49c..73690a760 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -337,6 +337,7 @@ gnupg_w32_set_errno (int ec) if (ec == -1) ec = GetLastError (); _set_errno (map_w32_to_errno (ec)); + return ec; } #endif /*HAVE_W32_SYSTEM*/ From a3be97df4ddfce008dcc6e877e9fb98c71656ec6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 10 Jul 2023 11:18:08 +0900 Subject: [PATCH 121/869] common:w32: Fix gnupg_w32_set_errno. * common/sysutils.c (gnupg_w32_set_errno): Return EC. -- Cherry-pick master commit of: 4c6b759368bcf19a13df07c5c6080765ecac28ca Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/sysutils.c b/common/sysutils.c index f8e6d86fc..c88c02d36 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -337,6 +337,7 @@ gnupg_w32_set_errno (int ec) if (ec == -1) ec = GetLastError (); _set_errno (map_w32_to_errno (ec)); + return ec; } #endif /*HAVE_W32_SYSTEM*/ From 37343db08f4aaa36a0f58d2ecf50e7fbba4cacd7 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 7 Jul 2023 15:07:34 +0900 Subject: [PATCH 122/869] common,gpg,kbx: Factor out open_stream_nc. * common/sysutils.h (open_stream_nc): New. * common/sysutils.c (open_stream_nc): New. * g10/decrypt.c (decrypt_message_fd): Use open_stream_nc. * g10/server.c (cmd_verify): Likewise. * kbx/kbxserver.c (prepare_outstream): Likewise. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- common/sysutils.c | 19 +++++++++++++++++++ common/sysutils.h | 1 + g10/decrypt.c | 10 +--------- g10/server.c | 11 +---------- kbx/kbxserver.c | 11 +---------- 5 files changed, 23 insertions(+), 29 deletions(-) diff --git a/common/sysutils.c b/common/sysutils.c index 73690a760..745b762ba 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -1931,3 +1931,22 @@ gnupg_fd_valid (int fd) close (d); return 1; } + + +/* Open a stream from FD (a file descriptor on POSIX, a system + handle on Windows), non-closed. */ +estream_t +open_stream_nc (gnupg_fd_t fd, const char *mode) +{ + es_syshd_t syshd; + +#ifdef HAVE_W32_SYSTEM + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = fd; +#else + syshd.type = ES_SYSHD_FD; + syshd.u.fd = fd; +#endif + + return es_sysopen_nc (&syshd, mode); +} diff --git a/common/sysutils.h b/common/sysutils.h index 50e59175f..8cc303b61 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -109,6 +109,7 @@ gpg_error_t gnupg_inotify_watch_delete_self (int *r_fd, const char *fname); gpg_error_t gnupg_inotify_watch_socket (int *r_fd, const char *socket_name); int gnupg_inotify_has_name (int fd, const char *name); +estream_t open_stream_nc (gnupg_fd_t fd, const char *mode); #ifdef HAVE_W32_SYSTEM int gnupg_w32_set_errno (int ec); diff --git a/g10/decrypt.c b/g10/decrypt.c index e000ac478..64ba0b7f1 100644 --- a/g10/decrypt.c +++ b/g10/decrypt.c @@ -114,7 +114,6 @@ decrypt_message_fd (ctrl_t ctrl, gnupg_fd_t input_fd, IOBUF fp; armor_filter_context_t *afx = NULL; progress_filter_context_t *pfx; - es_syshd_t syshd; if (opt.outfp) return gpg_error (GPG_ERR_BUG); @@ -140,14 +139,7 @@ decrypt_message_fd (ctrl_t ctrl, gnupg_fd_t input_fd, return err; } -#ifdef HAVE_W32_SYSTEM - syshd.type = ES_SYSHD_HANDLE; - syshd.u.handle = output_fd; -#else - syshd.type = ES_SYSHD_FD; - syshd.u.fd = output_fd; -#endif - opt.outfp = es_sysopen_nc (&syshd, "w"); + opt.outfp = open_stream_nc (output_fd, "w"); if (!opt.outfp) { char xname[64]; diff --git a/g10/server.c b/g10/server.c index 8ddfbba8e..24e525e7f 100644 --- a/g10/server.c +++ b/g10/server.c @@ -388,16 +388,7 @@ cmd_verify (assuan_context_t ctx, char *line) if (out_fd != GNUPG_INVALID_FD) { - es_syshd_t syshd; - -#ifdef HAVE_W32_SYSTEM - syshd.type = ES_SYSHD_HANDLE; - syshd.u.handle = out_fd; -#else - syshd.type = ES_SYSHD_FD; - syshd.u.fd = out_fd; -#endif - out_fp = es_sysopen_nc (&syshd, "w"); + out_fp = open_stream_nc (fd, "w"); if (!out_fp) return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); } diff --git a/kbx/kbxserver.c b/kbx/kbxserver.c index cc122fad5..d50b9dfdf 100644 --- a/kbx/kbxserver.c +++ b/kbx/kbxserver.c @@ -144,16 +144,7 @@ prepare_outstream (ctrl_t ctrl) return 0; /* No Output command active. */ else { - es_syshd_t syshd; - -#ifdef HAVE_W32_SYSTEM - syshd.type = ES_SYSHD_HANDLE; - syshd.u.handle = fd; -#else - syshd.type = ES_SYSHD_FD; - syshd.u.fd = fd; -#endif - out_fp = es_sysopen_nc (&syshd, "w"); + out_fp = open_stream_nc (fd, "w"); if (!out_fp) return gpg_err_code_from_syserror (); } From 250733c0d86d392c6e37b62cc82df0c396362581 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 11 Jul 2023 10:46:36 +0900 Subject: [PATCH 123/869] common: Add gnupg_check_special_filename. * common/sysutils.h (gnupg_check_special_filename): New. * common/sysutils.c (gnupg_check_special_filename): New. * common/iobuf.c (translate_file_handle): Remove. (iobuf_is_pipe_filename): Use gnupg_check_special_filename. (do_open): Use gnupg_check_special_filename. * g10/plaintext.c (get_output_file): Use gnupg_check_special_filename and open_stream_nc. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- common/iobuf.c | 40 ++++------------------------------------ common/sysutils.c | 42 ++++++++++++++++++++++++++++++++++++++++++ common/sysutils.h | 1 + g10/plaintext.c | 10 +++++----- 4 files changed, 52 insertions(+), 41 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index 477a66874..2427e4f19 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -166,7 +166,6 @@ block_filter_ctx_t; /* Local prototypes. */ static int underflow (iobuf_t a, int clear_pending_eof); static int underflow_target (iobuf_t a, int clear_pending_eof, size_t target); -static gnupg_fd_t translate_file_handle (int fd, int for_write); static iobuf_t do_iobuf_fdopen (gnupg_fd_t fp, const char *mode, int keep_open); @@ -1412,7 +1411,7 @@ iobuf_is_pipe_filename (const char *fname) { if (!fname || (*fname=='-' && !fname[1]) ) return 1; - return check_special_filename (fname, 0, 1) != -1; + return gnupg_check_special_filename (fname) != GNUPG_INVALID_FD; } @@ -1425,7 +1424,7 @@ do_open (const char *fname, int special_filenames, file_filter_ctx_t *fcx; size_t len = 0; int print_only = 0; - int fd; + gnupg_fd_t fd; byte desc[MAX_IOBUF_DESC]; log_assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT); @@ -1449,9 +1448,8 @@ do_open (const char *fname, int special_filenames, else if (!fname) return NULL; else if (special_filenames - && (fd = check_special_filename (fname, 0, 1)) != -1) - return do_iobuf_fdopen (translate_file_handle (fd, use == IOBUF_INPUT - ? 0 : 1), opentype, 0); + && (fd = gnupg_check_special_filename (fname)) != GNUPG_INVALID_FD) + return do_iobuf_fdopen (fd, opentype, 0); else { if (use == IOBUF_INPUT) @@ -2948,36 +2946,6 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, return nbytes; } -static gnupg_fd_t -translate_file_handle (int fd, int for_write) -{ -#if defined(HAVE_W32_SYSTEM) - { - gnupg_fd_t x; - - (void)for_write; - - if (fd == 0) - x = GetStdHandle (STD_INPUT_HANDLE); - else if (fd == 1) - x = GetStdHandle (STD_OUTPUT_HANDLE); - else if (fd == 2) - x = GetStdHandle (STD_ERROR_HANDLE); - else - x = (gnupg_fd_t)(intptr_t)fd; - - if (x == INVALID_HANDLE_VALUE) - log_debug ("GetStdHandle(%d) failed: ec=%d\n", - fd, (int) GetLastError ()); - - return x; - } -#else - (void)for_write; - return fd; -#endif -} - void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial) diff --git a/common/sysutils.c b/common/sysutils.c index 745b762ba..80aa3a04a 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -682,6 +682,48 @@ check_special_filename (const char *fname, int for_write, int notranslate) } +/* Check whether FNAME has the form "-&nnnn", where N is a number + * representing a file. Returns GNUPG_INVALID_FD if it is not the + * case. Returns a file descriptor on POSIX, a system handle on + * Windows. */ +gnupg_fd_t +gnupg_check_special_filename (const char *fname) +{ + if (allow_special_filenames + && fname && *fname == '-' && fname[1] == '&') + { + int i; + + fname += 2; + for (i=0; digitp (fname+i); i++ ) + ; + if (!fname[i]) + { + es_syshd_t syshd; + + if (gnupg_parse_fdstr (fname, &syshd)) + return GNUPG_INVALID_FD; + +#ifdef HAVE_W32_SYSTEM + if (syshd.type == ES_SYSHD_FD) + { + if (syshd.u.fd == 0) + return GetStdHandle (STD_INPUT_HANDLE); + else if (syshd.u.fd == 1) + return GetStdHandle (STD_OUTPUT_HANDLE); + else if (syshd.u.fd == 2) + return GetStdHandle (STD_ERROR_HANDLE); + } + else + return syshd.u.handle; +#else + return syshd.u.fd; +#endif + } + } + return GNUPG_INVALID_FD; +} + /* Replacement for tmpfile(). This is required because the tmpfile function of Windows' runtime library is broken, insecure, ignores TMPDIR and so on. In addition we create a file with an inheritable diff --git a/common/sysutils.h b/common/sysutils.h index 8cc303b61..c6740a874 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -76,6 +76,7 @@ int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); int translate_sys2libc_fd_int (int fd, int for_write); gpg_error_t gnupg_parse_fdstr (const char *fdstr, es_syshd_t *r_syshd); int check_special_filename (const char *fname, int for_write, int notranslate); +gnupg_fd_t gnupg_check_special_filename (const char *fname); FILE *gnupg_tmpfile (void); void gnupg_reopen_std (const char *pgmname); void gnupg_inhibit_set_foregound_window (int yes); diff --git a/g10/plaintext.c b/g10/plaintext.c index 3d54b843c..9544ddf03 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -111,20 +111,20 @@ get_output_file (const byte *embedded_name, int embedded_namelen, { /* Special file name, no filename, or "-" given; write to the * file descriptor or to stdout. */ - int fd; + gnupg_fd_t fd; char xname[64]; - fd = check_special_filename (fname, 1, 0); - if (fd == -1) + fd = gnupg_check_special_filename (fname); + if (fd == GNUPG_INVALID_FD) { /* Not a special filename, thus we want stdout. */ fp = es_stdout; es_set_binary (fp); } - else if (!(fp = es_fdopen_nc (fd, "wb"))) + else if (!(fp = open_stream_nc (fd, "wb"))) { err = gpg_error_from_syserror (); - snprintf (xname, sizeof xname, "[fd %d]", fd); + snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)fd); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err)); goto leave; } From 16d135c39648e7f80ce0ff7e442c753a17e7fa4a Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 11 Jul 2023 11:21:05 +0900 Subject: [PATCH 124/869] common: Change iobuf_fdopen argument type to gnupg_fd_t. * common/iobuf.h (iobuf_fdopen): Use gnupg_fd_t. * common/iobuf.c (iobuf_fdopen): Use gnupg_fd_t. (iobuf_sockopen): Call do_iobuf_fdopen. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- common/iobuf.c | 5 ++--- common/iobuf.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index 2427e4f19..3c5dc800c 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -1522,9 +1522,8 @@ do_iobuf_fdopen (gnupg_fd_t fp, const char *mode, int keep_open) iobuf_t -iobuf_fdopen (int fd, const char *mode) +iobuf_fdopen (gnupg_fd_t fp, const char *mode) { - gnupg_fd_t fp = INT2FD (fd); return do_iobuf_fdopen (fp, mode, 0); } @@ -1583,7 +1582,7 @@ iobuf_sockopen (int fd, const char *mode) log_debug ("iobuf-%d.%d: sockopen '%s'\n", a->no, a->subno, scx->fname); iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL); #else - a = iobuf_fdopen (fd, mode); + a = do_iobuf_fdopen (fd, mode, 0); #endif return a; } diff --git a/common/iobuf.h b/common/iobuf.h index c523b8c96..4a723908d 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -333,7 +333,7 @@ iobuf_t iobuf_openrw (const char *fname); creates an input filter. Note: MODE must reflect the file descriptors actual mode! When the filter is destroyed, the file descriptor is closed. */ -iobuf_t iobuf_fdopen (int fd, const char *mode); +iobuf_t iobuf_fdopen (gnupg_fd_t fd, const char *mode); /* Like iobuf_fdopen, but doesn't close the file descriptor when the filter is destroyed. */ From 067bc2ed4c842eb8975bd68f58fc804e3bd74dcd Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 11 Jul 2023 13:49:41 +0900 Subject: [PATCH 125/869] gpg: Move the check by is_secured_file earlier. * g10/decrypt.c (decrypt_message_fd): Call is_secured_file here. * g10/plaintext.c (get_output_file): Remove the call. -- Fixes-commit: 71625f56fd98ab37bc05f1806b4b49a2e418ac37 GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- g10/decrypt.c | 12 ++++++++++++ g10/plaintext.c | 8 +------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/g10/decrypt.c b/g10/decrypt.c index 64ba0b7f1..0c2c51617 100644 --- a/g10/decrypt.c +++ b/g10/decrypt.c @@ -139,6 +139,18 @@ decrypt_message_fd (ctrl_t ctrl, gnupg_fd_t input_fd, return err; } + if (is_secured_file (output_fd)) + { + char xname[64]; + + err = gpg_error (GPG_ERR_EPERM); + snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)output_fd); + log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err)); + iobuf_close (fp); + release_progress_context (pfx); + return err; + } + opt.outfp = open_stream_nc (output_fd, "w"); if (!opt.outfp) { diff --git a/g10/plaintext.c b/g10/plaintext.c index 9544ddf03..03ddadcec 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -145,13 +145,7 @@ get_output_file (const byte *embedded_name, int embedded_namelen, } } - if (opt.outfp && is_secured_file (es_fileno (opt.outfp))) - { - err = gpg_error (GPG_ERR_EPERM); - log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err)); - goto leave; - } - else if (fp || nooutput) + if (fp || nooutput) ; else if (is_secured_filename (fname)) { From b07b5144ff6a9208ea27fe1e1518270bd22b382c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 12 Jul 2023 13:34:19 +0900 Subject: [PATCH 126/869] gpg: Fix expiration time when Creation-Date is specified. * g10/keygen.c (parse_expire_string_with_ct): New function, optionally supply the creation time. (parse_expire_string): Use parse_expire_string_with_ct with no creation time. (proc_parameter_file): Use parse_expire_string_with_ct possibly with the creation time. -- GnuPG-bug-id: 5252 Signed-off-by: NIIBE Yutaka --- g10/keygen.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 3cafc476d..594a9ee82 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2740,14 +2740,19 @@ ask_curve (int *algo, int *subkey_algo, const char *current) * just cope for the next few years until we get a 64-bit time_t or * similar. */ -u32 -parse_expire_string( const char *string ) +static u32 +parse_expire_string_with_ct (const char *string, u32 creation_time) { int mult; u32 seconds; u32 abs_date = 0; - u32 curtime = make_timestamp (); time_t tt; + u32 curtime; + + if (creation_time == (u32)-1) + curtime = make_timestamp (); + else + curtime = creation_time; if (!string || !*string || !strcmp (string, "none") || !strcmp (string, "never") || !strcmp (string, "-")) @@ -2767,6 +2772,13 @@ parse_expire_string( const char *string ) return seconds; } +u32 +parse_expire_string ( const char *string ) +{ + return parse_expire_string_with_ct (string, (u32)-1); +} + + /* Parse a Creation-Date string which is either "1986-04-26" or "19860426T042640". Returns 0 on error. */ static u32 @@ -4157,6 +4169,7 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname, int is_default = 0; int have_user_id = 0; int err, algo; + u32 creation_time = (u32)-1; /* Check that we have all required parameters. */ r = get_parameter( para, pKEYTYPE ); @@ -4322,15 +4335,13 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname, if (r && *r->u.value && !(get_parameter_bool (para, pCARDKEY) && get_parameter_u32 (para, pKEYCREATIONDATE))) { - u32 seconds; - - seconds = parse_creation_string (r->u.value); - if (!seconds) + creation_time = parse_creation_string (r->u.value); + if (!creation_time) { log_error ("%s:%d: invalid creation date\n", fname, r->lnr ); return -1; } - r->u.creation = seconds; + r->u.creation = creation_time; r->key = pKEYCREATIONDATE; /* Change that entry. */ } @@ -4340,7 +4351,7 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname, { u32 seconds; - seconds = parse_expire_string( r->u.value ); + seconds = parse_expire_string_with_ct (r->u.value, creation_time); if( seconds == (u32)-1 ) { log_error("%s:%d: invalid expire date\n", fname, r->lnr ); From 23bcb78d279ebc81ec9340356401d19cf89985f1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 12 Jul 2023 14:04:28 +0900 Subject: [PATCH 127/869] gpg: Add support for Subkey-Expire-Date. * g10/keygen.c (enum para_name): Add pSUBKEYEXPIREDATE. (proc_parameter_file): Add support for pSUBKEYEXPIREDATE. (read_parameter_file): Add "Subkey-Expire-Date". -- Signed-off-by: NIIBE Yutaka --- g10/keygen.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 594a9ee82..1605bff89 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -87,6 +87,7 @@ enum para_name { pEXPIREDATE, pKEYEXPIRE, /* in n seconds */ pSUBKEYCREATIONDATE, + pSUBKEYEXPIREDATE, pSUBKEYEXPIRE, /* in n seconds */ pAUTHKEYCREATIONDATE, /* Not yet used. */ pPASSPHRASE, @@ -4358,12 +4359,29 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname, return -1; } r->u.expire = seconds; - r->key = pKEYEXPIRE; /* change hat entry */ - /* also set it for the subkey */ - r = xmalloc_clear( sizeof *r + 20 ); - r->key = pSUBKEYEXPIRE; - r->u.expire = seconds; - append_to_parameter (para, r); + r->key = pKEYEXPIRE; /* change that entry */ + + /* Make SUBKEYEXPIRE from Subkey-Expire-Date, if any. */ + r = get_parameter( para, pSUBKEYEXPIREDATE ); + if( r && *r->u.value ) + { + seconds = parse_expire_string_with_ct (r->u.value, creation_time); + if( seconds == (u32)-1 ) + { + log_error("%s:%d: invalid subkey expire date\n", fname, r->lnr ); + return -1; + } + r->key = pSUBKEYEXPIRE; /* change that entry */ + r->u.expire = seconds; + } + else + { + /* Or else, set Expire-Date for the subkey */ + r = xmalloc_clear( sizeof *r + 20 ); + r->key = pSUBKEYEXPIRE; + r->u.expire = seconds; + append_to_parameter (para, r); + } } do_generate_keypair (ctrl, para, outctrl, card ); @@ -4394,6 +4412,7 @@ read_parameter_file (ctrl_t ctrl, const char *fname ) { "Name-Email", pNAMEEMAIL }, { "Name-Comment", pNAMECOMMENT }, { "Expire-Date", pEXPIREDATE }, + { "Subkey-Expire-Date", pSUBKEYEXPIREDATE }, { "Creation-Date", pCREATIONDATE }, { "Passphrase", pPASSPHRASE }, { "Preferences", pPREFERENCES }, From fb046ccd931d145d6db27ffbf2c36b1852687380 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 13 Jul 2023 11:18:47 +0900 Subject: [PATCH 128/869] sm: Use open_stream_nc for HANDLE by assuan_get_output_fd. * sm/server.c (cmd_encrypt): Use gnupg_fd_t for OUT_FD. Call open_stream_nc with OUT_FD. (cmd_decrypt, cmd_verify, cmd_sign, cmd_export): Likewise. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- sm/server.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/sm/server.c b/sm/server.c index b545c1bfb..934d3764d 100644 --- a/sm/server.c +++ b/sm/server.c @@ -451,7 +451,8 @@ cmd_encrypt (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); certlist_t cl; - int inp_fd, out_fd; + int inp_fd; + gnupg_fd_t out_fd; estream_t out_fp; int rc; @@ -460,11 +461,11 @@ cmd_encrypt (assuan_context_t ctx, char *line) inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); if (inp_fd == -1) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); - if (out_fd == -1) + out_fd = assuan_get_output_fd (ctx); + if (out_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); - out_fp = es_fdopen_nc (out_fd, "w"); + out_fp = open_stream_nc (out_fd, "w"); if (!out_fp) return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); @@ -508,7 +509,8 @@ static gpg_error_t cmd_decrypt (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; + int inp_fd; + gnupg_fd_t out_fd; estream_t out_fp; int rc; @@ -517,11 +519,11 @@ cmd_decrypt (assuan_context_t ctx, char *line) inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); if (inp_fd == -1) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); - if (out_fd == -1) + out_fd = assuan_get_output_fd (ctx); + if (out_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); - out_fp = es_fdopen_nc (out_fd, "w"); + out_fp = open_stream_nc (out_fd, "w"); if (!out_fp) return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); @@ -554,7 +556,7 @@ cmd_verify (assuan_context_t ctx, char *line) int rc; ctrl_t ctrl = assuan_get_pointer (ctx); int fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); - int out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); + gnupg_fd_t out_fd = assuan_get_output_fd (ctx); estream_t out_fp = NULL; (void)line; @@ -562,9 +564,9 @@ cmd_verify (assuan_context_t ctx, char *line) if (fd == -1) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - if (out_fd != -1) + if (out_fd != GNUPG_INVALID_FD) { - out_fp = es_fdopen_nc (out_fd, "w"); + out_fp = open_stream_nc (out_fd, "w"); if (!out_fp) return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); } @@ -594,7 +596,8 @@ static gpg_error_t cmd_sign (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; + int inp_fd; + gnupg_fd_t out_fd; estream_t out_fp; int detached; int rc; @@ -602,13 +605,13 @@ cmd_sign (assuan_context_t ctx, char *line) inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); if (inp_fd == -1) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); - if (out_fd == -1) + out_fd = assuan_get_output_fd (ctx); + if (out_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); detached = has_option (line, "--detached"); - out_fp = es_fdopen_nc (out_fd, "w"); + out_fp = open_stream_nc (out_fd, "w"); if (!out_fp) return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed"); @@ -756,15 +759,15 @@ cmd_export (assuan_context_t ctx, char *line) } else { - int fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); + gnupg_fd_t fd = assuan_get_output_fd (ctx); estream_t out_fp; - if (fd == -1) + if (fd == GNUPG_INVALID_FD) { free_strlist (list); return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); } - out_fp = es_fdopen_nc (fd, "w"); + out_fp = open_stream_nc (fd, "w"); if (!out_fp) { free_strlist (list); From 69c1d812842c2cd50e7139c3aa851930dad08b72 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 13 Jul 2023 13:44:32 +0900 Subject: [PATCH 129/869] sm: Use gnupg_fd_t and open_stream_nc for assuan_get_input_fd. * sm/server.c (cmd_genkey): Use open_stream_nc for input and output. (cmd_getauditlog): Use open_stream_nc for output. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- sm/server.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sm/server.c b/sm/server.c index 934d3764d..bb048a62a 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1090,24 +1090,24 @@ static gpg_error_t cmd_genkey (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - int inp_fd, out_fd; + gnupg_fd_t inp_fd, out_fd; estream_t in_stream, out_stream; int rc; (void)line; - inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); - if (inp_fd == -1) + inp_fd = assuan_get_input_fd (ctx); + if (inp_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); - if (out_fd == -1) + out_fd = assuan_get_output_fd (ctx); + if (out_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); - in_stream = es_fdopen_nc (inp_fd, "r"); + in_stream = open_stream_nc (inp_fd, "r"); if (!in_stream) return set_error (GPG_ERR_ASS_GENERAL, "es_fdopen failed"); - out_stream = es_fdopen_nc (out_fd, "w"); + out_stream = open_stream_nc (out_fd, "w"); if (!out_stream) { es_fclose (in_stream); @@ -1138,7 +1138,7 @@ static gpg_error_t cmd_getauditlog (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - int out_fd; + gnupg_fd_t out_fd; estream_t out_stream; int opt_data, opt_html; int rc; @@ -1159,11 +1159,11 @@ cmd_getauditlog (assuan_context_t ctx, char *line) } else { - out_fd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); - if (out_fd == -1) + out_fd = assuan_get_output_fd (ctx); + if (out_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); - out_stream = es_fdopen_nc (out_fd, "w"); + out_stream = open_stream_nc (out_fd, "w"); if (!out_stream) { return set_error (GPG_ERR_ASS_GENERAL, "es_fdopen() failed"); From ea625c74f00a81245a34f5330e5d92790ea84f5d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 13 Jul 2023 13:51:26 +0900 Subject: [PATCH 130/869] sm: Use open_stream_nc for do_listkeys. * sm/server.c (do_listkeys): Use open_stream_nc. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- sm/server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sm/server.c b/sm/server.c index bb048a62a..693932c2e 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1014,14 +1014,14 @@ do_listkeys (assuan_context_t ctx, char *line, int mode) if (ctrl->server_local->list_to_output) { - int outfd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1); + gnupg_fd_t outfd = assuan_get_output_fd (ctx); - if ( outfd == -1 ) + if ( outfd == GNUPG_INVALID_FD ) { free_strlist (list); return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); } - fp = es_fdopen_nc (outfd, "w"); + fp = open_stream_nc (outfd, "w"); if (!fp) { free_strlist (list); From cf270b0d3028a0837a69bb9f9b2ba13dafd536a4 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 13 Jul 2023 14:35:00 +0900 Subject: [PATCH 131/869] sm: Fix open_es_fread and open_es_fwrite for gnupg_fd_t. * sm/gpgsm.c (open_es_fread, open_es_fwrite): Use gnupg_fd_t and open_stream_nc. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- sm/gpgsm.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index ce977413d..f23c63e0b 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -2327,7 +2327,7 @@ open_es_fread (const char *filename, const char *mode) estream_t fp; if (filename[0] == '-' && !filename[1]) - fd = fileno (stdin); + return es_fpopen_nc (stdin, mode); else fd = check_special_filename (filename, 0, 0); if (fd != -1) @@ -2335,7 +2335,8 @@ open_es_fread (const char *filename, const char *mode) fp = es_fdopen_nc (fd, mode); if (!fp) { - log_error ("es_fdopen(%d) failed: %s\n", fd, strerror (errno)); + log_error ("es_fdopen(%d) failed: %s\n", (int)(intptr_t)fd, + strerror (errno)); gpgsm_exit (2); } return fp; @@ -2357,23 +2358,24 @@ open_es_fread (const char *filename, const char *mode) static estream_t open_es_fwrite (const char *filename) { - int fd; + gnupg_fd_t fd; estream_t fp; if (filename[0] == '-' && !filename[1]) { fflush (stdout); - fp = es_fdopen_nc (fileno(stdout), "wb"); + fp = es_fpopen_nc (stdout, "wb"); return fp; } - fd = check_special_filename (filename, 1, 0); - if (fd != -1) + fd = gnupg_check_special_filename (filename); + if (fd != GNUPG_INVALID_FD) { - fp = es_fdopen_nc (fd, "wb"); + fp = open_stream_nc (fd, "wb"); if (!fp) { - log_error ("es_fdopen(%d) failed: %s\n", fd, strerror (errno)); + log_error ("es_fdopen(%d) failed: %s\n", + (int)(intptr_t)fd, strerror (errno)); gpgsm_exit (2); } return fp; From 5d375bb1682548a70882f270f8c8bba7033ab642 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 14 Jul 2023 15:49:23 +0900 Subject: [PATCH 132/869] gpg: Use is_secured_filename before opening the file. * g10/gpg.c (print_mds): Check by is_secured_filename, earlier. * g10/tdbdump.c (import_ownertrust): Likewise. -- GnuPG-bug-id: 6508 Signed-off-by: NIIBE Yutaka --- g10/gpg.c | 6 +++--- g10/tdbdump.c | 13 +++++-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/g10/gpg.c b/g10/gpg.c index d836ff072..23bf8d971 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -5622,13 +5622,13 @@ print_mds( const char *fname, int algo ) } else { - fp = es_fopen (fname, "rb" ); - if (fp && is_secured_file (es_fileno (fp))) + if (is_secured_filename (fname)) { - es_fclose (fp); fp = NULL; gpg_err_set_errno (EPERM); } + else + fp = es_fopen (fname, "rb" ); } if (!fp) { diff --git a/g10/tdbdump.c b/g10/tdbdump.c index 2a02ad108..9ff3f81a3 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -141,19 +141,16 @@ import_ownertrust (ctrl_t ctrl, const char *fname ) fname = "[stdin]"; is_stdin = 1; } + else if (is_secured_filename (fname)) { + gpg_err_set_errno (EPERM); + log_error (_("can't open '%s': %s\n"), fname, strerror(errno) ); + return; + } else if( !(fp = es_fopen( fname, "r" )) ) { log_error ( _("can't open '%s': %s\n"), fname, strerror(errno) ); return; } - if (is_secured_file (es_fileno (fp))) - { - es_fclose (fp); - gpg_err_set_errno (EPERM); - log_error (_("can't open '%s': %s\n"), fname, strerror(errno) ); - return; - } - while (es_fgets (line, DIM(line)-1, fp)) { TRUSTREC rec; From ee9e3578ce30892ce86276819f0eedf8fb3f6e47 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 14 Jul 2023 15:52:08 +0900 Subject: [PATCH 133/869] gpg: Use gnupg_fd_t for iobuf_get_fd and is_secured_file. * common/iobuf.c (iobuf_get_fd): Return type is now gnupg_fd_t. * common/iobuf.h (iobuf_get_fd): Fix the return type. * g10/misc.c (is_secured_file): Argument is now gnupg_fd_t. * g10/main.h (is_secured_file): Fix the argument type. -- GnuPG-bug-id: 6580 Signed-off-by: NIIBE Yutaka --- common/iobuf.c | 6 +++--- common/iobuf.h | 2 +- g10/main.h | 2 +- g10/misc.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index 3c5dc800c..f70ab9879 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -2641,20 +2641,20 @@ iobuf_get_filelength (iobuf_t a) } -int +gnupg_fd_t iobuf_get_fd (iobuf_t a) { for (; a->chain; a = a->chain) ; if (a->filter != file_filter) - return -1; + return GNUPG_INVALID_FD; { file_filter_ctx_t *b = a->filter_ov; gnupg_fd_t fp = b->fp; - return FD2INT (fp); + return fp; } } diff --git a/common/iobuf.h b/common/iobuf.h index 4a723908d..4354c718d 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -590,7 +590,7 @@ uint64_t iobuf_get_filelength (iobuf_t a); /* Return the file descriptor designating the underlying file. This only works with file_filter based pipelines. */ -int iobuf_get_fd (iobuf_t a); +gnupg_fd_t iobuf_get_fd (iobuf_t a); /* Return the real filename, if available. This only supports pipelines that end in file filters. Returns NULL if not diff --git a/g10/main.h b/g10/main.h index 38e6a9c22..c202dacb8 100644 --- a/g10/main.h +++ b/g10/main.h @@ -107,7 +107,7 @@ char *make_radix64_string( const byte *data, size_t len ); void trap_unaligned(void); void register_secured_file (const char *fname); void unregister_secured_file (const char *fname); -int is_secured_file (int fd); +int is_secured_file (gnupg_fd_t fd); int is_secured_filename (const char *fname); u16 checksum_u16( unsigned n ); u16 checksum( const byte *p, unsigned n ); diff --git a/g10/misc.c b/g10/misc.c index d1f0efc6e..ec9b9025d 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -160,7 +160,7 @@ unregister_secured_file (const char *fname) /* Return true if FD is corresponds to a secured file. Using -1 for FS is allowed and will return false. */ int -is_secured_file (int fd) +is_secured_file (gnupg_fd_t fd) { #ifdef ENABLE_SELINUX_HACKS struct stat buf; From b849c930e9b5056b705ab08285eb96aacbebbd23 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 18 Jul 2023 11:54:16 +0900 Subject: [PATCH 134/869] common: Introduce FD_DBG to display gnupg_fd_t value. * common/sysutils.h (FD_DBG): New. * agent/gpg-agent.c (check_nonce): Use FD_DBG. (do_start_connection_thread, start_connection_thread_ssh): Likewise. * common/iobuf.c (fd_cache_close, file_filter, do_open): Likewise. (do_iobuf_fdopen): Likewise. * dirmngr/dirmngr.c (check_nonce, start_connection_thread) (handle_connections): Likewise. * dirmngr/http.c (_my_socket_new, _my_socket_ref): Likewise. (_my_socket_unref): Likewise. * g10/decrypt.c (decrypt_message_fd): Likewise. * g10/encrypt.c (encrypt_crypt): Likewise. * g10/openfile.c (open_outfile): Likewise. * g10/plaintext.c (get_output_file, hash_datafile_by_fd): Likewise. * g10/verify.c (gpg_verify): Likewise. * kbx/keyboxd.c (check_nonce, do_start_connection_thread): Likewise. * scd/scdaemon.c (start_connection_thread): Likewise. (handle_connections): Likewise. * sm/gpgsm.c (open_es_fread, open_es_fwrite): Likewise. * tpm2d/tpm2daemon.c (start_connection_thread): Likewise. (handle_connections): Likewise. -- GnuPG-bug-id: 6597 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 10 +++++----- common/iobuf.c | 9 +++++---- common/sysutils.h | 2 ++ dirmngr/dirmngr.c | 8 ++++---- dirmngr/http.c | 6 +++--- g10/decrypt.c | 4 ++-- g10/encrypt.c | 2 +- g10/openfile.c | 4 ++-- g10/plaintext.c | 4 ++-- g10/verify.c | 3 ++- kbx/keyboxd.c | 6 +++--- scd/scdaemon.c | 8 ++++---- sm/gpgsm.c | 4 ++-- tpm2d/tpm2daemon.c | 8 ++++---- 14 files changed, 41 insertions(+), 37 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index e55cd0b7c..de33d0b4e 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -2569,7 +2569,7 @@ check_nonce (ctrl_t ctrl, assuan_sock_nonce_t *nonce) if (assuan_sock_check_nonce (ctrl->thread_startup.fd, nonce)) { log_info (_("error reading nonce on fd %d: %s\n"), - FD2INT(ctrl->thread_startup.fd), strerror (errno)); + FD_DBG (ctrl->thread_startup.fd), strerror (errno)); assuan_sock_close (ctrl->thread_startup.fd); xfree (ctrl); return -1; @@ -2869,12 +2869,12 @@ do_start_connection_thread (ctrl_t ctrl) agent_init_default_ctrl (ctrl); if (opt.verbose > 1 && !DBG_IPC) log_info (_("handler 0x%lx for fd %d started\n"), - (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD_DBG (ctrl->thread_startup.fd)); start_command_handler (ctrl, GNUPG_INVALID_FD, ctrl->thread_startup.fd); if (opt.verbose > 1 && !DBG_IPC) log_info (_("handler 0x%lx for fd %d terminated\n"), - (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD_DBG (ctrl->thread_startup.fd)); agent_deinit_default_ctrl (ctrl); xfree (ctrl); @@ -2949,12 +2949,12 @@ start_connection_thread_ssh (void *arg) agent_init_default_ctrl (ctrl); if (opt.verbose) log_info (_("ssh handler 0x%lx for fd %d started\n"), - (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD_DBG (ctrl->thread_startup.fd)); start_command_handler_ssh (ctrl, ctrl->thread_startup.fd); if (opt.verbose) log_info (_("ssh handler 0x%lx for fd %d terminated\n"), - (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD_DBG (ctrl->thread_startup.fd)); agent_deinit_default_ctrl (ctrl); xfree (ctrl); diff --git a/common/iobuf.c b/common/iobuf.c index f70ab9879..e46eeac95 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -390,7 +390,7 @@ fd_cache_close (const char *fname, gnupg_fd_t fp) close (fp); #endif if (DBG_IOBUF) - log_debug ("fd_cache_close (%d) real\n", (int)fp); + log_debug ("fd_cache_close (%d) real\n", FD_DBG (fp)); return; } /* try to reuse a slot */ @@ -697,7 +697,7 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, if (f != FD_FOR_STDIN && f != FD_FOR_STDOUT) { if (DBG_IOBUF) - log_debug ("%s: close fd/handle %d\n", a->fname, FD2INT (f)); + log_debug ("%s: close fd/handle %d\n", a->fname, FD_DBG (f)); if (!a->keep_open) fd_cache_close (a->no_cache ? NULL : a->fname, f); } @@ -1472,7 +1472,8 @@ do_open (const char *fname, int special_filenames, file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); if (DBG_IOBUF) log_debug ("iobuf-%d.%d: open '%s' desc=%s fd=%d\n", - a->no, a->subno, fname, iobuf_desc (a, desc), FD2INT (fcx->fp)); + a->no, a->subno, fname, iobuf_desc (a, desc), + FD_DBG (fcx->fp)); return a; } @@ -1509,7 +1510,7 @@ do_iobuf_fdopen (gnupg_fd_t fp, const char *mode, int keep_open) fcx->fp = fp; fcx->print_only_name = 1; fcx->keep_open = keep_open; - sprintf (fcx->fname, "[fd %d]", (int)(intptr_t)fp); + sprintf (fcx->fname, "[fd %d]", FD_DBG (fp)); a->filter = file_filter; a->filter_ov = fcx; file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); diff --git a/common/sysutils.h b/common/sysutils.h index c6740a874..180e82df8 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -39,11 +39,13 @@ typedef void *gnupg_fd_t; #define GNUPG_INVALID_FD ((void*)(-1)) #define INT2FD(s) ((void *)(s)) #define FD2INT(h) ((unsigned int)(h)) +#define FD_DBG(h) ((int)(intptr_t)(h)) #else typedef int gnupg_fd_t; #define GNUPG_INVALID_FD (-1) #define INT2FD(s) (s) #define FD2INT(h) (h) +#define FD_DBG(h) (h) #endif #ifdef HAVE_STAT diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 799f7cd5f..8b0fefc64 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -2232,7 +2232,7 @@ check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce) if (assuan_sock_check_nonce (fd, nonce)) { log_info (_("error reading nonce on fd %d: %s\n"), - FD2INT (fd), strerror (errno)); + FD_DBG (fd), strerror (errno)); assuan_sock_close (fd); return -1; } @@ -2266,7 +2266,7 @@ start_connection_thread (void *arg) active_connections++; if (opt.verbose) - log_info (_("handler for fd %d started\n"), FD2INT (fd)); + log_info (_("handler for fd %d started\n"), FD_DBG (fd)); session_id = ++last_session_id; if (!session_id) @@ -2274,7 +2274,7 @@ start_connection_thread (void *arg) start_command_handler (fd, session_id); if (opt.verbose) - log_info (_("handler for fd %d terminated\n"), FD2INT (fd)); + log_info (_("handler for fd %d terminated\n"), FD_DBG (fd)); active_connections--; workqueue_run_post_session_tasks (session_id); @@ -2493,7 +2493,7 @@ handle_connections (assuan_fd_t listen_fd) memset (&argval, 0, sizeof argval); argval.afd = fd; snprintf (threadname, sizeof threadname, - "conn fd=%d", FD2INT(fd)); + "conn fd=%d", FD_DBG (fd)); ret = npth_create (&thread, &tattr, start_connection_thread, argval.aptr); diff --git a/dirmngr/http.c b/dirmngr/http.c index 8153fcef4..211d167bd 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -397,7 +397,7 @@ _my_socket_new (int lnr, assuan_fd_t fd) so->refcount = 1; if (opt_debug) log_debug ("http.c:%d:socket_new: object %p for fd %d created\n", - lnr, so, (int)so->fd); + lnr, so, FD_DBG (so->fd)); return so; } #define my_socket_new(a) _my_socket_new (__LINE__, (a)) @@ -409,7 +409,7 @@ _my_socket_ref (int lnr, my_socket_t so) so->refcount++; if (opt_debug > 1) log_debug ("http.c:%d:socket_ref: object %p for fd %d refcount now %d\n", - lnr, so, (int)so->fd, so->refcount); + lnr, so, FD_DBG (so->fd), so->refcount); return so; } #define my_socket_ref(a) _my_socket_ref (__LINE__,(a)) @@ -427,7 +427,7 @@ _my_socket_unref (int lnr, my_socket_t so, so->refcount--; if (opt_debug > 1) log_debug ("http.c:%d:socket_unref: object %p for fd %d ref now %d\n", - lnr, so, (int)so->fd, so->refcount); + lnr, so, FD_DBG (so->fd), so->refcount); if (!so->refcount) { diff --git a/g10/decrypt.c b/g10/decrypt.c index 0c2c51617..b30359af4 100644 --- a/g10/decrypt.c +++ b/g10/decrypt.c @@ -144,7 +144,7 @@ decrypt_message_fd (ctrl_t ctrl, gnupg_fd_t input_fd, char xname[64]; err = gpg_error (GPG_ERR_EPERM); - snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)output_fd); + snprintf (xname, sizeof xname, "[fd %d]", FD_DBG (output_fd)); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err)); iobuf_close (fp); release_progress_context (pfx); @@ -157,7 +157,7 @@ decrypt_message_fd (ctrl_t ctrl, gnupg_fd_t input_fd, char xname[64]; err = gpg_error_from_syserror (); - snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)output_fd); + snprintf (xname, sizeof xname, "[fd %d]", FD_DBG (output_fd)); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err)); iobuf_close (fp); release_progress_context (pfx); diff --git a/g10/encrypt.c b/g10/encrypt.c index a5b020736..62483fa16 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -842,7 +842,7 @@ encrypt_crypt (ctrl_t ctrl, gnupg_fd_t filefd, const char *filename, rc = gpg_error_from_syserror (); if (filefd != GNUPG_INVALID_FD) - snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)filefd); + snprintf (xname, sizeof xname, "[fd %d]", FD_DBG (filefd)); else if (!filename) strcpy (xname, "[stdin]"); else diff --git a/g10/openfile.c b/g10/openfile.c index 80c33f094..01f323399 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -193,12 +193,12 @@ open_outfile (gnupg_fd_t out_fd, const char *iname, int mode, if (!*a) { rc = gpg_error_from_syserror (); - snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)out_fd); + snprintf (xname, sizeof xname, "[fd %d]", FD_DBG (out_fd)); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (rc)); } else if (opt.verbose) { - snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)out_fd); + snprintf (xname, sizeof xname, "[fd %d]", FD_DBG (out_fd)); log_info (_("writing to '%s'\n"), xname); } } diff --git a/g10/plaintext.c b/g10/plaintext.c index 03ddadcec..a96214994 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -124,7 +124,7 @@ get_output_file (const byte *embedded_name, int embedded_namelen, else if (!(fp = open_stream_nc (fd, "wb"))) { err = gpg_error_from_syserror (); - snprintf (xname, sizeof xname, "[fd %d]", (int)(intptr_t)fd); + snprintf (xname, sizeof xname, "[fd %d]", FD_DBG (fd)); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err)); goto leave; } @@ -740,7 +740,7 @@ hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, { int rc = gpg_error_from_syserror (); log_error (_("can't open signed data fd=%d: %s\n"), - data_fd, strerror (errno)); + FD_DBG (data_fd), strerror (errno)); release_progress_context (pfx); return rc; } diff --git a/g10/verify.c b/g10/verify.c index 17134a281..f8abadd45 100644 --- a/g10/verify.c +++ b/g10/verify.c @@ -261,7 +261,8 @@ gpg_verify (ctrl_t ctrl, gnupg_fd_t sig_fd, gnupg_fd_t data_fd, if (!fp) { rc = gpg_error_from_syserror (); - log_error (_("can't open fd %d: %s\n"), sig_fd, strerror (errno)); + log_error (_("can't open fd %d: %s\n"), FD_DBG (sig_fd), + strerror (errno)); goto leave; } diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index 88a350a08..8fbc36195 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -1395,7 +1395,7 @@ check_nonce (ctrl_t ctrl, assuan_sock_nonce_t *nonce) if (assuan_sock_check_nonce (ctrl->thread_startup.fd, nonce)) { log_info (_("error reading nonce on fd %d: %s\n"), - FD2INT(ctrl->thread_startup.fd), strerror (errno)); + FD_DBG (ctrl->thread_startup.fd), strerror (errno)); assuan_sock_close (ctrl->thread_startup.fd); xfree (ctrl); return -1; @@ -1415,7 +1415,7 @@ do_start_connection_thread (ctrl_t ctrl) kbxd_init_default_ctrl (ctrl); if (opt.verbose && !DBG_IPC) log_info (_("handler 0x%lx for fd %d started\n"), - (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD_DBG (ctrl->thread_startup.fd)); session_id = ++last_session_id; if (!session_id) @@ -1423,7 +1423,7 @@ do_start_connection_thread (ctrl_t ctrl) kbxd_start_command_handler (ctrl, ctrl->thread_startup.fd, session_id); if (opt.verbose && !DBG_IPC) log_info (_("handler 0x%lx for fd %d terminated\n"), - (unsigned long) npth_self(), FD2INT(ctrl->thread_startup.fd)); + (unsigned long) npth_self(), FD_DBG (ctrl->thread_startup.fd)); kbxd_deinit_default_ctrl (ctrl); xfree (ctrl); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index e43769f85..6422ebec9 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1183,7 +1183,7 @@ start_connection_thread (void *arg) && assuan_sock_check_nonce (ctrl->thread_startup.fd, &socket_nonce)) { log_info (_("error reading nonce on fd %d: %s\n"), - FD2INT(ctrl->thread_startup.fd), strerror (errno)); + FD_DBG (ctrl->thread_startup.fd), strerror (errno)); assuan_sock_close (ctrl->thread_startup.fd); xfree (ctrl); return NULL; @@ -1194,7 +1194,7 @@ start_connection_thread (void *arg) scd_init_default_ctrl (ctrl); if (opt.verbose) log_info (_("handler for fd %d started\n"), - FD2INT(ctrl->thread_startup.fd)); + FD_DBG (ctrl->thread_startup.fd)); /* If this is a pipe server, we request a shutdown if the command handler asked for it. With the next ticker event and given that @@ -1206,7 +1206,7 @@ start_connection_thread (void *arg) if (opt.verbose) log_info (_("handler for fd %d terminated\n"), - FD2INT (ctrl->thread_startup.fd)); + FD_DBG (ctrl->thread_startup.fd)); scd_deinit_default_ctrl (ctrl); xfree (ctrl); @@ -1417,7 +1417,7 @@ handle_connections (gnupg_fd_t listen_fd) npth_t thread; snprintf (threadname, sizeof threadname, "conn fd=%d", - FD2INT (fd)); + FD_DBG (fd)); ctrl->thread_startup.fd = fd; ret = npth_create (&thread, &tattr, start_connection_thread, ctrl); if (ret) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index f23c63e0b..0b69e6d62 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -2335,7 +2335,7 @@ open_es_fread (const char *filename, const char *mode) fp = es_fdopen_nc (fd, mode); if (!fp) { - log_error ("es_fdopen(%d) failed: %s\n", (int)(intptr_t)fd, + log_error ("es_fdopen(%d) failed: %s\n", FD_DBG (fd), strerror (errno)); gpgsm_exit (2); } @@ -2375,7 +2375,7 @@ open_es_fwrite (const char *filename) if (!fp) { log_error ("es_fdopen(%d) failed: %s\n", - (int)(intptr_t)fd, strerror (errno)); + FD_DBG (fd), strerror (errno)); gpgsm_exit (2); } return fp; diff --git a/tpm2d/tpm2daemon.c b/tpm2d/tpm2daemon.c index b4e6f66e7..3246cfc9a 100644 --- a/tpm2d/tpm2daemon.c +++ b/tpm2d/tpm2daemon.c @@ -1012,7 +1012,7 @@ start_connection_thread (void *arg) && assuan_sock_check_nonce (ctrl->thread_startup.fd, &socket_nonce)) { log_info (_("error reading nonce on fd %d: %s\n"), - FD2INT (ctrl->thread_startup.fd), strerror (errno)); + FD_DBG (ctrl->thread_startup.fd), strerror (errno)); assuan_sock_close (ctrl->thread_startup.fd); xfree (ctrl); return NULL; @@ -1023,7 +1023,7 @@ start_connection_thread (void *arg) tpm2d_init_default_ctrl (ctrl); if (opt.verbose) log_info (_("handler for fd %d started\n"), - FD2INT (ctrl->thread_startup.fd)); + FD_DBG (ctrl->thread_startup.fd)); /* If this is a pipe server, we request a shutdown if the command handler asked for it. With the next ticker event and given that @@ -1035,7 +1035,7 @@ start_connection_thread (void *arg) if (opt.verbose) log_info (_("handler for fd %d terminated\n"), - FD2INT (ctrl->thread_startup.fd)); + FD_DBG (ctrl->thread_startup.fd)); tpm2d_deinit_default_ctrl (ctrl); xfree (ctrl); @@ -1255,7 +1255,7 @@ handle_connections (gnupg_fd_t listen_fd) char threadname[50]; npth_t thread; - snprintf (threadname, sizeof threadname, "conn fd=%d", FD2INT (fd)); + snprintf (threadname, sizeof threadname, "conn fd=%d", FD_DBG (fd)); ctrl->thread_startup.fd = fd; ret = npth_create (&thread, &tattr, start_connection_thread, ctrl); if (ret) From 81055baf5c31dc3ff0b181994dc7eb883472dafa Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 18 Jul 2023 12:07:25 +0900 Subject: [PATCH 135/869] dirmngr,kbk,tools: Fix type casting. * dirmngr/http.c (send_request): Remove cast which is not needed. * kbx/kbx-client-util.c (prepare_data_pipe): Cast to HANDLE. * tools/gpg-connect-agent.c (do_open): Ditto. -- GnuPG-bug-id: 6508 Signed-off-by: NIIBE Yutaka --- dirmngr/http.c | 4 ++-- kbx/kbx-client-util.c | 2 +- tools/gpg-connect-agent.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dirmngr/http.c b/dirmngr/http.c index 211d167bd..2345ce8c1 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2052,7 +2052,7 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, /* Until we support send/recv in estream under Windows we need * to use es_fopencookie. */ # ifdef HAVE_W32_SYSTEM - in = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "rb", + in = es_fopencookie (hd->sock->fd, "rb", simple_cookie_functions); # else in = es_fdopen_nc (hd->sock->fd, "rb"); @@ -2065,7 +2065,7 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, } # ifdef HAVE_W32_SYSTEM - out = es_fopencookie ((void*)(unsigned int)hd->sock->fd, "wb", + out = es_fopencookie (hd->sock->fd, "wb", simple_cookie_functions); # else out = es_fdopen_nc (hd->sock->fd, "wb"); diff --git a/kbx/kbx-client-util.c b/kbx/kbx-client-util.c index 9c7b57f2f..8cd6dc0f3 100644 --- a/kbx/kbx-client-util.c +++ b/kbx/kbx-client-util.c @@ -119,7 +119,7 @@ prepare_data_pipe (kbx_client_data_t kcd) } #ifdef HAVE_W32_SYSTEM - err = assuan_sendfd (kcd->ctx, INT2FD (_get_osfhandle (inpipe[1]))); + err = assuan_sendfd (kcd->ctx, (HANDLE)_get_osfhandle (inpipe[1])); #else err = assuan_sendfd (kcd->ctx, inpipe[1]); #endif diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index 6be401c4f..ab96d3b02 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -1040,7 +1040,7 @@ do_open (char *line) HANDLE prochandle, handle, newhandle; char numbuf[35]; - handle = (void*)_get_osfhandle (fd); + handle = (HANDLE)_get_osfhandle (fd); prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid); if (!prochandle) From ae188a3357cf9c90967eabdd304782dea40cd1a1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 18 Jul 2023 14:05:13 +0900 Subject: [PATCH 136/869] agent,build,w32: Fix use of SOCKET. * configure.ac (HAVE_SOCKET): Detect SOCKET type. * agent/command-ssh.c [HAVE_SOCKET] (start_command_handler_ssh): Use SOCKET to cast. -- GnuPG-bug-id: 6508 Signed-off-by: NIIBE Yutaka --- agent/command-ssh.c | 4 ++++ configure.ac | 2 ++ 2 files changed, 6 insertions(+) diff --git a/agent/command-ssh.c b/agent/command-ssh.c index ca3993321..0afa24111 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -3952,7 +3952,11 @@ start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client) es_syshd_t syshd; syshd.type = ES_SYSHD_SOCK; +#ifdef HAVE_SOCKET + syshd.u.sock = (SOCKET)sock_client; +#else syshd.u.sock = sock_client; +#endif get_client_info (sock_client, &peer_info); ctrl->client_pid = peer_info.pid; diff --git a/configure.ac b/configure.ac index fe7e82108..57bcdac4e 100644 --- a/configure.ac +++ b/configure.ac @@ -1385,6 +1385,8 @@ AC_CHECK_SIZEOF(time_t,,[[ ]]) GNUPG_TIME_T_UNSIGNED +# Check SOCKET type for Windows. +AC_CHECK_TYPES([SOCKET], [], [], [[#include "winsock2.h"]]) if test "$ac_cv_sizeof_unsigned_short" = "0" \ || test "$ac_cv_sizeof_unsigned_int" = "0" \ From 521ec40aea89a3e172874ccdef359e87b25f1242 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 18 Jul 2023 14:21:19 +0900 Subject: [PATCH 137/869] common,w32: Fix FD2INT macro. * common/sysutils.h [HAVE_W32_SYSTEM] (FD2INT): Use intptr_t for 64-bit Windows. -- GnuPG-bug-id: 6598 Signed-off-by: NIIBE Yutaka --- common/sysutils.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/sysutils.h b/common/sysutils.h index 180e82df8..e34fff72f 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -38,7 +38,11 @@ typedef void *gnupg_fd_t; #define GNUPG_INVALID_FD ((void*)(-1)) #define INT2FD(s) ((void *)(s)) -#define FD2INT(h) ((unsigned int)(h)) +# ifdef _WIN64 +# define FD2INT(h) ((intptr_t)(h)) +# else +# define FD2INT(h) ((unsigned int)(h)) +# endif #define FD_DBG(h) ((int)(intptr_t)(h)) #else typedef int gnupg_fd_t; From ea1935252e287b63f04c6d460cfb85e4e5efe379 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 18 Jul 2023 14:43:36 +0900 Subject: [PATCH 138/869] commond: Introduce FD2NUM to express conversion to number of fds. * common/sysutils.h (FD2NUM): New. * agent/call-pinentry.c (watch_sock): Use FD2NUM. * agent/gpg-agent.c (handle_connections): Likewise. * dirmngr/dirmngr.c (handle_connections): Likewise. * dirmngr/http.c (connect_with_timeout): Likewise. * kbx/keyboxd.c (handle_connections): Likewise. * scd/scdaemon.c (handle_connections): Likewise. * tpm2d/tpm2daemon.c (handle_connections): Likewise. -- GnuPG-bug-id: 6598 Signed-off-by: NIIBE Yutaka --- agent/call-pinentry.c | 2 +- agent/gpg-agent.c | 8 ++++---- common/sysutils.h | 2 ++ dirmngr/dirmngr.c | 2 +- dirmngr/http.c | 2 +- kbx/keyboxd.c | 2 +- scd/scdaemon.c | 2 +- tpm2d/tpm2daemon.c | 2 +- 8 files changed, 12 insertions(+), 10 deletions(-) diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 2369dffc2..9d8d93aec 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -1302,7 +1302,7 @@ watch_sock (void *arg) FD_ZERO (&fdset); FD_SET (FD2INT (sock), &fdset); - err = npth_select (FD2INT (sock)+1, &fdset, NULL, NULL, &timeout); + err = npth_select (FD2NUM (sock)+1, &fdset, NULL, NULL, &timeout); if (err < 0) { diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index de33d0b4e..335d389c6 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -3070,24 +3070,24 @@ handle_connections (gnupg_fd_t listen_fd, FD_ZERO (&fdset); FD_SET (FD2INT (listen_fd), &fdset); - nfd = FD2INT (listen_fd); + nfd = FD2NUM (listen_fd); if (listen_fd_extra != GNUPG_INVALID_FD) { FD_SET ( FD2INT(listen_fd_extra), &fdset); if (FD2INT (listen_fd_extra) > nfd) - nfd = FD2INT (listen_fd_extra); + nfd = FD2NUM (listen_fd_extra); } if (listen_fd_browser != GNUPG_INVALID_FD) { FD_SET ( FD2INT(listen_fd_browser), &fdset); if (FD2INT (listen_fd_browser) > nfd) - nfd = FD2INT (listen_fd_browser); + nfd = FD2NUM (listen_fd_browser); } if (listen_fd_ssh != GNUPG_INVALID_FD) { FD_SET ( FD2INT(listen_fd_ssh), &fdset); if (FD2INT (listen_fd_ssh) > nfd) - nfd = FD2INT (listen_fd_ssh); + nfd = FD2NUM (listen_fd_ssh); } if (sock_inotify_fd != -1) { diff --git a/common/sysutils.h b/common/sysutils.h index e34fff72f..dac2d9244 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -44,12 +44,14 @@ typedef void *gnupg_fd_t; # define FD2INT(h) ((unsigned int)(h)) # endif #define FD_DBG(h) ((int)(intptr_t)(h)) +#define FD2NUM(h) ((int)(intptr_t)(h)) #else typedef int gnupg_fd_t; #define GNUPG_INVALID_FD (-1) #define INT2FD(s) (s) #define FD2INT(h) (h) #define FD_DBG(h) (h) +#define FD2NUM(h) (h) #endif #ifdef HAVE_STAT diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 8b0fefc64..57f515b40 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -2377,7 +2377,7 @@ handle_connections (assuan_fd_t listen_fd) to full second. */ FD_ZERO (&fdset); FD_SET (FD2INT (listen_fd), &fdset); - nfd = FD2INT (listen_fd); + nfd = FD2NUM (listen_fd); if (my_inotify_fd != -1) { FD_SET (my_inotify_fd, &fdset); diff --git a/dirmngr/http.c b/dirmngr/http.c index 2345ce8c1..a7fd6ec26 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2906,7 +2906,7 @@ connect_with_timeout (assuan_fd_t sock, tval.tv_sec = timeout / 1000; tval.tv_usec = (timeout % 1000) * 1000; - n = my_select (FD2INT(sock)+1, &rset, &wset, NULL, &tval); + n = my_select (FD2NUM(sock)+1, &rset, &wset, NULL, &tval); if (n < 0) { err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index 8fbc36195..bfb0c653d 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -1521,7 +1521,7 @@ handle_connections (gnupg_fd_t listen_fd) FD_ZERO (&fdset); FD_SET (FD2INT (listen_fd), &fdset); - nfd = FD2INT (listen_fd); + nfd = FD2NUM (listen_fd); if (sock_inotify_fd != -1) { FD_SET (sock_inotify_fd, &fdset); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 6422ebec9..653fc78cc 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1313,7 +1313,7 @@ handle_connections (gnupg_fd_t listen_fd) if (listen_fd != GNUPG_INVALID_FD) { FD_SET (FD2INT (listen_fd), &fdset); - nfd = FD2INT (listen_fd); + nfd = FD2NUM (listen_fd); } for (;;) diff --git a/tpm2d/tpm2daemon.c b/tpm2d/tpm2daemon.c index 3246cfc9a..383421c30 100644 --- a/tpm2d/tpm2daemon.c +++ b/tpm2d/tpm2daemon.c @@ -1154,7 +1154,7 @@ handle_connections (gnupg_fd_t listen_fd) if (listen_fd != GNUPG_INVALID_FD) { FD_SET (FD2INT (listen_fd), &fdset); - nfd = FD2INT (listen_fd); + nfd = FD2NUM (listen_fd); } for (;;) From 6524becf28b134ed7c71001e7fd699dfe0546de8 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 19 Jul 2023 13:34:19 +0900 Subject: [PATCH 139/869] Revert "kbx,w32: Disable the fd-passing." This reverts commit 6944aefa3c2ef79cf3f14306ed384d22de36ba7f. -- The fd-passing works well on Windows with new libassuan (to be 3.0), and it doesn't require ASSUAN_SOCKET_SERVER_FDPASSING actually. Signed-off-by: NIIBE Yutaka --- kbx/kbxserver.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/kbx/kbxserver.c b/kbx/kbxserver.c index d50b9dfdf..d09a8f8eb 100644 --- a/kbx/kbxserver.c +++ b/kbx/kbxserver.c @@ -950,15 +950,9 @@ kbxd_start_command_handler (ctrl_t ctrl, gnupg_fd_t fd, unsigned int session_id) } else { - /* The fd-passing does not work reliable on Windows, and even it - * it is not used by gpg and gpgsm the current libassuan slows - * down things if it is allowed for the server.*/ rc = assuan_init_socket_server (ctx, fd, (ASSUAN_SOCKET_SERVER_ACCEPTED -#ifndef HAVE_W32_SYSTEM - |ASSUAN_SOCKET_SERVER_FDPASSING -#endif - )); + |ASSUAN_SOCKET_SERVER_FDPASSING)); } if (rc) From 6e2412e74a07dfea72191b64788dd52e50274241 Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Wed, 19 Jul 2023 11:27:08 +0200 Subject: [PATCH 140/869] dirmngr: Add doc for faked-system-time * dirmngr/dirmngr.c (gpgrt_opt_t): Use string for oFakedSystemTime. (oFakedSystemTime): Use similar conversion as gpgsm has. * dirmngr/dirmngr.texi (faked-system-time): Document it. -- For testing X509 certificates this is usually required and then confusing that the example from the gpgsm man page does not work for dirmngr. --- dirmngr/dirmngr.c | 9 +++++++-- doc/dirmngr.texi | 7 +++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 57f515b40..9528ba91b 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -221,7 +221,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"), ARGPARSE_s_i (oMaxReplies, "max-replies", N_("|N|do not return more than N items in one query")), - ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/ + ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"), ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"), ARGPARSE_s_s (oIgnoreCert,"ignore-cert", "@"), ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"), @@ -1179,7 +1179,12 @@ main (int argc, char **argv) case oLDAPAddServers: opt.add_new_ldapservers = 1; break; case oFakedSystemTime: - gnupg_set_time ((time_t)pargs.r.ret_ulong, 0); + { + time_t faked_time = isotime2epoch (pargs.r.ret_str); + if (faked_time == (time_t)(-1)) + faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10); + gnupg_set_time (faked_time, 0); + } break; case oForce: opt.force = 1; break; diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 0bf35b72f..fb448752a 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -175,6 +175,13 @@ names and are OR-ed together. The special flag "none" clears the list and allows to start over with an empty list. To get a list of available flags the sole word "help" can be used. +@item --faked-system-time @var{epoch} +@opindex faked-system-time +This option is only useful for testing; it sets the system time back or +forth to @var{epoch} which is the number of seconds elapsed since the year +1970. Alternatively @var{epoch} may be given as a full ISO time string +(e.g. "20070924T154812"). + @item --debug-level @var{level} @opindex debug-level Select the debug level for investigating problems. @var{level} may be a From eceba4f20749f936c4e787116aa5323dc95abaa5 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 21 Jul 2023 14:18:33 +0900 Subject: [PATCH 141/869] kbx: Fix error paths to fall back to D-lines. * kbx/kbx-client-util.c (prepare_data_pipe): Return an error. (kbx_client_data_new): Recover from an error by use of D-lines. (kbx_client_data_release): Handle the case of use of D-lines. -- Signed-off-by: NIIBE Yutaka --- kbx/kbx-client-util.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/kbx/kbx-client-util.c b/kbx/kbx-client-util.c index 8cd6dc0f3..2ea3f5ef7 100644 --- a/kbx/kbx-client-util.c +++ b/kbx/kbx-client-util.c @@ -129,7 +129,7 @@ prepare_data_pipe (kbx_client_data_t kcd) inpipe[1], gpg_strerror (err), gpg_strsource (err)); es_fclose (infp); gnupg_close_pipe (inpipe[1]); - return 0; /* Server may not support fd-passing. */ + return err; } err = assuan_transact (kcd->ctx, "OUTPUT FD", @@ -139,13 +139,12 @@ prepare_data_pipe (kbx_client_data_t kcd) log_info ("keyboxd does not accept our fd: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); es_fclose (infp); - return 0; + return err; } close (inpipe[1]); kcd->fp = infp; - rc = npth_attr_init (&tattr); if (rc) { @@ -295,8 +294,7 @@ kbx_client_data_new (kbx_client_data_t *r_kcd, assuan_context_t ctx, { err = gpg_error_from_errno (rc); log_error ("error initializing mutex: %s\n", gpg_strerror (err)); - xfree (kcd); - return err; + goto leave; /* Use D-lines. */ } rc = npth_cond_init (&kcd->cond, NULL); if (rc) @@ -304,8 +302,7 @@ kbx_client_data_new (kbx_client_data_t *r_kcd, assuan_context_t ctx, err = gpg_error_from_errno (rc); log_error ("error initializing condition: %s\n", gpg_strerror (err)); npth_mutex_destroy (&kcd->mutex); - xfree (kcd); - return err; + goto leave; /* Use D-lines. */ } err = prepare_data_pipe (kcd); @@ -313,8 +310,7 @@ kbx_client_data_new (kbx_client_data_t *r_kcd, assuan_context_t ctx, { npth_cond_destroy (&kcd->cond); npth_mutex_destroy (&kcd->mutex); - xfree (kcd); - return err; + /* Use D-lines. */ } leave: @@ -331,10 +327,16 @@ kbx_client_data_release (kbx_client_data_t kcd) if (!kcd) return; + fp = kcd->fp; + if (!fp) + { + xfree (kcd); + return; + } + if (npth_join (kcd->thd, NULL)) log_error ("kbx_client_data_release failed on npth_join"); - fp = kcd->fp; kcd->fp = NULL; es_fclose (fp); From 30fc365124aa86a915a6a729237a319729c7238e Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 21 Jul 2023 14:27:57 +0900 Subject: [PATCH 142/869] dirmngr: Silence compiler when it's without LDAP. * dirmngr/ks-action.c [!USE_LDAP] (ks_action_get): NEWER is not used. * ks_action_query [!USE_LDAP] (ks_action_query): Ignore unused args. -- Signed-off-by: NIIBE Yutaka --- dirmngr/ks-action.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dirmngr/ks-action.c b/dirmngr/ks-action.c index 002f1a7a5..2e04582a1 100644 --- a/dirmngr/ks-action.c +++ b/dirmngr/ks-action.c @@ -373,6 +373,8 @@ ks_action_get (ctrl_t ctrl, uri_item_t keyservers, || !strcmp (uri->parsed_uri->scheme, "ldaps") || !strcmp (uri->parsed_uri->scheme, "ldapi") || uri->parsed_uri->opaque); +#else + (void)newer; #endif if (is_hkp_s || is_http_s || is_ldap) @@ -590,6 +592,13 @@ ks_action_query (ctrl_t ctrl, const char *url, unsigned int ks_get_flags, return err; #else /* !USE_LDAP */ + (void)ctrl; + (void)url; + (void)ks_get_flags; + (void)filter; + (void)attrs; + (void)newer; + (void)outfp; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); #endif } From 083a16ae08eb0226f55783d6f7b65a35e7724067 Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Wed, 19 Jul 2023 11:27:08 +0200 Subject: [PATCH 143/869] dirmngr: Add doc for faked-system-time * dirmngr/dirmngr.c (gpgrt_opt_t): Use string for oFakedSystemTime. (oFakedSystemTime): Use similar conversion as gpgsm has. * dirmngr/dirmngr.texi (faked-system-time): Document it. -- For testing X509 certificates this is usually required and then confusing that the example from the gpgsm man page does not work for dirmngr. --- dirmngr/dirmngr.c | 9 +++++++-- doc/dirmngr.texi | 7 +++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index b460ed3b3..97c2dc490 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -221,7 +221,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"), ARGPARSE_s_i (oMaxReplies, "max-replies", N_("|N|do not return more than N items in one query")), - ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/ + ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"), ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"), ARGPARSE_s_s (oIgnoreCert,"ignore-cert", "@"), ARGPARSE_s_s (oIgnoreCertExtension,"ignore-cert-extension", "@"), @@ -1176,7 +1176,12 @@ main (int argc, char **argv) case oLDAPAddServers: opt.add_new_ldapservers = 1; break; case oFakedSystemTime: - gnupg_set_time ((time_t)pargs.r.ret_ulong, 0); + { + time_t faked_time = isotime2epoch (pargs.r.ret_str); + if (faked_time == (time_t)(-1)) + faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10); + gnupg_set_time (faked_time, 0); + } break; case oForce: opt.force = 1; break; diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 0bf35b72f..fb448752a 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -175,6 +175,13 @@ names and are OR-ed together. The special flag "none" clears the list and allows to start over with an empty list. To get a list of available flags the sole word "help" can be used. +@item --faked-system-time @var{epoch} +@opindex faked-system-time +This option is only useful for testing; it sets the system time back or +forth to @var{epoch} which is the number of seconds elapsed since the year +1970. Alternatively @var{epoch} may be given as a full ISO time string +(e.g. "20070924T154812"). + @item --debug-level @var{level} @opindex debug-level Select the debug level for investigating problems. @var{level} may be a From c68b70ce9d63221abfcaa9bb299c9f4556077006 Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Fri, 21 Jul 2023 10:29:22 +0200 Subject: [PATCH 144/869] w32: Add keyboxd.exe to signed files * build-aux/speedo.mk (AUTHENTICODE_FILES): Add keyboxd.exe -- This should prevent that keyboxd.exe is blocked on systems that only allow signed executables. --- build-aux/speedo.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 170c20b79..7777411e2 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -282,6 +282,7 @@ AUTHENTICODE_FILES= \ gpgtar.exe \ gpgv.exe \ gpg-card.exe \ + keyboxd.exe \ libassuan-0.dll \ libgcrypt-20.dll \ libgpg-error-0.dll \ From 95d97615097255a1db1b71eec4df18c171e88df1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 25 Jul 2023 10:04:18 +0900 Subject: [PATCH 145/869] sm: Use estream for I/O. * sm/decrypt.c (gpgsm_decrypt): Use estream for the input. * sm/encrypt.c (gpgsm_encrypt): Likewise. * sm/gpgsm.c (open_read): Remove. (main): Use open_es_fread for gpgsm_import_files. Fix call of gpgsm_encrypt, gpgsm_sign, gpgsm_verify and gpgsm_decrypt. (open_es_fread): Use gnupg_check_special_filename and open_stream_nc. * sm/gpgsm.h: Fix function declarations. * sm/import.c (import_one): Use estream for the input. (reimport_one, gpgsm_import, gpgsm_import_files): Likewise. * sm/server.c (struct server_local_s): Rename MESSAGE_FD to MESSAGE_FP. (close_message_fp): Rename from close_message_fd. (reset_notify): Follow the change of close_message_fp. (cmd_encrypt, cmd_decrypt, cmd_verify, cmd_sign): Follow the change of close_message_fp. Use open_stream_nc to get estream. (cmd_import): Likewise. (cmd_export, cmd_delkeys, gpgsm_server): Follow the change of close_message_fp. (cmd_message): Setup MESSAGE_FP with open_stream_nc. * sm/sign.c (hash_data): Use estream for the input. (hash_and_copy_data): Likewise. (gpgsm_sign): Likewise. * sm/verify.c (hash_data): Use estream_t for FP. (gpgsm_verify): Use estream_t for IN_FP and DATA_FP. -- GnuPG-bug-id: 6592 Signed-off-by: NIIBE Yutaka --- sm/decrypt.c | 12 +---- sm/encrypt.c | 14 +----- sm/gpgsm.c | 122 +++++++++++++++++++++++++++++++++------------------ sm/gpgsm.h | 13 +++--- sm/import.c | 51 +++++++++------------ sm/server.c | 121 +++++++++++++++++++++++++++++++------------------- sm/sign.c | 34 ++++---------- sm/verify.c | 41 +++++------------ 8 files changed, 203 insertions(+), 205 deletions(-) diff --git a/sm/decrypt.c b/sm/decrypt.c index 62983fe9c..a30eafc55 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -1052,7 +1052,7 @@ decrypt_gcm_filter (void *arg, /* Perform a decrypt operation. */ int -gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) +gpgsm_decrypt (ctrl_t ctrl, estream_t in_fp, estream_t out_fp) { int rc; gnupg_ksba_io_t b64reader = NULL; @@ -1063,7 +1063,6 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) ksba_stop_reason_t stopreason; KEYDB_HANDLE kh; int recp; - estream_t in_fp = NULL; struct decrypt_filter_parm_s dfparm; memset (&dfparm, 0, sizeof dfparm); @@ -1078,14 +1077,6 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) goto leave; } - in_fp = es_fdopen_nc (in_fd, "rb"); - if (!in_fp) - { - rc = gpg_error_from_syserror (); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - rc = gnupg_ksba_create_reader (&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0) | (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0) @@ -1516,7 +1507,6 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) gnupg_ksba_destroy_reader (b64reader); gnupg_ksba_destroy_writer (b64writer); keydb_release (kh); - es_fclose (in_fp); if (dfparm.hd) gcry_cipher_close (dfparm.hd); return rc; diff --git a/sm/encrypt.c b/sm/encrypt.c index 6e78a0620..923fdfd99 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -574,7 +574,8 @@ encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread) recipients are take from the certificate given in recplist; if this is NULL it will be encrypted for a default recipient */ int -gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) +gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, estream_t data_fp, + estream_t out_fp) { int rc = 0; gnupg_ksba_io_t b64writer = NULL; @@ -587,7 +588,6 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) struct encrypt_cb_parm_s encparm; DEK dek = NULL; int recpno; - estream_t data_fp = NULL; certlist_t cl; int count; int compliant; @@ -623,15 +623,6 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) goto leave; } - /* Fixme: We should use the unlocked version of the es functions. */ - data_fp = es_fdopen_nc (data_fd, "rb"); - if (!data_fp) - { - rc = gpg_error_from_syserror (); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - err = ksba_reader_new (&reader); if (err) rc = err; @@ -863,7 +854,6 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) ksba_reader_release (reader); keydb_release (kh); xfree (dek); - es_fclose (data_fp); xfree (encparm.buffer); return rc; } diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 0b69e6d62..20b574377 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -535,7 +535,6 @@ static void set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd ); static void emergency_cleanup (void); -static int open_read (const char *filename); static estream_t open_es_fread (const char *filename, const char *mode); static estream_t open_es_fwrite (const char *filename); static void run_protect_tool (int argc, char **argv); @@ -1778,7 +1777,7 @@ main ( int argc, char **argv) { log_info (_("importing common certificates '%s'\n"), filelist[0]); - gpgsm_import_files (&ctrl, 1, filelist, open_read); + gpgsm_import_files (&ctrl, 1, filelist, open_es_fread); } xfree (filelist[0]); } @@ -1916,9 +1915,20 @@ main ( int argc, char **argv) set_binary (stdin); if (!argc) /* Source is stdin. */ - err = gpgsm_encrypt (&ctrl, recplist, 0, fp); + err = gpgsm_encrypt (&ctrl, recplist, es_stdin, fp); else if (argc == 1) /* Source is the given file. */ - err = gpgsm_encrypt (&ctrl, recplist, open_read (*argv), fp); + { + estream_t data_fp = es_fopen (*argv, "rb"); + + if (!data_fp) + { + log_error (_("can't open '%s': %s\n"), *argv, + strerror (errno)); + gpgsm_exit (2); + } + err = gpgsm_encrypt (&ctrl, recplist, data_fp, fp); + es_fclose (data_fp); + } else wrong_args ("--encrypt [datafile]"); @@ -1937,10 +1947,20 @@ main ( int argc, char **argv) signing because that is what gpg does.*/ set_binary (stdin); if (!argc) /* Create from stdin. */ - err = gpgsm_sign (&ctrl, signerlist, 0, detached_sig, fp); + err = gpgsm_sign (&ctrl, signerlist, es_stdin, detached_sig, fp); else if (argc == 1) /* From file. */ - err = gpgsm_sign (&ctrl, signerlist, - open_read (*argv), detached_sig, fp); + { + estream_t data_fp = es_fopen (*argv, "rb"); + + if (!data_fp) + { + log_error (_("can't open '%s': %s\n"), *argv, + strerror (errno)); + gpgsm_exit (2); + } + err = gpgsm_sign (&ctrl, signerlist, data_fp, detached_sig, fp); + es_fclose (data_fp); + } else wrong_args ("--sign [datafile]"); @@ -1981,11 +2001,43 @@ main ( int argc, char **argv) fp = open_es_fwrite (opt.outfile); if (!argc) - gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */ + /* normal signature from stdin */ + gpgsm_verify (&ctrl, es_stdin, NULL, fp); else if (argc == 1) - gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */ + { + estream_t in_fp = es_fopen (*argv, "rb"); + + if (!in_fp) + { + log_error (_("can't open '%s': %s\n"), *argv, + strerror (errno)); + gpgsm_exit (2); + } + gpgsm_verify (&ctrl, in_fp, NULL, fp); /* std signature */ + es_fclose (in_fp); + } else if (argc == 2) /* detached signature (sig, detached) */ - gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); + { + estream_t in_fp = es_fopen (*argv, "rb"); + estream_t data_fp = es_fopen (argv[1], "rb"); + + if (!in_fp) + { + log_error (_("can't open '%s': %s\n"), *argv, + strerror (errno)); + gpgsm_exit (2); + } + if (!data_fp) + { + log_error (_("can't open '%s': %s\n"), argv[1], + strerror (errno)); + gpgsm_exit (2); + } + + gpgsm_verify (&ctrl, in_fp, data_fp, NULL); + es_fclose (in_fp); + es_fclose (data_fp); + } else wrong_args ("--verify [signature [detached_data]]"); @@ -1999,9 +2051,19 @@ main ( int argc, char **argv) set_binary (stdin); if (!argc) - err = gpgsm_decrypt (&ctrl, 0, fp); /* from stdin */ + err = gpgsm_decrypt (&ctrl, es_stdin, fp); /* from stdin */ else if (argc == 1) - err = gpgsm_decrypt (&ctrl, open_read (*argv), fp); /* from file */ + { + estream_t data_fp = es_fopen (*argv, "rb"); + if (!data_fp) + { + log_error (_("can't open '%s': %s\n"), *argv, + strerror (errno)); + gpgsm_exit (2); + } + err = gpgsm_decrypt (&ctrl, data_fp, fp); /* from file */ + es_fclose (data_fp); + } else wrong_args ("--decrypt [filename]"); @@ -2092,7 +2154,7 @@ main ( int argc, char **argv) case aImport: - gpgsm_import_files (&ctrl, argc, argv, open_read); + gpgsm_import_files (&ctrl, argc, argv, open_es_fread); break; case aExport: @@ -2293,46 +2355,20 @@ gpgsm_parse_validation_model (const char *model) } - -/* Open the FILENAME for read and return the file descriptor. Stop - with an error message in case of problems. "-" denotes stdin and - if special filenames are allowed the given fd is opened instead. */ -static int -open_read (const char *filename) -{ - int fd; - - if (filename[0] == '-' && !filename[1]) - { - set_binary (stdin); - return 0; /* stdin */ - } - fd = check_special_filename (filename, 0, 0); - if (fd != -1) - return fd; - fd = gnupg_open (filename, O_RDONLY | O_BINARY, 0); - if (fd == -1) - { - log_error (_("can't open '%s': %s\n"), filename, strerror (errno)); - gpgsm_exit (2); - } - return fd; -} - /* Same as open_read but return an estream_t. */ static estream_t open_es_fread (const char *filename, const char *mode) { - int fd; + gnupg_fd_t fd; estream_t fp; if (filename[0] == '-' && !filename[1]) return es_fpopen_nc (stdin, mode); else - fd = check_special_filename (filename, 0, 0); - if (fd != -1) + fd = gnupg_check_special_filename (filename); + if (fd != GNUPG_INVALID_FD) { - fp = es_fdopen_nc (fd, mode); + fp = open_stream_nc (fd, mode); if (!fp) { log_error ("es_fdopen(%d) failed: %s\n", FD_DBG (fd), diff --git a/sm/gpgsm.h b/sm/gpgsm.h index e1aca8bb7..93a80631f 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -426,9 +426,9 @@ gpg_error_t gpgsm_show_certs (ctrl_t ctrl, int nfiles, char **files, estream_t fp); /*-- import.c --*/ -int gpgsm_import (ctrl_t ctrl, int in_fd, int reimport_mode); +int gpgsm_import (ctrl_t ctrl, estream_t in_fp, int reimport_mode); int gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files, - int (*of)(const char *fname)); + estream_t (*of)(const char *fname, const char *mode)); /*-- export.c --*/ void gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream); @@ -439,23 +439,24 @@ void gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int gpgsm_delete (ctrl_t ctrl, strlist_t names); /*-- verify.c --*/ -int gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp); +int gpgsm_verify (ctrl_t ctrl, estream_t in_fp, estream_t data_fp, + estream_t out_fp); /*-- sign.c --*/ int gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert); int gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, - int data_fd, int detached, estream_t out_fp); + estream_t data_fp, int detached, estream_t out_fp); /*-- encrypt.c --*/ int gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, - int in_fd, estream_t out_fp); + estream_t in_fp, estream_t out_fp); /*-- decrypt.c --*/ gpg_error_t ecdh_derive_kek (unsigned char *key, unsigned int keylen, int hash_algo, const char *wrap_algo_str, const void *secret, unsigned int secretlen, const void *ukm, unsigned int ukmlen); -int gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp); +int gpgsm_decrypt (ctrl_t ctrl, estream_t in_fp, estream_t out_fp); /*-- certreqgen.c --*/ int gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, estream_t out_stream); diff --git a/sm/import.c b/sm/import.c index 5a193ef52..cd28cfbff 100644 --- a/sm/import.c +++ b/sm/import.c @@ -37,6 +37,10 @@ #include "../common/membuf.h" #include "minip12.h" +#ifndef O_BINARY +#define O_BINARY 0 +#endif + /* The arbitrary limit of one PKCS#12 object. */ #define MAX_P12OBJ_SIZE 128 /*kb*/ @@ -269,25 +273,16 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats, static int -import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) +import_one (ctrl_t ctrl, struct stats_s *stats, estream_t fp) { int rc; gnupg_ksba_io_t b64reader = NULL; ksba_reader_t reader; ksba_cert_t cert = NULL; ksba_cms_t cms = NULL; - estream_t fp = NULL; ksba_content_type_t ct; int any = 0; - fp = es_fdopen_nc (in_fd, "rb"); - if (!fp) - { - rc = gpg_error_from_syserror (); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - rc = gnupg_ksba_create_reader (&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0) | (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0) @@ -388,7 +383,6 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) ksba_cms_release (cms); ksba_cert_release (cert); gnupg_ksba_destroy_reader (b64reader); - es_fclose (fp); return rc; } @@ -398,10 +392,9 @@ import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) fingerprints t re-import. The actual re-import is done by clearing the ephemeral flag. */ static int -reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) +reimport_one (ctrl_t ctrl, struct stats_s *stats, estream_t fp) { gpg_error_t err = 0; - estream_t fp = NULL; char line[100]; /* Sufficient for a fingerprint. */ KEYDB_HANDLE kh; KEYDB_SEARCH_DESC desc; @@ -417,14 +410,6 @@ reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) } keydb_set_ephemeral (kh, 1); - fp = es_fdopen_nc (in_fd, "r"); - if (!fp) - { - err = gpg_error_from_syserror (); - log_error ("es_fdopen(%d) failed: %s\n", in_fd, gpg_strerror (err)); - goto leave; - } - while (es_fgets (line, DIM(line)-1, fp) ) { if (*line && line[strlen(line)-1] != '\n') @@ -500,30 +485,29 @@ reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) if (es_ferror (fp)) { err = gpg_error_from_syserror (); - log_error ("error reading fd %d: %s\n", in_fd, gpg_strerror (err)); + log_error ("error reading fp %p: %s\n", fp, gpg_strerror (err)); goto leave; } leave: ksba_cert_release (cert); keydb_release (kh); - es_fclose (fp); return err; } int -gpgsm_import (ctrl_t ctrl, int in_fd, int reimport_mode) +gpgsm_import (ctrl_t ctrl, estream_t in_fp, int reimport_mode) { int rc; struct stats_s stats; memset (&stats, 0, sizeof stats); if (reimport_mode) - rc = reimport_one (ctrl, &stats, in_fd); + rc = reimport_one (ctrl, &stats, in_fp); else - rc = import_one (ctrl, &stats, in_fd); + rc = import_one (ctrl, &stats, in_fp); print_imported_summary (ctrl, &stats); /* If we never printed an error message do it now so that a command line invocation will return with an error (log_error keeps a @@ -536,7 +520,7 @@ gpgsm_import (ctrl_t ctrl, int in_fd, int reimport_mode) int gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files, - int (*of)(const char *fname)) + estream_t (*of)(const char *fname, const char *mode)) { int rc = 0; struct stats_s stats; @@ -544,14 +528,19 @@ gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files, memset (&stats, 0, sizeof stats); if (!nfiles) - rc = import_one (ctrl, &stats, 0); + { +#ifdef HAVE_DOSISH_SYSTEM + setmode (0, O_BINARY); +#endif + rc = import_one (ctrl, &stats, es_stdin); + } else { for (; nfiles && !rc ; nfiles--, files++) { - int fd = of (*files); - rc = import_one (ctrl, &stats, fd); - close (fd); + estream_t fp = of (*files, "rb"); + rc = import_one (ctrl, &stats, fp); + es_fclose (fp); if (rc == -1/* legacy*/ || gpg_err_code (rc) == GPG_ERR_NOT_FOUND) rc = 0; } diff --git a/sm/server.c b/sm/server.c index 693932c2e..3ebf47299 100644 --- a/sm/server.c +++ b/sm/server.c @@ -43,7 +43,7 @@ static FILE *statusfp; /* Data used to assuciate an Assuan context with local server data */ struct server_local_s { assuan_context_t assuan_ctx; - int message_fd; + estream_t message_fp; int list_internal; int list_external; int list_to_output; /* Write keylistings to the output fd. */ @@ -130,12 +130,12 @@ data_line_cookie_close (void *cookie) static void -close_message_fd (ctrl_t ctrl) +close_message_fp (ctrl_t ctrl) { - if (ctrl->server_local->message_fd != -1) + if (ctrl->server_local->message_fp) { - close (ctrl->server_local->message_fd); - ctrl->server_local->message_fd = -1; + es_fclose (ctrl->server_local->message_fp); + ctrl->server_local->message_fp = NULL; } } @@ -320,7 +320,7 @@ reset_notify (assuan_context_t ctx, char *line) gpgsm_release_certlist (ctrl->server_local->signerlist); ctrl->server_local->recplist = NULL; ctrl->server_local->signerlist = NULL; - close_message_fd (ctrl); + close_message_fp (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); return 0; @@ -451,20 +451,25 @@ cmd_encrypt (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); certlist_t cl; - int inp_fd; + gnupg_fd_t inp_fd; gnupg_fd_t out_fd; + estream_t inp_fp; estream_t out_fp; int rc; (void)line; - inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); - if (inp_fd == -1) + inp_fd = assuan_get_input_fd (ctx); + if (inp_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); out_fd = assuan_get_output_fd (ctx); if (out_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); + inp_fp = open_stream_nc (inp_fd, "r"); + if (!inp_fp) + return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); + out_fp = open_stream_nc (out_fd, "w"); if (!out_fp) return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); @@ -484,13 +489,14 @@ cmd_encrypt (assuan_context_t ctx, char *line) if (!rc) rc = gpgsm_encrypt (assuan_get_pointer (ctx), ctrl->server_local->recplist, - inp_fd, out_fp); + inp_fp, out_fp); + es_fclose (inp_fp); es_fclose (out_fp); gpgsm_release_certlist (ctrl->server_local->recplist); ctrl->server_local->recplist = NULL; - /* Close and reset the fd */ - close_message_fd (ctrl); + /* Close and reset the fp and the fds */ + close_message_fp (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); return rc; @@ -509,31 +515,37 @@ static gpg_error_t cmd_decrypt (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - int inp_fd; + gnupg_fd_t inp_fd; gnupg_fd_t out_fd; + estream_t inp_fp; estream_t out_fp; int rc; (void)line; - inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); - if (inp_fd == -1) + inp_fd = assuan_get_input_fd (ctx); + if (inp_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); out_fd = assuan_get_output_fd (ctx); if (out_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL); + inp_fp = open_stream_nc (inp_fd, "r"); + if (!inp_fp) + return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); + out_fp = open_stream_nc (out_fd, "w"); if (!out_fp) return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); rc = start_audit_session (ctrl); if (!rc) - rc = gpgsm_decrypt (ctrl, inp_fd, out_fp); + rc = gpgsm_decrypt (ctrl, inp_fp, out_fp); + es_fclose (inp_fp); es_fclose (out_fp); /* Close and reset the fds. */ - close_message_fd (ctrl); + close_message_fp (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); @@ -555,15 +567,20 @@ cmd_verify (assuan_context_t ctx, char *line) { int rc; ctrl_t ctrl = assuan_get_pointer (ctx); - int fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); + gnupg_fd_t fd = assuan_get_input_fd (ctx); gnupg_fd_t out_fd = assuan_get_output_fd (ctx); + estream_t fp = NULL; estream_t out_fp = NULL; (void)line; - if (fd == -1) + if (fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); + fp = open_stream_nc (fd, "r"); + if (!fp) + return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); + if (out_fd != GNUPG_INVALID_FD) { out_fp = open_stream_nc (out_fd, "w"); @@ -573,12 +590,13 @@ cmd_verify (assuan_context_t ctx, char *line) rc = start_audit_session (ctrl); if (!rc) - rc = gpgsm_verify (assuan_get_pointer (ctx), fd, - ctrl->server_local->message_fd, out_fp); + rc = gpgsm_verify (assuan_get_pointer (ctx), fp, + ctrl->server_local->message_fp, out_fp); + es_fclose (fp); es_fclose (out_fp); - /* Close and reset the fd. */ - close_message_fd (ctrl); + /* Close and reset the fp and the fd. */ + close_message_fp (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); @@ -596,14 +614,15 @@ static gpg_error_t cmd_sign (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - int inp_fd; + gnupg_fd_t inp_fd; gnupg_fd_t out_fd; + estream_t inp_fp; estream_t out_fp; int detached; int rc; - inp_fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); - if (inp_fd == -1) + inp_fd = assuan_get_input_fd (ctx); + if (inp_fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); out_fd = assuan_get_output_fd (ctx); if (out_fd == GNUPG_INVALID_FD) @@ -611,6 +630,10 @@ cmd_sign (assuan_context_t ctx, char *line) detached = has_option (line, "--detached"); + inp_fp = open_stream_nc (inp_fd, "r"); + if (!inp_fp) + return set_error (gpg_err_code_from_syserror (), "fdopen() failed"); + out_fp = open_stream_nc (out_fd, "w"); if (!out_fp) return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed"); @@ -618,11 +641,12 @@ cmd_sign (assuan_context_t ctx, char *line) rc = start_audit_session (ctrl); if (!rc) rc = gpgsm_sign (assuan_get_pointer (ctx), ctrl->server_local->signerlist, - inp_fd, detached, out_fp); + inp_fp, detached, out_fp); + es_fclose (inp_fp); es_fclose (out_fp); - /* close and reset the fd */ - close_message_fd (ctrl); + /* close and reset the fp and the fds */ + close_message_fp (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); @@ -647,18 +671,24 @@ cmd_import (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int rc; - int fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); + gnupg_fd_t fd = assuan_get_input_fd (ctx); int reimport = has_option (line, "--re-import"); + estream_t fp; (void)line; - if (fd == -1) + if (fd == GNUPG_INVALID_FD) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - rc = gpgsm_import (assuan_get_pointer (ctx), fd, reimport); + fp = open_stream_nc (fd, "r"); + if (!fp) + return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - /* close and reset the fd */ - close_message_fd (ctrl); + rc = gpgsm_import (assuan_get_pointer (ctx), fp, reimport); + es_fclose (fp); + + /* close and reset the fp and the fds */ + close_message_fp (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); @@ -783,8 +813,8 @@ cmd_export (assuan_context_t ctx, char *line) } free_strlist (list); - /* Close and reset the fds. */ - close_message_fd (ctrl); + /* Close and reset the fp and the fds. */ + close_message_fp (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); return 0; @@ -832,8 +862,8 @@ cmd_delkeys (assuan_context_t ctx, char *line) rc = gpgsm_delete (ctrl, list); free_strlist (list); - /* close and reset the fd */ - close_message_fd (ctrl); + /* close and reset the fp and the fds */ + close_message_fp (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); @@ -867,19 +897,18 @@ static gpg_error_t cmd_message (assuan_context_t ctx, char *line) { int rc; - gnupg_fd_t sysfd; - int fd; + gnupg_fd_t fd; + estream_t fp; ctrl_t ctrl = assuan_get_pointer (ctx); - rc = assuan_command_parse_fd (ctx, line, &sysfd); + rc = assuan_command_parse_fd (ctx, line, &fd); if (rc) return rc; - - fd = translate_sys2libc_fd (sysfd, 0); - if (fd == -1) + fp = open_stream_nc (fd, "r"); + if (!fp) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - ctrl->server_local->message_fd = fd; + ctrl->server_local->message_fp = fp; return 0; } @@ -1425,7 +1454,7 @@ gpgsm_server (certlist_t default_recplist) assuan_set_pointer (ctx, &ctrl); ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); ctrl.server_local->assuan_ctx = ctx; - ctrl.server_local->message_fd = -1; + ctrl.server_local->message_fp = NULL; ctrl.server_local->list_internal = 1; ctrl.server_local->list_external = 0; ctrl.server_local->default_recplist = default_recplist; diff --git a/sm/sign.c b/sm/sign.c index 235dac8cb..39ff2b58f 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -40,20 +40,12 @@ /* Hash the data and return if something was hashed. Return -1 on error. */ static int -hash_data (int fd, gcry_md_hd_t md) +hash_data (estream_t fp, gcry_md_hd_t md) { - estream_t fp; char buffer[4096]; int nread; int rc = 0; - fp = es_fdopen_nc (fd, "rb"); - if (!fp) - { - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return -1; - } - do { nread = es_fread (buffer, 1, DIM(buffer), fp); @@ -62,32 +54,22 @@ hash_data (int fd, gcry_md_hd_t md) while (nread); if (es_ferror (fp)) { - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); + log_error ("read error on fd %p: %s\n", fp, strerror (errno)); rc = -1; } - es_fclose (fp); return rc; } static int -hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer) +hash_and_copy_data (estream_t fp, gcry_md_hd_t md, ksba_writer_t writer) { gpg_error_t err; - estream_t fp; char buffer[4096]; int nread; int rc = 0; int any = 0; - fp = es_fdopen_nc (fd, "rb"); - if (!fp) - { - gpg_error_t tmperr = gpg_error_from_syserror (); - log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno)); - return tmperr; - } - do { nread = es_fread (buffer, 1, DIM(buffer), fp); @@ -107,9 +89,9 @@ hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer) if (es_ferror (fp)) { rc = gpg_error_from_syserror (); - log_error ("read error on fd %d: %s\n", fd, strerror (errno)); + log_error ("read error on fp %p: %s\n", fp, strerror (errno)); } - es_fclose (fp); + if (!any) { /* We can't allow signing an empty message because it does not @@ -622,7 +604,7 @@ write_detached_signature (ctrl_t ctrl, const void *blob, size_t bloblen, be used if the value of this argument is NULL. */ int gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, - int data_fd, int detached, estream_t out_fp) + estream_t data_fp, int detached, estream_t out_fp) { int i, rc; gpg_error_t err; @@ -959,7 +941,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, unsigned char *digest; size_t digest_len; - if (!hash_data (data_fd, data_md)) + if (!hash_data (data_fp, data_md)) audit_log (ctrl->audit, AUDIT_GOT_DATA); for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) { @@ -1044,7 +1026,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, log_assert (!detached); - rc = hash_and_copy_data (data_fd, data_md, writer); + rc = hash_and_copy_data (data_fp, data_md, writer); if (rc) goto leave; audit_log (ctrl->audit, AUDIT_GOT_DATA); diff --git a/sm/verify.c b/sm/verify.c index c7f4492ce..de407bf16 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -53,21 +53,12 @@ strtimestamp_r (ksba_isotime_t atime) /* Hash the data for a detached signature. Returns 0 on success. */ static gpg_error_t -hash_data (int fd, gcry_md_hd_t md) +hash_data (estream_t fp, gcry_md_hd_t md) { gpg_error_t err = 0; - estream_t fp; char buffer[4096]; int nread; - fp = es_fdopen_nc (fd, "rb"); - if (!fp) - { - err = gpg_error_from_syserror (); - log_error ("fdopen(%d) failed: %s\n", fd, gpg_strerror (err)); - return err; - } - do { nread = es_fread (buffer, 1, DIM(buffer), fp); @@ -77,20 +68,20 @@ hash_data (int fd, gcry_md_hd_t md) if (es_ferror (fp)) { err = gpg_error_from_syserror (); - log_error ("read error on fd %d: %s\n", fd, gpg_strerror (err)); + log_error ("read error on fp %p: %s\n", fp, gpg_strerror (err)); } - es_fclose (fp); return err; } -/* Perform a verify operation. To verify detached signatures, DATA_FD - must be different than -1. With OUT_FP given and a non-detached +/* Perform a verify operation. To verify detached signatures, DATA_FP + must be different than NULL. With OUT_FP given and a non-detached signature, the signed material is written to that stream. */ int -gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) +gpgsm_verify (ctrl_t ctrl, estream_t in_fp, estream_t data_fp, + estream_t out_fp) { int i, rc; gnupg_ksba_io_t b64reader = NULL; @@ -106,7 +97,6 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) const char *algoid; int algo; int is_detached, maybe_detached; - estream_t in_fp = NULL; char *p; audit_set_type (ctrl->audit, AUDIT_TYPE_VERIFY); @@ -114,7 +104,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) /* Although we detect detached signatures during the parsing phase, * we need to know it earlier and thus accept the caller idea of * what to verify. */ - maybe_detached = (data_fd != -1); + maybe_detached = (data_fp != NULL); kh = keydb_new (ctrl); if (!kh) @@ -125,14 +115,6 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) } - in_fp = es_fdopen_nc (in_fd, "rb"); - if (!in_fp) - { - rc = gpg_error_from_syserror (); - log_error ("fdopen() failed: %s\n", strerror (errno)); - goto leave; - } - rc = gnupg_ksba_create_reader (&b64reader, ((ctrl->is_pem? GNUPG_KSBA_IO_PEM : 0) | (ctrl->is_base64? GNUPG_KSBA_IO_BASE64 : 0) @@ -242,7 +224,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) } if (is_detached) { - if (data_fd == -1) + if (!data_fp) { log_info ("detached signature w/o data " "- assuming certs-only\n"); @@ -250,7 +232,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) } else audit_log_ok (ctrl->audit, AUDIT_DATA_HASHING, - hash_data (data_fd, data_md)); + hash_data (data_fp, data_md)); } else { @@ -275,7 +257,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) } } - if (data_fd != -1 && !is_detached) + if (data_fp && !is_detached) { log_error ("data given for a non-detached signature\n"); rc = gpg_error (GPG_ERR_CONFLICT); @@ -315,7 +297,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) rc = ksba_cms_get_issuer_serial (cms, signer, &issuer, &serial); if (!signer && gpg_err_code (rc) == GPG_ERR_NO_DATA - && data_fd == -1 && is_detached) + && !data_fp && is_detached) { log_info ("certs-only message accepted\n"); rc = 0; @@ -748,7 +730,6 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) gnupg_ksba_destroy_writer (b64writer); keydb_release (kh); gcry_md_close (data_md); - es_fclose (in_fp); if (rc) { From 2258bcded654fc970a747627c4f560a8b03cc5e8 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 12 Jul 2023 13:34:19 +0900 Subject: [PATCH 146/869] gpg: Fix expiration time when Creation-Date is specified. * g10/keygen.c (parse_expire_string_with_ct): New function, optionally supply the creation time. (parse_expire_string): Use parse_expire_string_with_ct with no creation time. (proc_parameter_file): Use parse_expire_string_with_ct possibly with the creation time. -- Cherry-pick from master commit of: b07b5144ff6a9208ea27fe1e1518270bd22b382c GnuPG-bug-id: 5252 Signed-off-by: NIIBE Yutaka --- g10/keygen.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index d5099dbb9..608867cfa 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2740,14 +2740,19 @@ ask_curve (int *algo, int *subkey_algo, const char *current) * just cope for the next few years until we get a 64-bit time_t or * similar. */ -u32 -parse_expire_string( const char *string ) +static u32 +parse_expire_string_with_ct (const char *string, u32 creation_time) { int mult; u32 seconds; u32 abs_date = 0; - u32 curtime = make_timestamp (); time_t tt; + u32 curtime; + + if (creation_time == (u32)-1) + curtime = make_timestamp (); + else + curtime = creation_time; if (!string || !*string || !strcmp (string, "none") || !strcmp (string, "never") || !strcmp (string, "-")) @@ -2767,6 +2772,13 @@ parse_expire_string( const char *string ) return seconds; } +u32 +parse_expire_string ( const char *string ) +{ + return parse_expire_string_with_ct (string, (u32)-1); +} + + /* Parse a Creation-Date string which is either "1986-04-26" or "19860426T042640". Returns 0 on error. */ static u32 @@ -4130,6 +4142,7 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname, int is_default = 0; int have_user_id = 0; int err, algo; + u32 creation_time = (u32)-1; /* Check that we have all required parameters. */ r = get_parameter( para, pKEYTYPE ); @@ -4295,15 +4308,13 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname, if (r && *r->u.value && !(get_parameter_bool (para, pCARDKEY) && get_parameter_u32 (para, pKEYCREATIONDATE))) { - u32 seconds; - - seconds = parse_creation_string (r->u.value); - if (!seconds) + creation_time = parse_creation_string (r->u.value); + if (!creation_time) { log_error ("%s:%d: invalid creation date\n", fname, r->lnr ); return -1; } - r->u.creation = seconds; + r->u.creation = creation_time; r->key = pKEYCREATIONDATE; /* Change that entry. */ } @@ -4313,7 +4324,7 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname, { u32 seconds; - seconds = parse_expire_string( r->u.value ); + seconds = parse_expire_string_with_ct (r->u.value, creation_time); if( seconds == (u32)-1 ) { log_error("%s:%d: invalid expire date\n", fname, r->lnr ); From 96b69c1866dd960942c0c845ea3630f8884a8849 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 12 Jul 2023 14:04:28 +0900 Subject: [PATCH 147/869] gpg: Add support for Subkey-Expire-Date. * g10/keygen.c (enum para_name): Add pSUBKEYEXPIREDATE. (proc_parameter_file): Add support for pSUBKEYEXPIREDATE. (read_parameter_file): Add "Subkey-Expire-Date". -- Cherry-pick from master commit of: 23bcb78d279ebc81ec9340356401d19cf89985f1 Signed-off-by: NIIBE Yutaka --- g10/keygen.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 608867cfa..c252b0de4 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -87,6 +87,7 @@ enum para_name { pEXPIREDATE, pKEYEXPIRE, /* in n seconds */ pSUBKEYCREATIONDATE, + pSUBKEYEXPIREDATE, pSUBKEYEXPIRE, /* in n seconds */ pAUTHKEYCREATIONDATE, /* Not yet used. */ pPASSPHRASE, @@ -4331,12 +4332,29 @@ proc_parameter_file (ctrl_t ctrl, struct para_data_s *para, const char *fname, return -1; } r->u.expire = seconds; - r->key = pKEYEXPIRE; /* change hat entry */ - /* also set it for the subkey */ - r = xmalloc_clear( sizeof *r + 20 ); - r->key = pSUBKEYEXPIRE; - r->u.expire = seconds; - append_to_parameter (para, r); + r->key = pKEYEXPIRE; /* change that entry */ + + /* Make SUBKEYEXPIRE from Subkey-Expire-Date, if any. */ + r = get_parameter( para, pSUBKEYEXPIREDATE ); + if( r && *r->u.value ) + { + seconds = parse_expire_string_with_ct (r->u.value, creation_time); + if( seconds == (u32)-1 ) + { + log_error("%s:%d: invalid subkey expire date\n", fname, r->lnr ); + return -1; + } + r->key = pSUBKEYEXPIRE; /* change that entry */ + r->u.expire = seconds; + } + else + { + /* Or else, set Expire-Date for the subkey */ + r = xmalloc_clear( sizeof *r + 20 ); + r->key = pSUBKEYEXPIRE; + r->u.expire = seconds; + append_to_parameter (para, r); + } } do_generate_keypair (ctrl, para, outctrl, card ); @@ -4367,6 +4385,7 @@ read_parameter_file (ctrl_t ctrl, const char *fname ) { "Name-Email", pNAMEEMAIL }, { "Name-Comment", pNAMECOMMENT }, { "Expire-Date", pEXPIREDATE }, + { "Subkey-Expire-Date", pSUBKEYEXPIREDATE }, { "Creation-Date", pCREATIONDATE }, { "Passphrase", pPASSPHRASE }, { "Preferences", pPREFERENCES }, From 1ddd69935da629188dcf9215cd9e7a8f68b34a97 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 25 Jul 2023 12:02:26 +0900 Subject: [PATCH 148/869] gpg: Add parallelized filter for hashing. * g10/options.h (COMPAT_PARALLELIZED): New. * g10/filter.h (md_thd_filter_context_t): New type. (md_thd_filter_set_md, md_thd_filter): New. * g10/gpg.c (compatibility_flags): Update to support COMPAT_PARALLELIZED. * g10/mdfilter.c (struct md_thd_filter_context): New. (lock_md, unlock_md, get_buffer_to_hash, put_buffer_to_recv): New. (get_buffer_to_fill, put_buffer_to_send, md_thread): New. (md_thd_filter, md_thd_filter_set_md): New. * g10/sign.c (sign_file): Add support for md_thd_filter. (sign_symencrypt_file): Likewise. -- GnuPG-bug-id: 6570 Signed-off-by: NIIBE Yutaka --- g10/filter.h | 4 + g10/gpg.c | 1 + g10/mdfilter.c | 295 +++++++++++++++++++++++++++++++++++++++++++++++++ g10/options.h | 4 +- g10/sign.c | 64 ++++++++--- 5 files changed, 352 insertions(+), 16 deletions(-) diff --git a/g10/filter.h b/g10/filter.h index 4b4fc55ff..321b553dc 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -29,6 +29,9 @@ typedef struct { size_t maxbuf_size; } md_filter_context_t; +typedef struct md_thd_filter_context *md_thd_filter_context_t; +void md_thd_filter_set_md (md_thd_filter_context_t mfx, gcry_md_hd_t md); + typedef struct { int refcount; /* Initialized to 1. */ @@ -165,6 +168,7 @@ typedef struct { /*-- mdfilter.c --*/ int md_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len); +int md_thd_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len); void free_md_filter_context( md_filter_context_t *mfx ); /*-- armor.c --*/ diff --git a/g10/gpg.c b/g10/gpg.c index 23bf8d971..8b3d79e1e 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1027,6 +1027,7 @@ static struct debug_flags_s debug_flags [] = /* The list of compatibility flags. */ static struct compatibility_flags_s compatibility_flags [] = { + { COMPAT_PARALLELIZED, "parallelized" }, { 0, NULL } }; diff --git a/g10/mdfilter.c b/g10/mdfilter.c index f3318f15c..a655d6d72 100644 --- a/g10/mdfilter.c +++ b/g10/mdfilter.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "gpg.h" #include "../common/status.h" @@ -71,3 +72,297 @@ free_md_filter_context( md_filter_context_t *mfx ) mfx->md2 = NULL; mfx->maxbuf_size = 0; } + + +/**************** + * Threaded implementation for hashing. + */ + +struct md_thd_filter_context { + gcry_md_hd_t md; + npth_t thd; + /**/ + npth_mutex_t mutex; + npth_cond_t cond; + size_t bufsize; + unsigned int produce : 1; + unsigned int consume : 1; + ssize_t written0; + ssize_t written1; + unsigned char buf[1]; +}; + + +static void +lock_md (struct md_thd_filter_context *mfx) +{ + int rc = npth_mutex_lock (&mfx->mutex); + if (rc) + log_fatal ("%s: failed to acquire mutex: %s\n", __func__, + gpg_strerror (gpg_error_from_errno (rc))); +} + + +static void +unlock_md (struct md_thd_filter_context * mfx) +{ + int rc = npth_mutex_unlock (&mfx->mutex); + if (rc) + log_fatal ("%s: failed to release mutex: %s\n", __func__, + gpg_strerror (gpg_error_from_errno (rc))); +} + +static int +get_buffer_to_hash (struct md_thd_filter_context *mfx, + unsigned char **r_buf, size_t *r_len) +{ + int rc = 0; + + lock_md (mfx); + + if ((mfx->consume == 0 && mfx->written0 < 0) + || (mfx->consume != 0 && mfx->written1 < 0)) + { + rc = npth_cond_wait (&mfx->cond, &mfx->mutex); + if (rc) + { + unlock_md (mfx); + return -1; + } + } + + if (mfx->consume == 0) + { + *r_buf = mfx->buf; + *r_len = mfx->written0; + } + else + { + *r_buf = mfx->buf + mfx->bufsize; + *r_len = mfx->written1; + } + + unlock_md (mfx); + + return 0; +} + +static int +put_buffer_to_recv (struct md_thd_filter_context *mfx) +{ + int rc = 0; + + lock_md (mfx); + if (mfx->consume == 0) + { + mfx->written0 = -1; + mfx->consume = 1; + } + else + { + mfx->written1 = -1; + mfx->consume = 0; + } + + rc = npth_cond_signal (&mfx->cond); + if (rc) + { + unlock_md (mfx); + return -1; + } + + unlock_md (mfx); + return 0; +} + +static int +get_buffer_to_fill (struct md_thd_filter_context *mfx, + unsigned char **r_buf, size_t len) +{ + lock_md (mfx); + + if (len > mfx->bufsize) + { + unlock_md (mfx); + return GPG_ERR_BUFFER_TOO_SHORT; + } + + if ((mfx->produce == 0 && mfx->written0 >= 0) + || (mfx->produce != 0 && mfx->written1 >= 0)) + { + int rc = npth_cond_wait (&mfx->cond, &mfx->mutex); + if (rc) + { + unlock_md (mfx); + return gpg_error_from_errno (rc); + } + } + + if (mfx->produce == 0) + *r_buf = mfx->buf; + else + *r_buf = mfx->buf + mfx->bufsize; + unlock_md (mfx); + return 0; +} + +static int +put_buffer_to_send (struct md_thd_filter_context *mfx, size_t len) +{ + int rc; + + lock_md (mfx); + if (mfx->produce == 0) + { + mfx->written0 = len; + mfx->produce = 1; + } + else + { + mfx->written1 = len; + mfx->produce = 0; + } + + rc = npth_cond_signal (&mfx->cond); + if (rc) + { + unlock_md (mfx); + return gpg_error_from_errno (rc); + } + + unlock_md (mfx); + + /* Yield to the md_thread to let it compute the hash in parallel */ + npth_usleep (0); + return 0; +} + + +static void * +md_thread (void *arg) +{ + struct md_thd_filter_context *mfx = arg; + + while (1) + { + unsigned char *buf; + size_t len; + + if (get_buffer_to_hash (mfx, &buf, &len) < 0) + /* Error */ + return NULL; + + if (len == 0) + break; + + npth_unprotect (); + gcry_md_write (mfx->md, buf, len); + npth_protect (); + + if (put_buffer_to_recv (mfx) < 0) + /* Error */ + return NULL; + } + + return NULL; +} + +int +md_thd_filter (void *opaque, int control, + IOBUF a, byte *buf, size_t *ret_len) +{ + size_t size = *ret_len; + struct md_thd_filter_context **r_mfx = opaque; + struct md_thd_filter_context *mfx = *r_mfx; + int rc=0; + + if (control == IOBUFCTRL_INIT) + { + npth_attr_t tattr; + size_t n; + + n = 2 * iobuf_set_buffer_size (0) * 1024; + mfx = xtrymalloc (n + offsetof (struct md_thd_filter_context, buf)); + if (!mfx) + return gpg_error_from_syserror (); + *r_mfx = mfx; + mfx->bufsize = n / 2; + mfx->consume = mfx->produce = 0; + mfx->written0 = -1; + mfx->written1 = -1; + + rc = npth_mutex_init (&mfx->mutex, NULL); + if (rc) + { + return gpg_error_from_errno (rc); + } + rc = npth_cond_init (&mfx->cond, NULL); + if (rc) + { + npth_mutex_destroy (&mfx->mutex); + return gpg_error_from_errno (rc); + } + rc = npth_attr_init (&tattr); + if (rc) + { + npth_cond_destroy (&mfx->cond); + npth_mutex_destroy (&mfx->mutex); + return gpg_error_from_errno (rc); + } + npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE); + rc = npth_create (&mfx->thd, &tattr, md_thread, mfx); + if (rc) + { + npth_cond_destroy (&mfx->cond); + npth_mutex_destroy (&mfx->mutex); + npth_attr_destroy (&tattr); + return gpg_error_from_errno (rc); + } + npth_attr_destroy (&tattr); + } + else if (control == IOBUFCTRL_UNDERFLOW) + { + int i; + unsigned char *md_buf = NULL; + + i = iobuf_read (a, buf, size); + if (i == -1) + i = 0; + + rc = get_buffer_to_fill (mfx, &md_buf, i); + if (rc) + return rc; + + if (i) + memcpy (md_buf, buf, i); + + rc = put_buffer_to_send (mfx, i); + if (rc) + return rc; + + if (i == 0) + { + npth_join (mfx->thd, NULL); + rc = -1; /* eof */ + } + + *ret_len = i; + } + else if (control == IOBUFCTRL_FREE) + { + npth_cond_destroy (&mfx->cond); + npth_mutex_destroy (&mfx->mutex); + xfree (mfx); + *r_mfx = NULL; + } + else if (control == IOBUFCTRL_DESC) + mem2str (buf, "md_thd_filter", *ret_len); + + return rc; +} + +void +md_thd_filter_set_md (struct md_thd_filter_context *mfx, gcry_md_hd_t md) +{ + mfx->md = md; +} diff --git a/g10/options.h b/g10/options.h index 914c24849..327a6a06f 100644 --- a/g10/options.h +++ b/g10/options.h @@ -373,7 +373,9 @@ EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode; EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; /* Compatibility flags */ -/* #define COMPAT_FOO 1 */ +#define COMPAT_PARALLELIZED 1 + +/* #define COMPAT_FOO 2 */ /* Compliance test macors. */ diff --git a/g10/sign.c b/g10/sign.c index 5588557c8..f68ea3bc7 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1020,7 +1020,9 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, const char *fname; armor_filter_context_t *afx; compress_filter_context_t zfx; + gcry_md_hd_t md; md_filter_context_t mfx; + md_thd_filter_context_t mfx2 = NULL; text_filter_context_t tfx; progress_filter_context_t *pfx; encrypt_filter_context_t efx; @@ -1126,10 +1128,10 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, iobuf_push_filter (inp, text_filter, &tfx); } - if (gcry_md_open (&mfx.md, 0, 0)) + if (gcry_md_open (&md, 0, 0)) BUG (); if (DBG_HASHING) - gcry_md_debug (mfx.md, "sign"); + gcry_md_debug (md, "sign"); /* If we're encrypting and signing, it is reasonable to pick the * hash algorithm to use out of the recipient key prefs. This is @@ -1226,10 +1228,21 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, } for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) - gcry_md_enable (mfx.md, hash_for (sk_rover->pk)); + gcry_md_enable (md, hash_for (sk_rover->pk)); if (!multifile) - iobuf_push_filter (inp, md_filter, &mfx); + { + if (encryptflag && (opt.compat_flags & COMPAT_PARALLELIZED)) + { + iobuf_push_filter (inp, md_thd_filter, &mfx2); + md_thd_filter_set_md (mfx2, md); + } + else + { + iobuf_push_filter (inp, md_filter, &mfx); + mfx.md = md; + } + } if (detached && !encryptflag) afx->what = 2; @@ -1292,7 +1305,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, goto leave; } - write_status_begin_signing (mfx.md); + write_status_begin_signing (md); /* Setup the inner packet. */ if (detached) @@ -1332,7 +1345,16 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, memset (&tfx, 0, sizeof tfx); iobuf_push_filter (inp, text_filter, &tfx); } - iobuf_push_filter (inp, md_filter, &mfx); + if (encryptflag && (opt.compat_flags & COMPAT_PARALLELIZED)) + { + iobuf_push_filter (inp, md_thd_filter, &mfx2); + md_thd_filter_set_md (mfx2, md); + } + else + { + iobuf_push_filter (inp, md_filter, &mfx); + mfx.md = md; + } while (iobuf_read (inp, NULL, iobuf_size) != -1) ; iobuf_close (inp); @@ -1361,7 +1383,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, goto leave; /* Write the signatures. */ - rc = write_signature_packets (ctrl, sk_list, out, mfx.md, extrahash, + rc = write_signature_packets (ctrl, sk_list, out, md, extrahash, opt.textmode && !outfile? 0x01 : 0x00, 0, duration, detached ? 'D':'S', NULL); if (rc) @@ -1378,7 +1400,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, write_status (STATUS_END_ENCRYPTION); } iobuf_close (inp); - gcry_md_close (mfx.md); + gcry_md_close (md); release_sk_list (sk_list); release_pk_list (pk_list); recipient_digest_algo = 0; @@ -1561,6 +1583,8 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) progress_filter_context_t *pfx; compress_filter_context_t zfx; md_filter_context_t mfx; + md_thd_filter_context_t mfx2 = NULL; + gcry_md_hd_t md; text_filter_context_t tfx; cipher_filter_context_t cfx; iobuf_t inp = NULL; @@ -1644,15 +1668,25 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) /* Prepare to calculate the MD over the input. */ if (opt.textmode) iobuf_push_filter (inp, text_filter, &tfx); - if (gcry_md_open (&mfx.md, 0, 0)) + if (gcry_md_open (&md, 0, 0)) BUG (); if (DBG_HASHING) - gcry_md_debug (mfx.md, "symc-sign"); + gcry_md_debug (md, "symc-sign"); for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) - gcry_md_enable (mfx.md, hash_for (sk_rover->pk)); + gcry_md_enable (md, hash_for (sk_rover->pk)); + + if ((opt.compat_flags & COMPAT_PARALLELIZED)) + { + iobuf_push_filter (inp, md_thd_filter, &mfx2); + md_thd_filter_set_md (mfx2, md); + } + else + { + iobuf_push_filter (inp, md_filter, &mfx); + mfx.md = md; + } - iobuf_push_filter (inp, md_filter, &mfx); /* Push armor output filter */ if (opt.armor) @@ -1694,7 +1728,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) if (rc) goto leave; - write_status_begin_signing (mfx.md); + write_status_begin_signing (md); /* Pipe data through all filters; i.e. write the signed stuff. */ /* (current filters: zip - encrypt - armor) */ @@ -1706,7 +1740,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) /* Write the signatures. */ /* (current filters: zip - encrypt - armor) */ - rc = write_signature_packets (ctrl, sk_list, out, mfx.md, extrahash, + rc = write_signature_packets (ctrl, sk_list, out, md, extrahash, opt.textmode? 0x01 : 0x00, 0, duration, 'S', NULL); if (rc) @@ -1723,7 +1757,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) } iobuf_close (inp); release_sk_list (sk_list); - gcry_md_close (mfx.md); + gcry_md_close (md); xfree (cfx.dek); xfree (s2k); release_progress_context (pfx); From dad880155ed07bec6a64d792a52696277a7d0c83 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 26 Jul 2023 11:29:05 +0900 Subject: [PATCH 149/869] build: Update libassuan.m4 for API compatibility. * m4/libassuan.m4: Update from libassuan master. -- Signed-off-by: NIIBE Yutaka --- m4/libassuan.m4 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/m4/libassuan.m4 b/m4/libassuan.m4 index 79391bb4d..a2eb5d973 100644 --- a/m4/libassuan.m4 +++ b/m4/libassuan.m4 @@ -9,7 +9,7 @@ dnl This file is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dnl SPDX-License-Identifier: FSFULLR -# Last-changed: 2022-11-01 +# Last-changed: 2023-07-26 dnl dnl Common code used for libassuan detection [internal] @@ -89,6 +89,7 @@ AC_DEFUN([_AM_PATH_LIBASSUAN_COMMON], if test $ok = yes; then AC_MSG_RESULT([yes ($libassuan_config_version)]) + AC_DEFINE(LIBASSUAN_API_REQUESTED, $req_libassuan_api, Requested API version for libassuan) else AC_MSG_RESULT(no) fi @@ -104,6 +105,8 @@ AC_DEFUN([_AM_PATH_LIBASSUAN_COMMON], AC_MSG_CHECKING([LIBASSUAN API version]) if test "$req_libassuan_api" -eq "$tmp" ; then AC_MSG_RESULT(okay) + elif test "$req_libassuan_api" -eq 2 -a "$tmp" -eq 3; then + AC_MSG_RESULT(okay) else ok=no AC_MSG_RESULT([does not match. want=$req_libassuan_api got=$tmp.]) From fa29c86582487880364b710fd9679c8e77c8dce6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 2 Aug 2023 11:39:40 +0900 Subject: [PATCH 150/869] build: Update libassuan.m4 to allow build with libassuan 3. * m4/libassuan.m4: Update from libassuan master. -- Signed-off-by: NIIBE Yutaka --- m4/libassuan.m4 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/m4/libassuan.m4 b/m4/libassuan.m4 index 79391bb4d..a2eb5d973 100644 --- a/m4/libassuan.m4 +++ b/m4/libassuan.m4 @@ -9,7 +9,7 @@ dnl This file is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dnl SPDX-License-Identifier: FSFULLR -# Last-changed: 2022-11-01 +# Last-changed: 2023-07-26 dnl dnl Common code used for libassuan detection [internal] @@ -89,6 +89,7 @@ AC_DEFUN([_AM_PATH_LIBASSUAN_COMMON], if test $ok = yes; then AC_MSG_RESULT([yes ($libassuan_config_version)]) + AC_DEFINE(LIBASSUAN_API_REQUESTED, $req_libassuan_api, Requested API version for libassuan) else AC_MSG_RESULT(no) fi @@ -104,6 +105,8 @@ AC_DEFUN([_AM_PATH_LIBASSUAN_COMMON], AC_MSG_CHECKING([LIBASSUAN API version]) if test "$req_libassuan_api" -eq "$tmp" ; then AC_MSG_RESULT(okay) + elif test "$req_libassuan_api" -eq 2 -a "$tmp" -eq 3; then + AC_MSG_RESULT(okay) else ok=no AC_MSG_RESULT([does not match. want=$req_libassuan_api got=$tmp.]) From 0d20b79ab79819f6177737a61e886d4820e475e2 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 24 Jul 2023 13:49:51 +0900 Subject: [PATCH 151/869] build: Require libassuan 3.0.0 or later. * configure.ac (NEED_LIBASSUAN_API): Require the API version 3.0. (NEED_LIBASSUAN_VERSION): Require 3.0.0 or later. -- GnuPG-bug-id: 6606 Signed-off-by: NIIBE Yutaka --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 57bcdac4e..1729cf4f5 100644 --- a/configure.ac +++ b/configure.ac @@ -60,8 +60,8 @@ NEED_GPGRT_VERSION=1.46 NEED_LIBGCRYPT_API=1 NEED_LIBGCRYPT_VERSION=1.9.1 -NEED_LIBASSUAN_API=2 -NEED_LIBASSUAN_VERSION=2.5.0 +NEED_LIBASSUAN_API=3 +NEED_LIBASSUAN_VERSION=3.0.0 NEED_KSBA_API=1 NEED_KSBA_VERSION=1.6.3 From 5cad5f903e043a53538450eb38ab10965e455b40 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 24 Jul 2023 13:52:22 +0900 Subject: [PATCH 152/869] agent,dirmngr,kbx,scdaemon: Use assuan_sock_accept. * agent/gpg-agent.c (handle_connections): Use assuan_sock_accept. * dirmngr/dirmngr.c (handle_connections): Ditto. * kbx/keyboxd.c (handle_connections): Ditto. * scd/scdaemon.c (handle_connections): Ditto. * tpm2d/tpm2daemon.c (handle_connections): Ditto. -- GnuPG-bug-id: 6599 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 4 ++-- dirmngr/dirmngr.c | 4 ++-- kbx/keyboxd.c | 4 ++-- scd/scdaemon.c | 4 ++-- tpm2d/tpm2daemon.c | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 335d389c6..624d2972c 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -3222,8 +3222,8 @@ handle_connections (gnupg_fd_t listen_fd, continue; plen = sizeof paddr; - fd = INT2FD (npth_accept (FD2INT(listentbl[idx].l_fd), - (struct sockaddr *)&paddr, &plen)); + fd = assuan_sock_accept (listentbl[idx].l_fd, + (struct sockaddr *)&paddr, &plen); if (fd == GNUPG_INVALID_FD) { log_error ("accept failed for %s: %s\n", diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 9528ba91b..967281ede 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -2483,8 +2483,8 @@ handle_connections (assuan_fd_t listen_fd) gnupg_fd_t fd; plen = sizeof paddr; - fd = INT2FD (npth_accept (FD2INT(listen_fd), - (struct sockaddr *)&paddr, &plen)); + fd = assuan_sock_accept (listen_fd, + (struct sockaddr *)&paddr, &plen); if (fd == GNUPG_INVALID_FD) { log_error ("accept failed: %s\n", strerror (errno)); diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index bfb0c653d..c33d85518 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -1652,8 +1652,8 @@ handle_connections (gnupg_fd_t listen_fd) continue; plen = sizeof paddr; - fd = INT2FD (npth_accept (FD2INT(listentbl[idx].l_fd), - (struct sockaddr *)&paddr, &plen)); + fd = assuan_sock_accept (listentbl[idx].l_fd, + (struct sockaddr *)&paddr, &plen); if (fd == GNUPG_INVALID_FD) { log_error ("accept failed for %s: %s\n", diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 653fc78cc..71e37d28c 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -1399,8 +1399,8 @@ handle_connections (gnupg_fd_t listen_fd) gnupg_fd_t fd; plen = sizeof paddr; - fd = INT2FD (npth_accept (FD2INT (listen_fd), - (struct sockaddr *)&paddr, &plen)); + fd = assuan_sock_accept (listen_fd, + (struct sockaddr *)&paddr, &plen); if (fd == GNUPG_INVALID_FD) { log_error ("accept failed: %s\n", strerror (errno)); diff --git a/tpm2d/tpm2daemon.c b/tpm2d/tpm2daemon.c index 383421c30..9218d9a10 100644 --- a/tpm2d/tpm2daemon.c +++ b/tpm2d/tpm2daemon.c @@ -1238,8 +1238,8 @@ handle_connections (gnupg_fd_t listen_fd) gnupg_fd_t fd; plen = sizeof paddr; - fd = INT2FD (npth_accept (FD2INT (listen_fd), - (struct sockaddr *)&paddr, &plen)); + fd = assuan_sock_accept (listen_fd, + (struct sockaddr *)&paddr, &plen); if (fd == GNUPG_INVALID_FD) { log_error ("accept failed: %s\n", strerror (errno)); From 0821ceebfb7ad018b7d6067d01f3ccee8e27df08 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 24 Jul 2023 13:56:35 +0900 Subject: [PATCH 153/869] agent,dirmgr,gpg,g13,kbx,scd,sm,tmp2d: Remove ASSUAN_SYSTEM_NPTH. * agent/gpg-agent.c (ASSUAN_SYSTEM_NPTH_IMPL): Remove. (initialize_modules): Don't call assuan_set_system_hooks. (main): Don't call assuan_sock_set_system_hooks. * dirmngr/dirmngr.c (ASSUAN_SYSTEM_NPTH_IMPL): Remove. (thread_init): Don't call assuan_set_system_hooks. * g10/gpg.c (ASSUAN_SYSTEM_NPTH_IMPL): Remove. (main): Don't call assuan_set_system_hooks. * g13/g13.c (ASSUAN_SYSTEM_NPTH_IMPL): Remove. (main): Set the syscall clamp with gpgrt_set_syscall_clamp. Don't call assuan_set_system_hooks. * kbx/keyboxd.c (ASSUAN_SYSTEM_NPTH_IMPL): Remove. (initialize_modules): Don't call assuan_set_system_hooks. (main): Don't call assuan_sock_set_system_hooks. * scd/scdaemon.c (ASSUAN_SYSTEM_NPTH_IMPL): Remove. (main): Don't call assuan_set_system_hooks. * sm/gpgsm.c (ASSUAN_SYSTEM_NPTH_IMPL): Remove. (main): Don't call assuan_set_system_hooks. * tpm2d/tpm2daemon.c (ASSUAN_SYSTEM_NPTH_IMPL): Remove. (main): Don't call assuan_set_system_hooks. -- GnuPG-bug-id: 6606 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 5 ----- dirmngr/dirmngr.c | 4 ---- g10/gpg.c | 5 ----- g13/g13-syshelp.c | 1 - g13/g13.c | 6 +----- kbx/keyboxd.c | 6 ------ scd/scdaemon.c | 4 ---- sm/gpgsm.c | 5 ----- tpm2d/tpm2daemon.c | 4 ---- 9 files changed, 1 insertion(+), 39 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 624d2972c..afd864295 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -520,9 +520,6 @@ static void handle_connections (gnupg_fd_t listen_fd, static void check_own_socket (void); static int check_for_running_agent (int silent); -/* Pth wrapper function definitions. */ -ASSUAN_SYSTEM_NPTH_IMPL; - /* Functions. @@ -1053,7 +1050,6 @@ static void initialize_modules (void) { thread_init_once (); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); initialize_module_cache (); initialize_module_call_pinentry (); initialize_module_daemon (); @@ -1113,7 +1109,6 @@ main (int argc, char **argv) assuan_set_malloc_hooks (&malloc_hooks); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); assuan_sock_init (); - assuan_sock_set_system_hooks (ASSUAN_SYSTEM_NPTH); setup_libassuan_logging (&opt.debug, NULL); setup_libgcrypt_logging (); diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 967281ede..4619b0d7e 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -453,9 +453,6 @@ static void handle_connections (assuan_fd_t listen_fd); static void gpgconf_versions (void); -/* NPth wrapper function definitions. */ -ASSUAN_SYSTEM_NPTH_IMPL; - static const char * my_strusage( int level ) { @@ -983,7 +980,6 @@ static void thread_init (void) { npth_init (); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); /* Now with NPth running we can set the logging callback. Our diff --git a/g10/gpg.c b/g10/gpg.c index 8b3d79e1e..0e7ae82b0 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1079,10 +1079,6 @@ static void read_sessionkey_from_fd (int fd); -/* NPth wrapper function definitions. */ -ASSUAN_SYSTEM_NPTH_IMPL; - - static char * make_libversion (const char *libname, const char *(*getfnc)(const char*)) { @@ -3864,7 +3860,6 @@ main (int argc, char **argv) /* Init threading which is used by some helper functions. */ npth_init (); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); if (logfile) diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c index 6a4d3a446..6d0d1a659 100644 --- a/g13/g13-syshelp.c +++ b/g13/g13-syshelp.c @@ -306,7 +306,6 @@ main (int argc, char **argv) /* Prepare libassuan. */ assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - /*assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);*/ setup_libassuan_logging (&opt.debug, NULL); /* Setup a default control structure for command line mode. */ diff --git a/g13/g13.c b/g13/g13.c index 785c91950..d9594dd52 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -226,10 +226,6 @@ static void set_cmd (enum cmd_and_opt_values *ret_cmd, static void start_idle_task (void); static void join_idle_task (void); - -/* Begin NPth wrapper functions. */ -ASSUAN_SYSTEM_NPTH_IMPL; - static const char * my_strusage( int level ) @@ -377,6 +373,7 @@ main (int argc, char **argv) init_common_subsystems (&argc, &argv); npth_init (); + gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); /* Take extra care of the random pool. */ gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); @@ -435,7 +432,6 @@ main (int argc, char **argv) /* Prepare libassuan. */ assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); setup_libassuan_logging (&opt.debug, NULL); /* Setup a default control structure for command line mode. */ diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index c33d85518..c55b2a0d9 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -257,10 +257,6 @@ static void kbxd_deinit_default_ctrl (ctrl_t ctrl); static void handle_connections (gnupg_fd_t listen_fd); static void check_own_socket (void); static int check_for_running_kbxd (int silent); - -/* Pth wrapper function definitions. */ -ASSUAN_SYSTEM_NPTH_IMPL; - /* * Functions. @@ -447,7 +443,6 @@ static void initialize_modules (void) { thread_init_once (); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); } @@ -497,7 +492,6 @@ main (int argc, char **argv ) assuan_set_malloc_hooks (&malloc_hooks); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); assuan_sock_init (); - assuan_sock_set_system_hooks (ASSUAN_SYSTEM_NPTH); setup_libassuan_logging (&opt.debug, kbxd_assuan_log_monitor); setup_libgcrypt_logging (); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 71e37d28c..54c5760ba 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -272,9 +272,6 @@ static gnupg_fd_t create_server_socket (const char *name, static void *start_connection_thread (void *arg); static void handle_connections (gnupg_fd_t listen_fd); -/* Pth wrapper function definitions. */ -ASSUAN_SYSTEM_NPTH_IMPL; - static int active_connections; @@ -480,7 +477,6 @@ main (int argc, char **argv ) malloc_hooks.free = gcry_free; assuan_set_malloc_hooks (&malloc_hooks); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); assuan_sock_init (); setup_libassuan_logging (&opt.debug, NULL); diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 20b574377..9f6363652 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -596,10 +596,6 @@ our_md_test_algo (int algo) } -/* nPth wrapper function definitions. */ -ASSUAN_SYSTEM_NPTH_IMPL; - - static char * make_libversion (const char *libname, const char *(*getfnc)(const char*)) { @@ -1588,7 +1584,6 @@ main ( int argc, char **argv) log_info (_("WARNING: program may create a core file!\n")); npth_init (); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); /* if (opt.qualsig_approval && !opt.quiet) */ diff --git a/tpm2d/tpm2daemon.c b/tpm2d/tpm2daemon.c index 9218d9a10..13e20b9ef 100644 --- a/tpm2d/tpm2daemon.c +++ b/tpm2d/tpm2daemon.c @@ -192,9 +192,6 @@ static gnupg_fd_t create_server_socket (const char *name, static void *start_connection_thread (void *arg); static void handle_connections (gnupg_fd_t listen_fd); -/* Pth wrapper function definitions. */ -ASSUAN_SYSTEM_NPTH_IMPL; - static int active_connections; @@ -368,7 +365,6 @@ main (int argc, char **argv ) malloc_hooks.free = gcry_free; assuan_set_malloc_hooks (&malloc_hooks); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); assuan_sock_init (); setup_libassuan_logging (&opt.debug, NULL); From ed4050e01172479fb5dda968c1ee8fec59b778d9 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 30 May 2023 13:25:00 +0900 Subject: [PATCH 154/869] agent: Use new libassuan API for pipe server process. * agent/call-daemon.c (struct wait_child_thread_parm_s): Remove PID field. (wait_child_thread): Don't touch the internals but call assuan_pipe_wait_server_termination. (daemon_start): Don't use PID. (agent_daemon_dump_state): Don't use PID. * agent/call-pinentry.c (watch_sock): Call assuan_pipe_kill_server. (agent_popup_message_stop): Likewise. -- GnuPG-bug-id: 6487 Signed-off-by: NIIBE Yutaka --- agent/call-daemon.c | 47 ++----------------------------------------- agent/call-pinentry.c | 37 ++++------------------------------ 2 files changed, 6 insertions(+), 78 deletions(-) diff --git a/agent/call-daemon.c b/agent/call-daemon.c index 2699595e2..806ef5dc1 100644 --- a/agent/call-daemon.c +++ b/agent/call-daemon.c @@ -98,7 +98,6 @@ static npth_mutex_t start_daemon_lock; struct wait_child_thread_parm_s { enum daemon_type type; - pid_t pid; }; @@ -109,54 +108,14 @@ wait_child_thread (void *arg) int err; struct wait_child_thread_parm_s *parm = arg; enum daemon_type type = parm->type; - pid_t pid = parm->pid; -#ifndef HAVE_W32_SYSTEM - int wstatus; -#endif const char *name = opt.daemon_program[type]; struct daemon_global_s *g = &daemon_global[type]; struct daemon_local_s *sl; xfree (parm); /* We have copied all data to the stack. */ -#ifdef HAVE_W32_SYSTEM - npth_unprotect (); - /* Note that although we use a pid_t here, it is actually a HANDLE. */ - WaitForSingleObject ((HANDLE)pid, INFINITE); - npth_protect (); + assuan_pipe_wait_server_termination (g->primary_ctx, NULL, 0); log_info ("daemon %s finished\n", name); -#else /* !HAVE_W32_SYSTEM*/ - - again: - npth_unprotect (); - err = waitpid (pid, &wstatus, 0); - npth_protect (); - - if (err < 0) - { - if (errno == EINTR) - goto again; - log_error ("waitpid for %s failed: %s\n", name, strerror (errno)); - return NULL; - } - else - { - if (WIFEXITED (wstatus)) - log_info ("daemon %s finished (status %d)\n", - name, WEXITSTATUS (wstatus)); - else if (WIFSIGNALED (wstatus)) - log_info ("daemon %s killed by signal %d\n", name, WTERMSIG (wstatus)); - else - { - if (WIFSTOPPED (wstatus)) - log_info ("daemon %s stopped by signal %d\n", - name, WSTOPSIG (wstatus)); - goto again; - } - - assuan_set_flag (g->primary_ctx, ASSUAN_NO_WAITPID, 1); - } -#endif /*!HAVE_W32_SYSTEM*/ agent_flush_cache (1); /* Flush the PIN cache. */ @@ -496,7 +455,6 @@ daemon_start (enum daemon_type type, ctrl_t ctrl) } wctp->type = type; - wctp->pid = assuan_get_pid (g->primary_ctx); err = npth_attr_init (&tattr); if (!err) { @@ -561,10 +519,9 @@ agent_daemon_dump_state (void) for (i = 0; i < DAEMON_MAX_TYPE; i++) { struct daemon_global_s *g = &daemon_global[i]; - log_info ("%s: name %s primary_ctx=%p pid=%ld reusable=%d\n", __func__, + log_info ("%s: name %s primary_ctx=%p reusable=%d\n", __func__, gnupg_module_name (daemon_modules[i]), g->primary_ctx, - (long)assuan_get_pid (g->primary_ctx), g->primary_ctx_reusable); if (g->socket_name) log_info ("%s: socket='%s'\n", __func__, g->socket_name); diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 9d8d93aec..ba0e41c82 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -1288,8 +1288,6 @@ build_cmd_setdesc (char *line, size_t linelen, const char *desc) static void * watch_sock (void *arg) { - pid_t pid = assuan_get_pid (entry_ctx); - while (1) { int err; @@ -1317,17 +1315,7 @@ watch_sock (void *arg) break; } - if (pid == (pid_t)(-1)) - ; /* No pid available can't send a kill. */ -#ifdef HAVE_W32_SYSTEM - /* Older versions of assuan set PID to 0 on Windows to indicate an - invalid value. */ - else if (pid != (pid_t) INVALID_HANDLE_VALUE && pid != 0) - TerminateProcess ((HANDLE)pid, 1); -#else - else if (pid > 0) - kill (pid, SIGINT); -#endif + assuan_pipe_kill_server (entry_ctx); return NULL; } @@ -2122,7 +2110,6 @@ void agent_popup_message_stop (ctrl_t ctrl) { int rc; - pid_t pid; (void)ctrl; @@ -2135,26 +2122,10 @@ agent_popup_message_stop (ctrl_t ctrl) return; } - pid = assuan_get_pid (entry_ctx); - if (pid == (pid_t)(-1)) - ; /* No pid available can't send a kill. */ - else if (popup_finished) + if (popup_finished) ; /* Already finished and ready for joining. */ -#ifdef HAVE_W32_SYSTEM - /* Older versions of assuan set PID to 0 on Windows to indicate an - invalid value. */ - else if (pid != (pid_t) INVALID_HANDLE_VALUE - && pid != 0) - { - HANDLE process = (HANDLE) pid; - - /* Arbitrary error code. */ - TerminateProcess (process, 1); - } -#else - else if (pid > 0) - kill (pid, SIGINT); -#endif + else + assuan_pipe_kill_server (entry_ctx); /* Now wait for the thread to terminate. */ rc = npth_join (popup_tid, NULL); From 1d73806972b1fb8670326d0cea4f2768b14db67b Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 2 Aug 2023 14:34:17 +0900 Subject: [PATCH 155/869] gpg,agent,kbx,sm,scd,tpm2d,g13: Use assuan_control. * agent/gpg-agent.c (thread_init_once): Call assuan_control. * g10/gpg.c (main): Likewise. * g13/g13.c (main): Likewise. * kbx/keyboxd.c (thread_init_once): Likewise. * scd/scdaemon.c (main): Likewise. * sm/gpgsm.c (main): Likewise. * tpm2d/tpm2daemon.c (main): Likewise. -- GnuPG-bug-id: 6606 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 1 + g10/gpg.c | 1 + g13/g13.c | 1 + kbx/keyboxd.c | 1 + scd/scdaemon.c | 2 ++ sm/gpgsm.c | 1 + tpm2d/tpm2daemon.c | 2 ++ 7 files changed, 9 insertions(+) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index afd864295..9df0facbe 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1043,6 +1043,7 @@ thread_init_once (void) * initialized and thus Libgcrypt could not set its system call * clamp. */ gcry_control (GCRYCTL_REINIT_SYSCALL_CLAMP, 0, 0); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); } diff --git a/g10/gpg.c b/g10/gpg.c index 0e7ae82b0..54e74f5b1 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3861,6 +3861,7 @@ main (int argc, char **argv) /* Init threading which is used by some helper functions. */ npth_init (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); if (logfile) { diff --git a/g13/g13.c b/g13/g13.c index d9594dd52..e0453176a 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -433,6 +433,7 @@ main (int argc, char **argv) /* Prepare libassuan. */ assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); setup_libassuan_logging (&opt.debug, NULL); + assuan_control (ASSUAN_REINIT_SYSCALL_CLAMP, NULL); /* Setup a default control structure for command line mode. */ memset (&ctrl, 0, sizeof ctrl); diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index c55b2a0d9..e8e41486c 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -436,6 +436,7 @@ thread_init_once (void) * initialized and thus Libgcrypt could not set its system call * clamp. */ gcry_control (GCRYCTL_REINIT_SYSCALL_CLAMP, 0, 0); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); } diff --git a/scd/scdaemon.c b/scd/scdaemon.c index 54c5760ba..0376cbfba 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -754,6 +754,7 @@ main (int argc, char **argv ) npth_init (); setup_signal_mask (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); /* If --debug-allow-core-dump has been given we also need to switch the working directory to a place where we can actually @@ -895,6 +896,7 @@ main (int argc, char **argv ) npth_init (); setup_signal_mask (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); /* Detach from tty and put process into a new session. */ if (!nodetach ) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 9f6363652..74d23e5c1 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1585,6 +1585,7 @@ main ( int argc, char **argv) npth_init (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); /* if (opt.qualsig_approval && !opt.quiet) */ /* log_info (_("This software has officially been approved to " */ diff --git a/tpm2d/tpm2daemon.c b/tpm2d/tpm2daemon.c index 13e20b9ef..416a27df0 100644 --- a/tpm2d/tpm2daemon.c +++ b/tpm2d/tpm2daemon.c @@ -595,6 +595,7 @@ main (int argc, char **argv ) npth_init (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); + assuan_control (ASSUAN_REINIT_SYSCALL_CLAMP, NULL); /* If --debug-allow-core-dump has been given we also need to switch the working directory to a place where we can actually @@ -736,6 +737,7 @@ main (int argc, char **argv ) npth_init (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); + assuan_control (ASSUAN_REINIT_SYSCALL_CLAMP, NULL); /* Detach from tty and put process into a new session. */ if (!nodetach ) From 9e4d52223945d677c1ffcb0e20dae48299e9aae1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 16 Aug 2023 09:05:53 +0900 Subject: [PATCH 156/869] tpm2d: Fix call to assuan_control. * tpm2d/tpm2daemon.c (main): Use ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP. -- Signed-off-by: NIIBE Yutaka --- tpm2d/tpm2daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tpm2d/tpm2daemon.c b/tpm2d/tpm2daemon.c index 416a27df0..a8c83cd8b 100644 --- a/tpm2d/tpm2daemon.c +++ b/tpm2d/tpm2daemon.c @@ -595,7 +595,7 @@ main (int argc, char **argv ) npth_init (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); - assuan_control (ASSUAN_REINIT_SYSCALL_CLAMP, NULL); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); /* If --debug-allow-core-dump has been given we also need to switch the working directory to a place where we can actually From 716e59b0b62888776706472e69ee595e00a2e010 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 24 Aug 2023 16:07:26 +0900 Subject: [PATCH 157/869] agent: Add agent_kick_the_loop function. * agent/agent.h (agent_kick_the_loop): New. * agent/gpg-agent.c [HAVE_W32_SYSTEM] (the_event2): New. [HAVE_PSELECT_NO_EINTR] (event_pipe_fd): New. [!HAVE_PSELECT_NO_EINTR] (main_thread_pid): New. (create_an_event): New, factored out. (get_agent_daemon_notify_event): Use create_an_event. (handle_signal): Add a case for SIGCONT. (agent_kick_the_loop): New. (handle_connections): Call pselect possibly with the pipe. Call eselect with THE_EVENT2. -- GnuPG-bug-id: 6682 Signed-off-by: NIIBE Yutaka --- agent/agent.h | 1 + agent/gpg-agent.c | 150 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 117 insertions(+), 34 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 531fad210..69a1d5ff5 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -411,6 +411,7 @@ void *get_agent_daemon_notify_event (void); #endif void agent_sighup_action (void); int map_pk_openpgp_to_gcry (int openpgp_algo); +void agent_kick_the_loop (void); /*-- command.c --*/ gpg_error_t agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid, diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 9df0facbe..dd38528bb 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -432,6 +432,17 @@ static assuan_sock_nonce_t socket_nonce_ssh; * Let's try this as default. Change at runtime with --listen-backlog. */ static int listen_backlog = 64; +#ifdef HAVE_W32_SYSTEM +/* The event to break the select call. */ +static HANDLE the_event2; +#elif defined(HAVE_PSELECT_NO_EINTR) +/* An FD to break the select call. */ +static int event_pipe_fd; +#else +/* PID of the main thread. */ +static pid_t main_thread_pid; +#endif + /* Default values for options passed to the pinentry. */ static char *default_display; static char *default_ttyname; @@ -2130,39 +2141,45 @@ get_agent_active_connection_count (void) notification event. Calling it the first time creates that event. */ #if defined(HAVE_W32_SYSTEM) +static void * +create_an_event (void) +{ + HANDLE h, h2; + SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE}; + + /* We need to use a manual reset event object due to the way our + w32-pth wait function works: If we would use an automatic + reset event we are not able to figure out which handle has + been signaled because at the time we single out the signaled + handles using WFSO the event has already been reset due to + the WFMO. */ + h = CreateEvent (&sa, TRUE, FALSE, NULL); + if (!h) + log_error ("can't create an event: %s\n", w32_strerror (-1) ); + else if (!DuplicateHandle (GetCurrentProcess(), h, + GetCurrentProcess(), &h2, + EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0)) + { + log_error ("setting synchronize for an event failed: %s\n", + w32_strerror (-1) ); + CloseHandle (h); + } + else + { + CloseHandle (h); + return h2; + } + + return INVALID_HANDLE_VALUE; +} + void * get_agent_daemon_notify_event (void) { static HANDLE the_event = INVALID_HANDLE_VALUE; if (the_event == INVALID_HANDLE_VALUE) - { - HANDLE h, h2; - SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE}; - - /* We need to use a manual reset event object due to the way our - w32-pth wait function works: If we would use an automatic - reset event we are not able to figure out which handle has - been signaled because at the time we single out the signaled - handles using WFSO the event has already been reset due to - the WFMO. */ - h = CreateEvent (&sa, TRUE, FALSE, NULL); - if (!h) - log_error ("can't create scd notify event: %s\n", w32_strerror (-1) ); - else if (!DuplicateHandle (GetCurrentProcess(), h, - GetCurrentProcess(), &h2, - EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0)) - { - log_error ("setting synchronize for scd notify event failed: %s\n", - w32_strerror (-1) ); - CloseHandle (h); - } - else - { - CloseHandle (h); - the_event = h2; - } - } + the_event = create_an_event (); return the_event; } @@ -2528,6 +2545,11 @@ handle_signal (int signo) agent_sigusr2_action (); break; + case SIGCONT: + /* Do nothing, but break the syscall. */ + log_debug ("SIGCONT received - breaking select\n"); + break; + case SIGTERM: if (!shutdown_pending) log_info ("SIGTERM received - shutting down ...\n"); @@ -2959,6 +2981,28 @@ start_connection_thread_ssh (void *arg) } +void +agent_kick_the_loop (void) +{ + /* Kick the select loop. */ +#ifdef HAVE_W32_SYSTEM + int ret = SetEvent (the_event2); + if (ret == 0) + log_error ("SetEvent for agent_kick_the_loop failed: %s\n", + w32_strerror (-1)); +#else +# ifdef HAVE_PSELECT_NO_EINTR + write (event_pipe_fd, "", 1); +# else + int ret = kill (main_thread_pid, SIGCONT); + if (ret < 0) + log_error ("sending signal for agent_kick_the_loop failed: %s\n", + gpg_strerror (gpg_error_from_syserror ())); +# endif +#endif +} + + /* Connection handler loop. Wait for connection requests and spawn a thread after accepting a connection. */ static void @@ -2980,8 +3024,13 @@ handle_connections (gnupg_fd_t listen_fd, struct timespec curtime; struct timespec timeout; #ifdef HAVE_W32_SYSTEM - HANDLE events[2]; + HANDLE events[3]; unsigned int events_set; +#else + int signo; +# ifdef HAVE_PSELECT_NO_EINTR + int pipe_fd[2]; +# endif #endif int sock_inotify_fd = -1; int home_inotify_fd = -1; @@ -3009,11 +3058,24 @@ handle_connections (gnupg_fd_t listen_fd, npth_sigev_add (SIGUSR1); npth_sigev_add (SIGUSR2); npth_sigev_add (SIGINT); + npth_sigev_add (SIGCONT); npth_sigev_add (SIGTERM); npth_sigev_fini (); +# ifdef HAVE_PSELECT_NO_EINTR + ret = gnupg_create_pipe (pipe_fd); + if (ret) + { + log_error ("pipe creation failed: %s\n", gpg_strerror (ret)); + return; + } + event_pipe_fd = pipe_fd[1]; +# else + main_thread_pid = getpid (); +# endif #else events[0] = get_agent_daemon_notify_event (); - events[1] = INVALID_HANDLE_VALUE; + events[1] = the_event2 = create_an_event (); + events[2] = INVALID_HANDLE_VALUE; #endif if (disable_check_own_socket) @@ -3140,6 +3202,12 @@ handle_connections (gnupg_fd_t listen_fd, thus a simple assignment is fine to copy the entire set. */ read_fdset = fdset; +#ifdef HAVE_PSELECT_NO_EINTR + FD_SET (pipe_fd[0], &read_fdset); + if (nfd < pipe_fd[0]) + nfd = pipe_fd[0]; +#endif + npth_clock_gettime (&curtime); if (!(npth_timercmp (&curtime, &abstime, <))) { @@ -3155,11 +3223,8 @@ handle_connections (gnupg_fd_t listen_fd, npth_sigev_sigmask ()); saved_errno = errno; - { - int signo; - while (npth_sigev_get_pending (&signo)) - handle_signal (signo); - } + while (npth_sigev_get_pending (&signo)) + handle_signal (signo); #else ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, events, &events_set); @@ -3182,6 +3247,15 @@ handle_connections (gnupg_fd_t listen_fd, next timeout. */ continue; +#ifdef HAVE_PSELECT_NO_EINTR + if (FD_ISSET (pipe_fd[0], &read_fdset)) + { + char buf[256]; + + read (pipe_fd[0], buf, sizeof buf); + } +#endif + /* The inotify fds are set even when a shutdown is pending (see * above). So we must handle them in any case. To avoid that * they trigger a second time we close them immediately. */ @@ -3259,6 +3333,14 @@ handle_connections (gnupg_fd_t listen_fd, close (sock_inotify_fd); if (home_inotify_fd != -1) close (home_inotify_fd); +#ifdef HAVE_W32_SYSTEM + if (the_event2 != INVALID_HANDLE_VALUE) + CloseHandle (the_event2); +#endif +#ifdef HAVE_PSELECT_NO_EINTR + close (pipe_fd[0]); + close (pipe_fd[1]); +#endif cleanup (); log_info (_("%s %s stopped\n"), gpgrt_strusage(11), gpgrt_strusage(13)); npth_attr_destroy (&tattr); From 32c55603dfeb14c7e3a2fd44cdcb301280dc7f6d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 May 2023 16:02:39 +0200 Subject: [PATCH 158/869] dirmngr: Fix LDAP time parser. * dirmngr/ldap-misc.c (rfc4517toisotime): Correct index. -- Obviously the parser assumes the standard ISO format with the 'T' before the hour. That is not correct here. We need this parser for the modifyTimestamp thingy. --- dirmngr/ldap-misc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dirmngr/ldap-misc.c b/dirmngr/ldap-misc.c index 6b0939a3b..c3a659d5c 100644 --- a/dirmngr/ldap-misc.c +++ b/dirmngr/ldap-misc.c @@ -380,13 +380,14 @@ rfc4517toisotime (gnupg_isotime_t timebuf, const char *string) int year, month, day, hour, minu, sec; const char *s; + /* Sample value: "20230823141623Z"; */ for (i=0, s=string; i < 10; i++, s++) /* Need yyyymmddhh */ if (!digitp (s)) return gpg_error (GPG_ERR_INV_TIME); year = atoi_4 (string); month = atoi_2 (string + 4); day = atoi_2 (string + 6); - hour = atoi_2 (string + 9); + hour = atoi_2 (string + 8); minu = 0; sec = 0; if (digitp (s) && digitp (s+1)) From ee27ac18eaf27802be9258ac384e8844911a5443 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 24 Aug 2023 11:28:12 +0200 Subject: [PATCH 159/869] doc: Add some hints for AD queries. -- This is repo only. --- doc/ad-query-hints.org | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 doc/ad-query-hints.org diff --git a/doc/ad-query-hints.org b/doc/ad-query-hints.org new file mode 100644 index 000000000..fd32a5831 --- /dev/null +++ b/doc/ad-query-hints.org @@ -0,0 +1,65 @@ + + +* Examples + +** List the DNs of all users in our QAUsers group + +: ad_query --subst --attr=dn +: ^OU=QAUsers,$domain&sub&(&(objectcategory=person)(objectclass=user)) + +** List the DN using the user's mail address + +: ad_query --subst --attr=dn,userAccountControl +: (&(objectcategory=person)(objectclass=user) +: (|(userPrincipalName=dd9jn@w32demo.g10code.de) +: (mail=dd9jn@w32demo.g10code.de))) + +After that the userControlFlags should be checked - see below for +the bit flags. For a non-disabled user use: + +: if ((userControlFlags & 0x0212) == 0x200)) +: use_this_user() + + +* Useful attributes + +** userAccountControl + +These are bit flags. For details see +https://learn.microsoft.com/en-us/windows/win32/api/iads/ne-iads-ads_user_flag_enum + +- 0x00000002 :: ADS_UF_ACCOUNTDISABLE, the account is disabled. +- 0x00000010 :: ADS_UF_LOCKOUT, the account is temporarily locked out. +- 0x00000100 :: ADS_UF_TEMP_DUPLICATE_ACCOUNT, this is an account for + a user whose primary account is in another domain. +- 0x00000200 :: ADS_UF_NORMAL_ACCOUNT, the default account type that + represents a typical user. +- 0x00000800 :: ADS_UF_INTERDOMAIN_TRUST_ACCOUNT, the account for a + domain-to-domain trust. +- 0x00001000 :: ADS_UF_WORKSTATION_ACCOUNT, the computer account for a + computer that is a member of this domain. +- 0x00002000 :: ADS_UF_SERVER_TRUST_ACCOUNT, the computer account for + a DC. +- 0x00010000 :: ADS_UF_DONT_EXPIRE_PASSWD, the password will not expire. +- 0x04000000 :: ADS_UF_PARTIAL_SECRETS_ACCOUNT, the computer account + for an RODC. + +For example to select only user accounts which are not disabled or +are locked out could naivly be used: + +: (userAccountControl:1.2.840.113556.1.4.803:=512) + +1.2.840.113556.1.4.803 is bit wise AND, 1.2.840.113556.1.4.804 is bit +wise OR. However, because a mask can't be specified, this is not really +useful. Thus the above needs to be replaced by explicit checks; i.e. + +: (&(userAccountControl:1.2.840.113556.1.4.804:=512) +: (!(userAccountControl:1.2.840.113556.1.4.804:=2)) +: (!(userAccountControl:1.2.840.113556.1.4.804:=16))) + +I'd suggest to also add explict checks on the returned data. + + +* Resources + +- https://qa.social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx From a430f2254999383d48d3891a79623a4b33e7ce2d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 29 Aug 2023 13:18:13 +0200 Subject: [PATCH 160/869] common: Prepare for more flags in start_new_service. * common/asshelp.h (ASSHELP_FLAG_AUTOSTART): New. * common/asshelp.c (start_new_service): Rename arg autostart to flags and adjust checks. (start_new_gpg_agent): Likewise. Change all callers. (start_new_keyboxd): Likewise. Change all callers. (start_new_dirmngr): Likewise. Change all callers. -- It is easier to have a generic flags arg instead of adding more and more dedicated args. verbose and debug are kept as they are because they are not boolean. --- common/asshelp.c | 29 +++++++++++++++++------------ common/asshelp.h | 11 ++++++++--- common/get-passphrase.c | 3 ++- dirmngr/dirmngr-client.c | 2 +- g10/call-agent.c | 3 ++- g10/call-dirmngr.c | 3 ++- g10/call-keyboxd.c | 3 ++- sm/call-agent.c | 3 ++- sm/call-dirmngr.c | 3 ++- sm/keydb.c | 3 ++- tools/call-dirmngr.c | 3 ++- tools/card-call-scd.c | 3 ++- tools/gpg-auth.c | 2 +- tools/gpg-connect-agent.c | 6 +++--- 14 files changed, 48 insertions(+), 29 deletions(-) diff --git a/common/asshelp.c b/common/asshelp.c index 8b3df2a4b..5a40e0380 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -386,7 +386,8 @@ start_new_service (assuan_context_t *r_ctx, const char *opt_lc_ctype, const char *opt_lc_messages, session_env_t session_env, - int autostart, int verbose, int debug, + unsigned int flags, + int verbose, int debug, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg) { @@ -445,7 +446,7 @@ start_new_service (assuan_context_t *r_ctx, } err = assuan_socket_connect (ctx, sockname, 0, connect_flags); - if (err && autostart) + if (err && (flags & ASSHELP_FLAG_AUTOSTART)) { char *abs_homedir; lock_spawn_t lock; @@ -547,7 +548,8 @@ start_new_service (assuan_context_t *r_ctx, xfree (sockname); if (err) { - if (autostart || gpg_err_code (err) != GPG_ERR_ASS_CONNECT_FAILED) + if ((flags & ASSHELP_FLAG_AUTOSTART) + || gpg_err_code (err) != GPG_ERR_ASS_CONNECT_FAILED) log_error ("can't connect to the %s: %s\n", printed_name, gpg_strerror (err)); assuan_release (ctx); @@ -599,55 +601,58 @@ start_new_gpg_agent (assuan_context_t *r_ctx, const char *opt_lc_ctype, const char *opt_lc_messages, session_env_t session_env, - int autostart, int verbose, int debug, + unsigned int flags, + int verbose, int debug, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg) { return start_new_service (r_ctx, GNUPG_MODULE_NAME_AGENT, errsource, agent_program, opt_lc_ctype, opt_lc_messages, session_env, - autostart, verbose, debug, + flags, verbose, debug, status_cb, status_cb_arg); } /* Try to connect to the dirmngr via a socket. On platforms - supporting it, start it up if needed and if AUTOSTART is true. + supporting it, start it up if needed and if ASSHELP_FLAG_AUTOSTART is set. Returns a new assuan context at R_CTX or an error code. */ gpg_error_t start_new_keyboxd (assuan_context_t *r_ctx, gpg_err_source_t errsource, const char *keyboxd_program, - int autostart, int verbose, int debug, + unsigned int flags, + int verbose, int debug, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg) { return start_new_service (r_ctx, GNUPG_MODULE_NAME_KEYBOXD, errsource, keyboxd_program, NULL, NULL, NULL, - autostart, verbose, debug, + flags, verbose, debug, status_cb, status_cb_arg); } /* Try to connect to the dirmngr via a socket. On platforms - supporting it, start it up if needed and if AUTOSTART is true. + supporting it, start it up if needed and if ASSHELP_FLAG_AUTOSTART is set. Returns a new assuan context at R_CTX or an error code. */ gpg_error_t start_new_dirmngr (assuan_context_t *r_ctx, gpg_err_source_t errsource, const char *dirmngr_program, - int autostart, int verbose, int debug, + unsigned int flags, + int verbose, int debug, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg) { #ifndef USE_DIRMNGR_AUTO_START - autostart = 0; + flags &= ~ASSHELP_FLAG_AUTOSTART; /* Clear flag. */ #endif return start_new_service (r_ctx, GNUPG_MODULE_NAME_DIRMNGR, errsource, dirmngr_program, NULL, NULL, NULL, - autostart, verbose, debug, + flags, verbose, debug, status_cb, status_cb_arg); } diff --git a/common/asshelp.h b/common/asshelp.h index e7e43bd1b..bca50759d 100644 --- a/common/asshelp.h +++ b/common/asshelp.h @@ -37,6 +37,8 @@ #include "util.h" /*-- asshelp.c --*/ +#define ASSHELP_FLAG_AUTOSTART 1 /* Autostart the new service. */ + void setup_libassuan_logging (unsigned int *debug_var_address, int (*log_monitor)(assuan_context_t ctx, @@ -61,7 +63,8 @@ start_new_gpg_agent (assuan_context_t *r_ctx, const char *opt_lc_ctype, const char *opt_lc_messages, session_env_t session_env, - int autostart, int verbose, int debug, + unsigned int flags, + int verbose, int debug, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg); @@ -71,7 +74,8 @@ gpg_error_t start_new_keyboxd (assuan_context_t *r_ctx, gpg_err_source_t errsource, const char *keyboxd_program, - int autostart, int verbose, int debug, + unsigned int flags, + int verbose, int debug, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg); @@ -81,7 +85,8 @@ gpg_error_t start_new_dirmngr (assuan_context_t *r_ctx, gpg_err_source_t errsource, const char *dirmngr_program, - int autostart, int verbose, int debug, + unsigned int flags, + int verbose, int debug, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg); diff --git a/common/get-passphrase.c b/common/get-passphrase.c index c24b40e88..8ea822710 100644 --- a/common/get-passphrase.c +++ b/common/get-passphrase.c @@ -94,7 +94,8 @@ start_agent (void) agentargs.lc_ctype, agentargs.lc_messages, agentargs.session_env, - 1, agentargs.verbosity, 0, NULL, NULL); + ASSHELP_FLAG_AUTOSTART, + agentargs.verbosity, 0, NULL, NULL); if (!err) { /* Tell the agent that we support Pinentry notifications. No diff --git a/dirmngr/dirmngr-client.c b/dirmngr/dirmngr-client.c index 3912bf47b..f1059c939 100644 --- a/dirmngr/dirmngr-client.c +++ b/dirmngr/dirmngr-client.c @@ -308,7 +308,7 @@ main (int argc, char **argv ) opt.dirmngr_program ? opt.dirmngr_program : gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR), - ! cmd_ping, + cmd_ping? 0 : ASSHELP_FLAG_AUTOSTART, opt.verbose, 0, NULL, NULL); diff --git a/g10/call-agent.c b/g10/call-agent.c index b0bccc0a5..d6e4575c3 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -248,7 +248,8 @@ start_agent (ctrl_t ctrl, int flag_for_card) opt.agent_program, opt.lc_ctype, opt.lc_messages, opt.session_env, - opt.autostart, opt.verbose, DBG_IPC, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, + opt.verbose, DBG_IPC, NULL, NULL); if (!opt.autostart && gpg_err_code (rc) == GPG_ERR_NO_AGENT) { diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index c47bf0928..d00f61450 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -166,7 +166,8 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx) err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT, opt.dirmngr_program, - opt.autostart, opt.verbose, DBG_IPC, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, + opt.verbose, DBG_IPC, NULL /*gpg_status2*/, ctrl); if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR) { diff --git a/g10/call-keyboxd.c b/g10/call-keyboxd.c index dc3d30a93..960979aae 100644 --- a/g10/call-keyboxd.c +++ b/g10/call-keyboxd.c @@ -150,7 +150,8 @@ create_new_context (ctrl_t ctrl, assuan_context_t *r_ctx) err = start_new_keyboxd (&ctx, GPG_ERR_SOURCE_DEFAULT, opt.keyboxd_program, - opt.autostart, opt.verbose, DBG_IPC, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, + opt.verbose, DBG_IPC, NULL, ctrl); if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_KEYBOXD) { diff --git a/sm/call-agent.c b/sm/call-agent.c index 698039504..883c0c644 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -118,7 +118,8 @@ start_agent (ctrl_t ctrl) opt.agent_program, opt.lc_ctype, opt.lc_messages, opt.session_env, - opt.autostart, opt.verbose, DBG_IPC, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, + opt.verbose, DBG_IPC, gpgsm_status2, ctrl); if (!opt.autostart && gpg_err_code (rc) == GPG_ERR_NO_AGENT) diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index 7fe7a68f5..22580bd12 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -228,7 +228,8 @@ start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r) err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT, opt.dirmngr_program, - opt.autostart, opt.verbose, DBG_IPC, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, + opt.verbose, DBG_IPC, gpgsm_status2, ctrl); if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR) { diff --git a/sm/keydb.c b/sm/keydb.c index 9b3c7c8ba..512ab1af8 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -523,7 +523,8 @@ create_new_context (ctrl_t ctrl, assuan_context_t *r_ctx) err = start_new_keyboxd (&ctx, GPG_ERR_SOURCE_DEFAULT, opt.keyboxd_program, - opt.autostart, opt.verbose, DBG_IPC, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, + opt.verbose, DBG_IPC, NULL, ctrl); if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_KEYBOXD) { diff --git a/tools/call-dirmngr.c b/tools/call-dirmngr.c index c0ddcf568..d85801530 100644 --- a/tools/call-dirmngr.c +++ b/tools/call-dirmngr.c @@ -65,7 +65,8 @@ connect_dirmngr (assuan_context_t *r_ctx) err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT, NULL, - opt.autostart, opt.verbose, opt.debug_ipc, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, + opt.verbose, opt.debug_ipc, NULL, NULL); if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_DIRMNGR) { diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 27d8ad961..08f951331 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -299,7 +299,8 @@ start_agent (unsigned int flags) opt.agent_program, opt.lc_ctype, opt.lc_messages, opt.session_env, - opt.autostart, opt.verbose, DBG_IPC, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, + opt.verbose, DBG_IPC, NULL, NULL); if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_AGENT) { diff --git a/tools/gpg-auth.c b/tools/gpg-auth.c index f433ba220..a818bee5d 100644 --- a/tools/gpg-auth.c +++ b/tools/gpg-auth.c @@ -396,7 +396,7 @@ start_agent (assuan_context_t *ctx_p) opt.agent_program, NULL, NULL, session_env, - opt.autostart, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, !opt.quiet, 0, NULL, NULL); diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index ab96d3b02..5323313e2 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -2341,14 +2341,14 @@ start_agent (void) err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT, opt.dirmngr_program, - opt.autostart, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, !opt.quiet, 0, NULL, NULL); else if (opt.use_keyboxd) err = start_new_keyboxd (&ctx, GPG_ERR_SOURCE_DEFAULT, opt.keyboxd_program, - opt.autostart, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, !opt.quiet, 0, NULL, NULL); else @@ -2357,7 +2357,7 @@ start_agent (void) opt.agent_program, NULL, NULL, session_env, - opt.autostart, + opt.autostart?ASSHELP_FLAG_AUTOSTART:0, !opt.quiet, 0, NULL, NULL); From 9dd8fd4ae4456d8821cbe5cdf4d70dff2cd9377f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 29 Aug 2023 13:23:48 +0200 Subject: [PATCH 161/869] g13: Fix for new assuan_control. * g13/g13.c (main): Fix assuan control code. -- Fixes-commit: 1d73806972b1fb8670326d0cea4f2768b14db67b GnuPG-bug-id: 6606 --- g13/g13.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g13/g13.c b/g13/g13.c index e0453176a..e15fd8812 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -433,7 +433,7 @@ main (int argc, char **argv) /* Prepare libassuan. */ assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); setup_libassuan_logging (&opt.debug, NULL); - assuan_control (ASSUAN_REINIT_SYSCALL_CLAMP, NULL); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); /* Setup a default control structure for command line mode. */ memset (&ctrl, 0, sizeof ctrl); From 95186ae92f923df6240f1b677cbaf130c4f64fae Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 30 Aug 2023 10:57:36 +0900 Subject: [PATCH 162/869] agent: Use a thread to monitor socket takeover. * agent/gpg-agent.c (check_own_socket_running): Remove. (socket_takeover_detected): New. (check_own_socket): Remove. (handle_tick): Don't call check_own_socket any more. (handle_connections): Start off the check_own_socket_thread. Check socket_takeover_detected to handle the event. (do_check_own_socket): New, factoring out the task. (check_own_socket_thread): Loop with the interval. -- GnuPG-bug-id: 6692 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 109 +++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 63 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index dd38528bb..a493e2a98 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -384,9 +384,6 @@ static int startup_signal_mask_valid; /* Flag to indicate that a shutdown was requested. */ static int shutdown_pending; -/* Counter for the currently running own socket checks. */ -static int check_own_socket_running; - /* Flags to indicate that check_own_socket shall not be called. */ static int disable_check_own_socket; @@ -396,6 +393,9 @@ static int is_supervised; /* Flag indicating to start the daemon even if one already runs. */ static int steal_socket; +/* Flag to monitor socket takeover. */ +static int socket_takeover_detected; + /* Flag to inhibit socket removal in cleanup. */ static int inhibit_socket_removal; @@ -528,8 +528,8 @@ static void handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_extra, gnupg_fd_t listen_fd_browser, gnupg_fd_t listen_fd_ssh); -static void check_own_socket (void); static int check_for_running_agent (int silent); +static void *check_own_socket_thread (void *arg); /* @@ -2442,12 +2442,8 @@ create_directories (void) static void handle_tick (void) { - static time_t last_minute; struct stat statbuf; - if (!last_minute) - last_minute = time (NULL); - /* If we are running as a child of another process, check whether the parent is still alive and shutdown if not. */ #ifndef HAVE_W32_SYSTEM @@ -2464,15 +2460,6 @@ handle_tick (void) } #endif /*HAVE_W32_SYSTEM*/ - /* Code to be run from time to time. */ -#if CHECK_OWN_SOCKET_INTERVAL > 0 - if (last_minute + CHECK_OWN_SOCKET_INTERVAL <= time (NULL)) - { - check_own_socket (); - last_minute = time (NULL); - } -#endif - /* Need to check for expired cache entries. */ agent_cache_housekeeping (); @@ -3099,6 +3086,15 @@ handle_connections (gnupg_fd_t listen_fd, else have_homedir_inotify = 1; + if (!disable_check_own_socket) + { + npth_t thread; + + err = npth_create (&thread, &tattr, check_own_socket_thread, NULL); + if (err) + log_error ("error spawning check_own_socket_thread: %s\n", strerror (err)); + } + /* On Windows we need to fire up a separate thread to listen for requests from Putty (an SSH client), so we can replace Putty's Pageant (its ssh-agent implementation). */ @@ -3278,6 +3274,15 @@ handle_connections (gnupg_fd_t listen_fd, log_info ("homedir has been removed - shutting down\n"); } + if (socket_takeover_detected) + { + /* We may not remove the socket as it is now in use by another + server. */ + inhibit_socket_removal = 1; + shutdown_pending = 2; + log_info ("this process is useless - shutting down\n"); + } + if (!shutdown_pending) { int idx; @@ -3358,20 +3363,18 @@ check_own_socket_pid_cb (void *opaque, const void *buffer, size_t length) } -/* The thread running the actual check. We need to run this in a - separate thread so that check_own_thread can be called from the - timer tick. */ -static void * -check_own_socket_thread (void *arg) +/* Check whether we are still listening on our own socket. In case + another gpg-agent process started after us has taken ownership of + our socket, we would linger around without any real task. Thus we + better check once in a while whether we are really needed. */ +static int +do_check_own_socket (const char *sockname) { int rc; - char *sockname = arg; assuan_context_t ctx = NULL; membuf_t mb; char *buffer; - check_own_socket_running++; - rc = assuan_new (&ctx); if (rc) { @@ -3409,57 +3412,37 @@ check_own_socket_thread (void *arg) xfree (buffer); leave: - xfree (sockname); if (ctx) assuan_release (ctx); - if (rc) - { - /* We may not remove the socket as it is now in use by another - server. */ - inhibit_socket_removal = 1; - shutdown_pending = 2; - log_info ("this process is useless - shutting down\n"); - } - check_own_socket_running--; - return NULL; + + return rc; } - -/* Check whether we are still listening on our own socket. In case - another gpg-agent process started after us has taken ownership of - our socket, we would linger around without any real task. Thus we - better check once in a while whether we are really needed. */ -static void -check_own_socket (void) +/* The thread running the actual check. */ +static void * +check_own_socket_thread (void *arg) { char *sockname; - npth_t thread; - npth_attr_t tattr; - int err; - if (disable_check_own_socket) - return; - - if (check_own_socket_running || shutdown_pending) - return; /* Still running or already shutting down. */ + (void)arg; sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL); if (!sockname) - return; /* Out of memory. */ + return NULL; /* Out of memory. */ - err = npth_attr_init (&tattr); - if (err) + while (1) { - xfree (sockname); - return; - } - npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED); - err = npth_create (&thread, &tattr, check_own_socket_thread, sockname); - if (err) - log_error ("error spawning check_own_socket_thread: %s\n", strerror (err)); - npth_attr_destroy (&tattr); -} + if (do_check_own_socket (sockname)) + break; + gnupg_sleep (CHECK_OWN_SOCKET_INTERVAL); + } + + xfree (sockname); + socket_takeover_detected = 1; + + return NULL; +} /* Figure out whether an agent is available and running. Prints an From b2826924eeca2c4d824bc6ddba27f4db8b2175e3 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 30 Aug 2023 11:26:07 +0900 Subject: [PATCH 163/869] agent: Fix the handling of socket takeover. * agent/gpg-agent.c (handle_connections): Check the takeover when interrupted. (check_own_socket_thread): Kick the loop when detected. -- GnuPG-bug-id: 6692 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index a493e2a98..c379851b3 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -3238,6 +3238,16 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_sleep (1); continue; } + + if (socket_takeover_detected) + { + /* We may not remove the socket as it is now in use by another + server. */ + inhibit_socket_removal = 1; + shutdown_pending = 2; + log_info ("this process is useless - shutting down\n"); + } + if (ret <= 0) /* Interrupt or timeout. Will be handled when calculating the next timeout. */ @@ -3274,15 +3284,6 @@ handle_connections (gnupg_fd_t listen_fd, log_info ("homedir has been removed - shutting down\n"); } - if (socket_takeover_detected) - { - /* We may not remove the socket as it is now in use by another - server. */ - inhibit_socket_removal = 1; - shutdown_pending = 2; - log_info ("this process is useless - shutting down\n"); - } - if (!shutdown_pending) { int idx; @@ -3440,6 +3441,7 @@ check_own_socket_thread (void *arg) xfree (sockname); socket_takeover_detected = 1; + agent_kick_the_loop (); return NULL; } From 76896e2339a44f882d076171e52f5a45e1d05a45 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 30 Aug 2023 13:21:37 +0900 Subject: [PATCH 164/869] agent: Recover support CHECK_OWN_SOCKET_INTERVAL == 0. * agent/gpg-agent.c (handle_connections): Only spawn the thread when CHECK_OWN_SOCKET_INTERVAL > 0. [CHECK_OWN_SOCKET_INTERVAL == 0] (check_own_socket_pid_cb) (do_check_own_socket, check_own_socket_thread): Ifdef out. -- GnuPG-bug-id: 6692 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index c379851b3..962f39a62 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -529,8 +529,9 @@ static void handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_browser, gnupg_fd_t listen_fd_ssh); static int check_for_running_agent (int silent); +#if CHECK_OWN_SOCKET_INTERVAL > 0 static void *check_own_socket_thread (void *arg); - +#endif /* Functions. @@ -3086,6 +3087,7 @@ handle_connections (gnupg_fd_t listen_fd, else have_homedir_inotify = 1; +#if CHECK_OWN_SOCKET_INTERVAL > 0 if (!disable_check_own_socket) { npth_t thread; @@ -3094,6 +3096,7 @@ handle_connections (gnupg_fd_t listen_fd, if (err) log_error ("error spawning check_own_socket_thread: %s\n", strerror (err)); } +#endif /* On Windows we need to fire up a separate thread to listen for requests from Putty (an SSH client), so we can replace Putty's @@ -3353,7 +3356,7 @@ handle_connections (gnupg_fd_t listen_fd, } - +#if CHECK_OWN_SOCKET_INTERVAL > 0 /* Helper for check_own_socket. */ static gpg_error_t check_own_socket_pid_cb (void *opaque, const void *buffer, size_t length) @@ -3445,7 +3448,7 @@ check_own_socket_thread (void *arg) return NULL; } - +#endif /* Figure out whether an agent is available and running. Prints an error if not. If SILENT is true, no messages are printed. From 7025375e8bec6f28e5750f724faa93e7d9f7d692 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 30 Aug 2023 14:08:33 +0900 Subject: [PATCH 165/869] agent: Have a thread monitoring parent PID and homedir. * agent/gpg-agent.c (CHECK_PROBLEMS_INTERVAL): New. (socket_takeover_detected): Remove. (problem_detected): New. (handle_tick): Don't check parent PID and homedir in this function. (handle_connections): Spawn check_others_thread when needed. Handle AGENT_PROBLEM_PARENT_HAS_GONE and AGENT_PROBLEM_HOMEDIR_REMOVED. (check_own_socket_thread): Check SHUTDOWN_PENDING variable in the loop. Use PROBLEM_DETECTED variable. (check_others_thread): New. -- GnuPG-bug-id: 6693 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 126 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 39 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 962f39a62..6eb31c7ae 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -349,7 +349,7 @@ static struct debug_flags_s debug_flags [] = * don't check at all. All values are in seconds. */ #define TIMERTICK_INTERVAL (4) #define CHECK_OWN_SOCKET_INTERVAL (60) - +#define CHECK_PROBLEMS_INTERVAL (4) /* Flag indicating that the ssh-agent subsystem has been enabled. */ static int ssh_support; @@ -393,8 +393,11 @@ static int is_supervised; /* Flag indicating to start the daemon even if one already runs. */ static int steal_socket; -/* Flag to monitor socket takeover. */ -static int socket_takeover_detected; +/* Flag to monitor problems. */ +static int problem_detected; +#define AGENT_PROBLEM_SOCKET_TAKEOVER (1 << 0) +#define AGENT_PROBLEM_PARENT_HAS_GONE (1 << 1) +#define AGENT_PROBLEM_HOMEDIR_REMOVED (1 << 2) /* Flag to inhibit socket removal in cleanup. */ static int inhibit_socket_removal; @@ -463,9 +466,14 @@ static const char *debug_level; the log file after a SIGHUP if it didn't changed. Malloced. */ static char *current_logfile; -/* The handle_tick() function may test whether a parent is still - * running. We record the PID of the parent here or -1 if it should - * be watched. */ +#ifdef HAVE_W32_SYSTEM +#define HAVE_PARENT_PID_SUPPORT 0 +#else +#define HAVE_PARENT_PID_SUPPORT 1 +#endif +/* The check_others_thread() function may test whether a parent is + * still running. We record the PID of the parent here or -1 if it + * should be watched. */ static pid_t parent_pid = (pid_t)(-1); /* This flag is true if the inotify mechanism for detecting the @@ -532,6 +540,7 @@ static int check_for_running_agent (int silent); #if CHECK_OWN_SOCKET_INTERVAL > 0 static void *check_own_socket_thread (void *arg); #endif +static void *check_others_thread (void *arg); /* Functions. @@ -2443,35 +2452,8 @@ create_directories (void) static void handle_tick (void) { - struct stat statbuf; - - /* If we are running as a child of another process, check whether - the parent is still alive and shutdown if not. */ -#ifndef HAVE_W32_SYSTEM - if (parent_pid != (pid_t)(-1)) - { - if (kill (parent_pid, 0)) - { - shutdown_pending = 2; - log_info ("parent process died - shutting down\n"); - log_info ("%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13)); - cleanup (); - agent_exit (0); - } - } -#endif /*HAVE_W32_SYSTEM*/ - /* Need to check for expired cache entries. */ agent_cache_housekeeping (); - - /* Check whether the homedir is still available. */ - if (!shutdown_pending - && (!have_homedir_inotify || !reliable_homedir_inotify) - && gnupg_stat (gnupg_homedir (), &statbuf) && errno == ENOENT) - { - shutdown_pending = 1; - log_info ("homedir has been removed - shutting down\n"); - } } @@ -3098,6 +3080,16 @@ handle_connections (gnupg_fd_t listen_fd, } #endif + if ((HAVE_PARENT_PID_SUPPORT && parent_pid != (pid_t)(-1)) + || (!have_homedir_inotify || !reliable_homedir_inotify)) + { + npth_t thread; + + err = npth_create (&thread, &tattr, check_others_thread, NULL); + if (err) + log_error ("error spawning check_others_thread: %s\n", strerror (err)); + } + /* On Windows we need to fire up a separate thread to listen for requests from Putty (an SSH client), so we can replace Putty's Pageant (its ssh-agent implementation). */ @@ -3242,7 +3234,18 @@ handle_connections (gnupg_fd_t listen_fd, continue; } - if (socket_takeover_detected) +#ifndef HAVE_W32_SYSTEM + if ((problem_detected & AGENT_PROBLEM_PARENT_HAS_GONE)) + { + shutdown_pending = 2; + log_info ("parent process died - shutting down\n"); + log_info ("%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13)); + cleanup (); + agent_exit (0); + } +#endif + + if ((problem_detected & AGENT_PROBLEM_SOCKET_TAKEOVER)) { /* We may not remove the socket as it is now in use by another server. */ @@ -3251,6 +3254,12 @@ handle_connections (gnupg_fd_t listen_fd, log_info ("this process is useless - shutting down\n"); } + if ((problem_detected & AGENT_PROBLEM_HOMEDIR_REMOVED)) + { + shutdown_pending = 1; + log_info ("homedir has been removed - shutting down\n"); + } + if (ret <= 0) /* Interrupt or timeout. Will be handled when calculating the next timeout. */ @@ -3434,22 +3443,61 @@ check_own_socket_thread (void *arg) if (!sockname) return NULL; /* Out of memory. */ - while (1) + while (!problem_detected) { - if (do_check_own_socket (sockname)) - break; + if (shutdown_pending) + goto leave; gnupg_sleep (CHECK_OWN_SOCKET_INTERVAL); + + if (do_check_own_socket (sockname)) + problem_detected |= AGENT_PROBLEM_SOCKET_TAKEOVER; } - xfree (sockname); - socket_takeover_detected = 1; agent_kick_the_loop (); + leave: + xfree (sockname); return NULL; } #endif +/* The thread running other checks. */ +static void * +check_others_thread (void *arg) +{ + const char *homedir = gnupg_homedir (); + + (void)arg; + + while (!problem_detected) + { + struct stat statbuf; + + if (shutdown_pending) + goto leave; + + gnupg_sleep (CHECK_PROBLEMS_INTERVAL); + + /* If we are running as a child of another process, check whether + the parent is still alive and shutdown if not. */ +#ifndef HAVE_W32_SYSTEM + if (parent_pid != (pid_t)(-1) && kill (parent_pid, 0)) + problem_detected |= AGENT_PROBLEM_PARENT_HAS_GONE; +#endif /*HAVE_W32_SYSTEM*/ + + /* Check whether the homedir is still available. */ + if ((!have_homedir_inotify || !reliable_homedir_inotify) + && gnupg_stat (homedir, &statbuf) && errno == ENOENT) + problem_detected |= AGENT_PROBLEM_HOMEDIR_REMOVED; + } + + agent_kick_the_loop (); + + leave: + return NULL; +} + /* Figure out whether an agent is available and running. Prints an error if not. If SILENT is true, no messages are printed. Returns 0 if the agent is running. */ From 76a2f180286e6cb10fd7075994512a0028d4eb2c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 30 Aug 2023 14:48:56 +0900 Subject: [PATCH 166/869] agent: Better interaction between main loop and cache expiration. * agent/agent.h (agent_cache_housekeeping): Remove. (agent_cache_expiration): New. * agent/cache.c (agent_cache_housekeeping): Remove. (agent_cache_expiration): New. * agent/gpg-agent.c (TIMERTICK_INTERVAL): Remove. (handle_tick): Remove. (handle_connections): Call agent_cache_expiration and use the timeout value determined by the call. -- GnuPG-bug-id: 6681 Signed-off-by: NIIBE Yutaka --- agent/agent.h | 2 +- agent/cache.c | 45 ++++++++++++++++++++++++++++++++++----------- agent/gpg-agent.c | 44 +++++++++----------------------------------- 3 files changed, 44 insertions(+), 47 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 69a1d5ff5..3bedab121 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -515,7 +515,7 @@ int agent_clear_passphrase (ctrl_t ctrl, /*-- cache.c --*/ void initialize_module_cache (void); void deinitialize_module_cache (void); -void agent_cache_housekeeping (void); +struct timespec *agent_cache_expiration (void); void agent_flush_cache (int pincache_only); int agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode, const char *data, int ttl); diff --git a/agent/cache.c b/agent/cache.c index 7616dafc1..f900be6cc 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -270,23 +270,46 @@ housekeeping (void) } -void -agent_cache_housekeeping (void) +#define TIMERTICK_INTERVAL (4) +struct timespec * +agent_cache_expiration (void) { + static struct timespec abstime; + static struct timespec timeout; + static int initialized = 0; + struct timespec curtime; int res; - if (DBG_CACHE) - log_debug ("agent_cache_housekeeping\n"); + if (!initialized) + { + initialized = 1; + npth_clock_gettime (&abstime); + abstime.tv_sec += TIMERTICK_INTERVAL; + } - res = npth_mutex_lock (&cache_lock); - if (res) - log_fatal ("failed to acquire cache mutex: %s\n", strerror (res)); + npth_clock_gettime (&curtime); + if (!(npth_timercmp (&curtime, &abstime, <))) + { + /* Timeout. */ + npth_clock_gettime (&abstime); + abstime.tv_sec += TIMERTICK_INTERVAL; - housekeeping (); + if (DBG_CACHE) + log_debug ("agent_cache_housekeeping\n"); - res = npth_mutex_unlock (&cache_lock); - if (res) - log_fatal ("failed to release cache mutex: %s\n", strerror (res)); + res = npth_mutex_lock (&cache_lock); + if (res) + log_fatal ("failed to acquire cache mutex: %s\n", strerror (res)); + + housekeeping (); + + res = npth_mutex_unlock (&cache_lock); + if (res) + log_fatal ("failed to release cache mutex: %s\n", strerror (res)); + } + + npth_timersub (&abstime, &curtime, &timeout); + return &timeout; } diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 6eb31c7ae..8c7f08c22 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -341,14 +341,12 @@ static struct debug_flags_s debug_flags [] = #define MIN_PASSPHRASE_NONALPHA (1) #define MAX_PASSPHRASE_DAYS (0) -/* The timer tick used for housekeeping stuff. Note that on Windows - * we use a SetWaitableTimer seems to signal earlier than about 2 - * seconds. Thus we use 4 seconds on all platforms. - * CHECK_OWN_SOCKET_INTERVAL defines how often we check - * our own socket in standard socket mode. If that value is 0 we - * don't check at all. All values are in seconds. */ -#define TIMERTICK_INTERVAL (4) +/* CHECK_OWN_SOCKET_INTERVAL defines how often we check our own socket + * in standard socket mode. If that value is 0 we don't check at all. + * Values is in seconds. */ #define CHECK_OWN_SOCKET_INTERVAL (60) +/* CHECK_PROBLEMS_INTERFAL defines how often we check the existence of + * parent process and homedir. Value is in seconds. */ #define CHECK_PROBLEMS_INTERVAL (4) /* Flag indicating that the ssh-agent subsystem has been enabled. */ @@ -2446,17 +2444,6 @@ create_directories (void) } - -/* This is the worker for the ticker. It is called every few seconds - and may only do fast operations. */ -static void -handle_tick (void) -{ - /* Need to check for expired cache entries. */ - agent_cache_housekeeping (); -} - - /* A global function which allows us to call the reload stuff from other places too. This is only used when build for W32. */ void @@ -2990,9 +2977,7 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t fd; int nfd; int saved_errno; - struct timespec abstime; - struct timespec curtime; - struct timespec timeout; + struct timespec *tp; #ifdef HAVE_W32_SYSTEM HANDLE events[3]; unsigned int events_set; @@ -3156,9 +3141,6 @@ handle_connections (gnupg_fd_t listen_fd, listentbl[2].l_fd = listen_fd_browser; listentbl[3].l_fd = listen_fd_ssh; - npth_clock_gettime (&abstime); - abstime.tv_sec += TIMERTICK_INTERVAL; - for (;;) { /* Shutdown test. */ @@ -3199,25 +3181,17 @@ handle_connections (gnupg_fd_t listen_fd, nfd = pipe_fd[0]; #endif - npth_clock_gettime (&curtime); - if (!(npth_timercmp (&curtime, &abstime, <))) - { - /* Timeout. */ - handle_tick (); - npth_clock_gettime (&abstime); - abstime.tv_sec += TIMERTICK_INTERVAL; - } - npth_timersub (&abstime, &curtime, &timeout); + tp = agent_cache_expiration (); #ifndef HAVE_W32_SYSTEM - ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, + ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, tp, npth_sigev_sigmask ()); saved_errno = errno; while (npth_sigev_get_pending (&signo)) handle_signal (signo); #else - ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, + ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, tp, events, &events_set); saved_errno = errno; From 92de0387f04b1e87a4a49ed063323624f25ac3ef Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 31 Aug 2023 14:49:38 +0900 Subject: [PATCH 167/869] agent: Introduce management of timer to expire cache entries. * agent/cache.c (struct timer_s): New. (struct cache_item_s): Add a member filed T for timer. (the_timer_list, the_timer_list_new): New. (insert_to_timer_list_new, insert_to_timer_list): New. (remove_from_timer_list, remove_from_timer_list_new): New. (housekeeping): Remove. (compute_expiration, update_expiration): New. (do_expire): New. (TIMERTICK_INTERVAL): Remove. (agent_cache_expiration): Use timer list to manage the expiration of cache entries. (agent_flush_cache): Call update_expiration when needed. (agent_put_cache): Don't call housekeeping any more, but update_expiration for an entry in question. (agent_get_cache): Likewise. -- GnuPG-bug-id: 6681 Signed-off-by: NIIBE Yutaka --- agent/cache.c | 382 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 291 insertions(+), 91 deletions(-) diff --git a/agent/cache.c b/agent/cache.c index f900be6cc..9ed3cb195 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -53,8 +53,20 @@ struct secret_data_s { char data[1]; /* A string. */ }; -/* The cache object. */ +/* The type of cache object. */ typedef struct cache_item_s *ITEM; + +/* The timer entry in a linked list. */ +struct timer_s { + ITEM next; + int tv_sec; + int reason; +}; +#define CACHE_EXPIRE_UNUSED 0 +#define CACHE_EXPIRE_LAST_ACCESS 1 +#define CACHE_EXPIRE_CREATION 2 + +/* The cache object. */ struct cache_item_s { ITEM next; time_t created; @@ -63,12 +75,18 @@ struct cache_item_s { struct secret_data_s *pw; cache_mode_t cache_mode; int restricted; /* The value of ctrl->restricted is part of the key. */ + struct timer_s t; char key[1]; }; /* The cache himself. */ static ITEM thecache; +/* The timer list of expiration, in active. */ +static ITEM the_timer_list; +/* Newly created entries, to be inserted into the timer list. */ +static ITEM the_timer_list_new; + /* NULL or the last cache key stored by agent_store_cache_hit. */ static char *last_stored_cache_key; @@ -193,123 +211,301 @@ new_data (const char *string, struct secret_data_s **r_data) } - -/* Check whether there are items to expire. */ static void -housekeeping (void) +insert_to_timer_list_new (ITEM entry) { - ITEM r, rprev; + entry->t.next = the_timer_list_new; + the_timer_list_new = entry; +} + +/* Insert to the active timer list. */ +static void +insert_to_timer_list (struct timespec *ts, ITEM entry) +{ + ITEM e, eprev; + + if (!the_timer_list || ts->tv_sec >= entry->t.tv_sec) + { + if (the_timer_list && ts->tv_nsec) + the_timer_list->t.tv_sec++; + + ts->tv_sec = entry->t.tv_sec; + ts->tv_nsec = 0; + + entry->t.tv_sec = 0; + entry->t.next = the_timer_list; + the_timer_list = entry; + return; + } + + entry->t.tv_sec -= ts->tv_sec; + eprev = NULL; + for (e = the_timer_list; e; e = e->t.next) + { + if (e->t.tv_sec > entry->t.tv_sec) + break; + + eprev = e; + entry->t.tv_sec -= e->t.tv_sec; + } + + entry->t.next = e; + if (e) + e->t.tv_sec -= entry->t.tv_sec; + + if (eprev) + eprev->t.next = entry; + else + the_timer_list = entry; +} + +static void +remove_from_timer_list (ITEM entry) +{ + ITEM e, eprev; + + eprev = NULL; + for (e = the_timer_list; e; e = e->t.next) + if (e != entry) + eprev = e; + else + { + if (e->t.next) + e->t.next->t.tv_sec += e->t.tv_sec; + + if (eprev) + eprev->t.next = e->t.next; + else + the_timer_list = e->t.next; + + break; + } + + entry->t.next = NULL; + entry->t.tv_sec = 0; +} + +static void +remove_from_timer_list_new (ITEM entry) +{ + ITEM e, eprev; + + eprev = NULL; + for (e = the_timer_list_new; e; e = e->t.next) + if (e != entry) + eprev = e; + else + { + if (e->t.next) + e->t.next->t.tv_sec += e->t.tv_sec; + + if (eprev) + eprev->t.next = e->t.next; + else + the_timer_list_new = e->t.next; + + break; + } + + entry->t.next = NULL; + entry->t.tv_sec = 0; +} + +static int +compute_expiration (ITEM r) +{ + unsigned long maxttl; time_t current = gnupg_get_time (); + time_t next; - /* First expire the actual data */ - for (r=thecache; r; r = r->next) + if (r->cache_mode == CACHE_MODE_PIN) + return 0; /* Don't let it expire - scdaemon explicitly flushes them. */ + + if (!r->pw) { - if (r->cache_mode == CACHE_MODE_PIN) - ; /* Don't let it expire - scdaemon explicitly flushes them. */ - else if (r->pw && r->ttl >= 0 && r->accessed + r->ttl < current) - { - if (DBG_CACHE) - log_debug (" expired '%s'.%d (%ds after last access)\n", - r->key, r->restricted, r->ttl); - release_data (r->pw); - r->pw = NULL; - r->accessed = current; - } + /* Expire an old and unused entry after 30 minutes. */ + r->t.tv_sec = 60*30; + r->t.reason = CACHE_EXPIRE_UNUSED; + return 1; } - /* Second, make sure that we also remove them based on the created - * stamp so that the user has to enter it from time to time. We - * don't do this for data items which are used to storage secrets in - * meory and are not user entered passphrases etc. */ - for (r=thecache; r; r = r->next) + switch (r->cache_mode) { - unsigned long maxttl; - - switch (r->cache_mode) - { - case CACHE_MODE_DATA: - case CACHE_MODE_PIN: - continue; /* No MAX TTL here. */ - case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break; - default: maxttl = opt.max_cache_ttl; break; - } - if (r->pw && r->created + maxttl < current) - { - if (DBG_CACHE) - log_debug (" expired '%s'.%d (%lus after creation)\n", - r->key, r->restricted, opt.max_cache_ttl); - release_data (r->pw); - r->pw = NULL; - r->accessed = current; - } + case CACHE_MODE_DATA: + case CACHE_MODE_PIN: + maxttl = 0; /* No MAX TTL here. */ + break; + case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break; + default: maxttl = opt.max_cache_ttl; break; } - /* Third, make sure that we don't have too many items in the list. - * Expire old and unused entries after 30 minutes. */ - for (rprev=NULL, r=thecache; r; ) + if (maxttl) { - if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current) + if (r->created + maxttl < current) { - ITEM r2 = r->next; - if (DBG_CACHE) - log_debug (" removed '%s'.%d (mode %d) (slot not used for 30m)\n", - r->key, r->restricted, r->cache_mode); - xfree (r); - if (!rprev) - thecache = r2; - else - rprev->next = r2; - r = r2; - } - else - { - rprev = r; - r = r->next; + r->t.tv_sec = 0; + r->t.reason = CACHE_EXPIRE_CREATION; + return 1; } + + next = r->created + maxttl - current; + } + else + next = 0; + + if (r->ttl >= 0 && (next == 0 || r->ttl < next)) + { + r->t.tv_sec = r->ttl; + r->t.reason = CACHE_EXPIRE_LAST_ACCESS; + return 1; + } + + if (next) + { + r->t.tv_sec = next; + r->t.reason = CACHE_EXPIRE_CREATION; + return 1; + } + + return 0; +} + +static void +update_expiration (ITEM entry, int is_new_entry) +{ + if (!is_new_entry) + { + remove_from_timer_list (entry); + remove_from_timer_list_new (entry); + } + + if (compute_expiration (entry)) + { + insert_to_timer_list_new (entry); + agent_kick_the_loop (); } } -#define TIMERTICK_INTERVAL (4) +/* Expire the cache entry. Returns 1 when the entry should be removed + * from the cache. */ +static int +do_expire (ITEM e) +{ + if (!e->pw) + /* Unused entry after 30 minutes. */ + return 1; + + if (e->t.reason == CACHE_EXPIRE_LAST_ACCESS) + { + if (DBG_CACHE) + log_debug (" expired '%s'.%d (%ds after last access)\n", + e->key, e->restricted, e->ttl); + } + else + { + if (DBG_CACHE) + log_debug (" expired '%s'.%d (%lus after creation)\n", + e->key, e->restricted, opt.max_cache_ttl); + } + + release_data (e->pw); + e->pw = NULL; + e->accessed = 0; + + if (compute_expiration (e)) + insert_to_timer_list_new (e); + + return 0; +} + + struct timespec * agent_cache_expiration (void) { static struct timespec abstime; static struct timespec timeout; - static int initialized = 0; + struct timespec *tp; struct timespec curtime; int res; + int expired = 0; + ITEM e, enext; - if (!initialized) - { - initialized = 1; - npth_clock_gettime (&abstime); - abstime.tv_sec += TIMERTICK_INTERVAL; - } + res = npth_mutex_lock (&cache_lock); + if (res) + log_fatal ("failed to acquire cache mutex: %s\n", strerror (res)); npth_clock_gettime (&curtime); - if (!(npth_timercmp (&curtime, &abstime, <))) + if (the_timer_list) { - /* Timeout. */ - npth_clock_gettime (&abstime); - abstime.tv_sec += TIMERTICK_INTERVAL; - - if (DBG_CACHE) - log_debug ("agent_cache_housekeeping\n"); - - res = npth_mutex_lock (&cache_lock); - if (res) - log_fatal ("failed to acquire cache mutex: %s\n", strerror (res)); - - housekeeping (); - - res = npth_mutex_unlock (&cache_lock); - if (res) - log_fatal ("failed to release cache mutex: %s\n", strerror (res)); + if (npth_timercmp (&abstime, &curtime, <)) + expired = 1; + else + npth_timersub (&abstime, &curtime, &timeout); } - npth_timersub (&abstime, &curtime, &timeout); - return &timeout; + if (expired && (e = the_timer_list) && e->t.tv_sec == 0) + { + the_timer_list = e->t.next; + e->t.next = NULL; + + if (do_expire (e)) + { + ITEM r, rprev; + + if (DBG_CACHE) + log_debug (" removed '%s'.%d (mode %d) (slot not used for 30m)\n", + e->key, e->restricted, e->cache_mode); + + rprev = NULL; + for (r = thecache; r; r = r->next) + if (r == e) + { + if (!rprev) + thecache = r->next; + else + rprev->next = r->next; + break; + } + else + rprev = r; + + remove_from_timer_list_new (e); + + xfree (e); + } + } + + if (expired || !the_timer_list) + timeout.tv_sec = timeout.tv_nsec = 0; + + for (e = the_timer_list_new; e; e = enext) + { + enext = e->t.next; + e->t.next = NULL; + insert_to_timer_list (&timeout, e); + } + the_timer_list_new = NULL; + + if (!the_timer_list) + tp = NULL; + else + { + if (the_timer_list->t.tv_sec != 0) + { + timeout.tv_sec += the_timer_list->t.tv_sec; + the_timer_list->t.tv_sec = 0; + } + + npth_timeradd (&timeout, &curtime, &abstime); + tp = &timeout; + } + + res = npth_mutex_unlock (&cache_lock); + if (res) + log_fatal ("failed to release cache mutex: %s\n", strerror (res)); + + return tp; } @@ -337,6 +533,7 @@ agent_flush_cache (int pincache_only) release_data (r->pw); r->pw = NULL; r->accessed = 0; + update_expiration (r, 0); } } @@ -381,7 +578,6 @@ agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode, if (DBG_CACHE) log_debug ("agent_put_cache '%s'.%d (mode %d) requested ttl=%d\n", key, restricted, cache_mode, ttl); - housekeeping (); if (!ttl) { @@ -433,6 +629,7 @@ agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode, err = new_data (data, &r->pw); if (err) log_error ("error replacing cache item: %s\n", gpg_strerror (err)); + update_expiration (r, 0); } } else if (data) /* Insert. */ @@ -454,6 +651,7 @@ agent_put_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode, { r->next = thecache; thecache = r; + update_expiration (r, 1); } } if (err) @@ -501,7 +699,6 @@ agent_get_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode) log_debug ("agent_get_cache '%s'.%d (mode %d)%s ...\n", key, restricted, cache_mode, last_stored? " (stored cache key)":""); - housekeeping (); for (r=thecache; r; r = r->next) { @@ -523,7 +720,10 @@ agent_get_cache (ctrl_t ctrl, const char *key, cache_mode_t cache_mode) * below. Note also that we don't update the accessed time * for data items. */ if (r->cache_mode != CACHE_MODE_DATA) - r->accessed = gnupg_get_time (); + { + r->accessed = gnupg_get_time (); + update_expiration (r, 0); + } if (DBG_CACHE) log_debug ("... hit\n"); if (r->pw->totallen < 32) From 776876ce1c4c5da3a0fe1dc538fc7a67cf18c054 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 31 Aug 2023 11:13:38 +0200 Subject: [PATCH 168/869] gpgsm: Add --always-trust feature. * sm/gpgsm.h (opt): Re-purpose unused flag always_trust. (struct server_control_s): Add "always_trust". (VALIDATE_FLAG_BYPASS): New. * sm/gpgsm.c (oAlwaysTrust): New. (opts): Add "--always-trust" (main): Set option. * sm/server.c (option_handler): Add option "always-trust". (reset_notify): Clear that option. (cmd_encrypt): Ditto. (cmd_getinfo): Add sub-command always-trust. * sm/certchain.c (gpgsm_validate_chain): Handle VALIDATE_FLAG_BYPASS. * sm/certlist.c (gpgsm_add_to_certlist): Set that flag for recipients in always-trust mode. -- GnuPG-bug-id: 6559 --- doc/gpgsm.texi | 20 ++++++++++++++++++++ sm/certchain.c | 14 +++++++++++--- sm/certlist.c | 8 +++++++- sm/gpgsm.c | 13 +++++++++++++ sm/gpgsm.h | 10 ++++++++-- sm/server.c | 21 ++++++++++++++++++++- 6 files changed, 79 insertions(+), 7 deletions(-) diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index e976767f6..497b33203 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -732,6 +732,13 @@ instead to make sure that the gpgsm process exits with a failure if the compliance rules are not fulfilled. Note that this option has currently an effect only in "de-vs" mode. +@item --always-trust +@opindex always-trust +Force encryption to the specified certificates without any validation +of the certificate chain. The only requirement is that the +certificate is capable of encryption. Note that this option is +ineffective if @option{--require-compliance} is used. + @item --ignore-cert-with-oid @var{oid} @opindex ignore-cert-with-oid Add @var{oid} to the list of OIDs to be checked while reading @@ -1622,6 +1629,10 @@ The leading two dashes usually used with @var{opt} shall not be given. Return OK if the connection is in offline mode. This may be either due to a @code{OPTION offline=1} or due to @command{gpgsm} being started with option @option{--disable-dirmngr}. +@item always-trust +Returns OK of the connection is in always-trust mode. That is either +@option{--always-trust} or @option{GPGSM OPTION always-trust} are +active. @end table @node GPGSM OPTION @@ -1728,6 +1739,15 @@ If @var{value} is true or @var{value} is not given all network access is disabled for this session. This is the same as the command line option @option{--disable-dirmngr}. +@item always-trust +If @var{value} is true or @var{value} is not given encryption to the +specified certificates is forced without any validation of the +certificate chain. The only requirement is that the certificates are +capable of encryption. If set to false the standard behaviour is +re-established. This option is cleared by a RESET and after each +encrypt operation. Note that this option is ignored if +@option{--always-trust} or @option{--require-compliance} are used. + @item input-size-hint This is the same as the @option{--input-size-hint} command line option. diff --git a/sm/certchain.c b/sm/certchain.c index 84dbed696..9d0fe684b 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -2199,9 +2199,15 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime, memset (&rootca_flags, 0, sizeof rootca_flags); - rc = do_validate_chain (ctrl, cert, checktime, - r_exptime, listmode, listfp, flags, - &rootca_flags); + if ((flags & VALIDATE_FLAG_BYPASS)) + { + *retflags |= VALIDATE_FLAG_BYPASS; + rc = 0; + } + else + rc = do_validate_chain (ctrl, cert, checktime, + r_exptime, listmode, listfp, flags, + &rootca_flags); if (!rc && (flags & VALIDATE_FLAG_STEED)) { *retflags |= VALIDATE_FLAG_STEED; @@ -2223,6 +2229,8 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime, if (opt.verbose) do_list (0, listmode, listfp, _("validation model used: %s"), + (*retflags & VALIDATE_FLAG_BYPASS)? + "bypass" : (*retflags & VALIDATE_FLAG_STEED)? "steed" : (*retflags & VALIDATE_FLAG_CHAIN_MODEL)? diff --git a/sm/certlist.c b/sm/certlist.c index fdf31a198..53d90ac30 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -448,6 +448,11 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, if (!rc && !is_cert_in_certlist (cert, *listaddr)) { + unsigned int valflags = 0; + + if (!secret && (opt.always_trust || ctrl->always_trust)) + valflags |= VALIDATE_FLAG_BYPASS; + if (!rc && secret) { char *p; @@ -461,9 +466,10 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, xfree (p); } } + if (!rc) rc = gpgsm_validate_chain (ctrl, cert, GNUPG_ISOTIME_NONE, NULL, - 0, NULL, 0, NULL); + 0, NULL, valflags, NULL); if (!rc) { certlist_t cl = xtrycalloc (1, sizeof *cl); diff --git a/sm/gpgsm.c b/sm/gpgsm.c index ce977413d..b3d48abce 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -215,6 +215,7 @@ enum cmd_and_opt_values { oRequireCompliance, oCompatibilityFlags, oKbxBufferSize, + oAlwaysTrust, oNoAutostart }; @@ -417,6 +418,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"), ARGPARSE_s_n (oNoRandomSeedFile, "no-random-seed-file", "@"), ARGPARSE_s_n (oRequireCompliance, "require-compliance", "@"), + ARGPARSE_s_n (oAlwaysTrust, "always-trust", "@"), ARGPARSE_header (NULL, N_("Options for unattended use")), @@ -1499,6 +1501,7 @@ main ( int argc, char **argv) case oMinRSALength: opt.min_rsa_length = pargs.r.ret_ulong; break; case oRequireCompliance: opt.require_compliance = 1; break; + case oAlwaysTrust: opt.always_trust = 1; break; case oKbxBufferSize: keybox_set_buffersize (pargs.r.ret_ulong, 0); @@ -1588,10 +1591,20 @@ main ( int argc, char **argv) if (may_coredump && !opt.quiet) log_info (_("WARNING: program may create a core file!\n")); + if (opt.require_compliance && opt.always_trust) + { + opt.always_trust = 0; + if (opt.quiet) + log_info (_("WARNING: %s overrides %s\n"), + "--require-compliance","--always-trust"); + } + + npth_init (); assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); + /* if (opt.qualsig_approval && !opt.quiet) */ /* log_info (_("This software has officially been approved to " */ /* "create and verify\n" */ diff --git a/sm/gpgsm.h b/sm/gpgsm.h index e1aca8bb7..a22327edc 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -116,8 +116,6 @@ struct int extra_digest_algo; /* A digest algorithm also used for verification of signatures. */ - int always_trust; /* Trust the given keys even if there is no - valid certification chain */ int skip_verify; /* do not check signatures on data */ int lock_once; /* Keep lock once they are set */ @@ -164,6 +162,10 @@ struct * mode. */ int require_compliance; + /* Enable always-trust mode - note that there is also server option + * for this. */ + int always_trust; + /* Enable creation of authenticode signatures. */ int authenticode; @@ -269,6 +271,9 @@ struct server_control_s 2 := STEED model. */ int offline; /* If true gpgsm won't do any network access. */ + int always_trust; /* True in always-trust mode; see also + * opt.always-trust. */ + /* The current time. Used as a helper in certchain.c. */ ksba_isotime_t current_time; @@ -388,6 +393,7 @@ int gpgsm_create_cms_signature (ctrl_t ctrl, #define VALIDATE_FLAG_NO_DIRMNGR 1 #define VALIDATE_FLAG_CHAIN_MODEL 2 #define VALIDATE_FLAG_STEED 4 +#define VALIDATE_FLAG_BYPASS 8 /* No actual validation. */ gpg_error_t gpgsm_walk_cert_chain (ctrl_t ctrl, ksba_cert_t start, ksba_cert_t *r_next); diff --git a/sm/server.c b/sm/server.c index b545c1bfb..184ec9379 100644 --- a/sm/server.c +++ b/sm/server.c @@ -287,6 +287,17 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) ctrl->offline = i; } } + else if (!strcmp (key, "always-trust")) + { + /* We ignore this option if gpgsm has been started with + --always-trust (which also sets offline) and if + --require-compliance is active */ + if (!opt.always_trust && !opt.require_compliance) + { + int i = *value? !!atoi (value) : 1; + ctrl->always_trust = i; + } + } else if (!strcmp (key, "request-origin")) { if (!opt.request_origin) @@ -320,6 +331,7 @@ reset_notify (assuan_context_t ctx, char *line) gpgsm_release_certlist (ctrl->server_local->signerlist); ctrl->server_local->recplist = NULL; ctrl->server_local->signerlist = NULL; + ctrl->always_trust = 0; close_message_fd (ctrl); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); @@ -488,6 +500,7 @@ cmd_encrypt (assuan_context_t ctx, char *line) gpgsm_release_certlist (ctrl->server_local->recplist); ctrl->server_local->recplist = NULL; + ctrl->always_trust = 0; /* Close and reset the fd */ close_message_fd (ctrl); assuan_close_input_fd (ctx); @@ -1189,7 +1202,8 @@ static const char hlp_getinfo[] = " agent-check - Return success if the agent is running.\n" " cmd_has_option CMD OPT\n" " - Returns OK if the command CMD implements the option OPT.\n" - " offline - Returns OK if the connection is in offline mode."; + " offline - Returns OK if the connection is in offline mode." + " always-trust- Returns OK if the connection is in always-trust mode."; static gpg_error_t cmd_getinfo (assuan_context_t ctx, char *line) { @@ -1248,6 +1262,11 @@ cmd_getinfo (assuan_context_t ctx, char *line) { rc = ctrl->offline? 0 : gpg_error (GPG_ERR_FALSE); } + else if (!strcmp (line, "always-trust")) + { + rc = (ctrl->always_trust || opt.always_trust)? 0 + /**/ : gpg_error (GPG_ERR_FALSE); + } else rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); From 57125d3f5a3fcef1b7730bd5685162f485e4e95d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 1 Sep 2023 11:00:44 +0900 Subject: [PATCH 169/869] agent: Fix the previous commit. * agent/cache.c (remove_from_timer_list_new): Fix cut&paste error. TV_SEC field should not be touched. -- Signed-off-by: NIIBE Yutaka --- agent/cache.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/agent/cache.c b/agent/cache.c index 9ed3cb195..16a21bd77 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -296,9 +296,6 @@ remove_from_timer_list_new (ITEM entry) eprev = e; else { - if (e->t.next) - e->t.next->t.tv_sec += e->t.tv_sec; - if (eprev) eprev->t.next = e->t.next; else From 5e47d5edd8f854d4905985105991603f106ed16b Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 1 Sep 2023 11:28:44 +0900 Subject: [PATCH 170/869] agent: Fix timer list management. * agent/cache.c (insert_to_timer_list): Update TV_SEC of the top entry when inserted. -- Signed-off-by: NIIBE Yutaka --- agent/cache.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/agent/cache.c b/agent/cache.c index 16a21bd77..0525e3b09 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -226,8 +226,12 @@ insert_to_timer_list (struct timespec *ts, ITEM entry) if (!the_timer_list || ts->tv_sec >= entry->t.tv_sec) { - if (the_timer_list && ts->tv_nsec) - the_timer_list->t.tv_sec++; + if (the_timer_list) + { + the_timer_list->t.tv_sec += ts->tv_sec - entry->t.tv_sec; + if (ts->tv_nsec) + the_timer_list->t.tv_sec++; + } ts->tv_sec = entry->t.tv_sec; ts->tv_nsec = 0; From 28364affa64ef9b3734b7af67062f96cca62a062 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 4 Sep 2023 10:34:42 +0900 Subject: [PATCH 171/869] agent: Fix sock_inotify_fd handling. * agent/gpg-agent.c (handle_connections): Also check SOCK_INOTIFY_FD when spawning check_onw_socket_thread. When removal of the socket is detected, do same as AGENT_PROBLEM_SOCKET_TAKEOVER. -- GnuPG-bug-id: 6692 Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 8c7f08c22..b7863cbbe 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -3055,7 +3055,7 @@ handle_connections (gnupg_fd_t listen_fd, have_homedir_inotify = 1; #if CHECK_OWN_SOCKET_INTERVAL > 0 - if (!disable_check_own_socket) + if (!disable_check_own_socket && sock_inotify_fd == -1) { npth_t thread; @@ -3255,7 +3255,10 @@ handle_connections (gnupg_fd_t listen_fd, && FD_ISSET (sock_inotify_fd, &read_fdset) && gnupg_inotify_has_name (sock_inotify_fd, GPG_AGENT_SOCK_NAME)) { - shutdown_pending = 1; + /* We may not remove the socket (if any), as it may be now + in use by another server. */ + inhibit_socket_removal = 1; + shutdown_pending = 2; close (sock_inotify_fd); sock_inotify_fd = -1; log_info ("socket file has been removed - shutting down\n"); From d90f1e5fa4d18c5e6467f9f1450b869dad67c426 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 4 Sep 2023 12:00:29 +0900 Subject: [PATCH 172/869] agent: Fix timer round-up check when inserting an entry into cache. * agent/cache.c (insert_to_timer_list): Round up when >= a half second. -- Signed-off-by: NIIBE Yutaka --- agent/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/cache.c b/agent/cache.c index 0525e3b09..e8544205f 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -229,7 +229,7 @@ insert_to_timer_list (struct timespec *ts, ITEM entry) if (the_timer_list) { the_timer_list->t.tv_sec += ts->tv_sec - entry->t.tv_sec; - if (ts->tv_nsec) + if (ts->tv_nsec >= 500000000) the_timer_list->t.tv_sec++; } From 1be7882344c5b3eae35539f6c3f490df197574bf Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 4 Sep 2023 16:34:55 +0200 Subject: [PATCH 173/869] gpg: Add option --with-v5-fingerprint * g10/gpg.c (oWithV5Fingerprint): New. (opts): Add new option. (main): Set option. * g10/options.h (opt): Add with_v5_fingerprint. * g10/keyid.c (hash_public_key): Factor out to ... (do_hash_public_key): this. Add new arg to foce v5 style hashing. (v5_fingerprint_from_pk): New. (v5hexfingerprint): New. * g10/keylist.c (print_fingerprint): Print v5 fingerprint for v4 keys if the option is set. -- GnuPG-bug-id: 6705 --- doc/gpg.texi | 5 +++ g10/gpg.c | 13 ++++++++ g10/keydb.h | 2 ++ g10/keyid.c | 84 +++++++++++++++++++++++++++++++++++++++++++++------ g10/keylist.c | 6 ++++ g10/options.h | 1 + 6 files changed, 102 insertions(+), 9 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 15b3243d0..ce72afbf5 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2849,6 +2849,11 @@ achieved by using the @option{--with-fingerprint} twice but by using this option along with keyid-format "none" a compact fingerprint is printed. +@item --with-v5-fingerprint +@opindex with-v5-fingerprint +In a colon mode listing emit "fp2" lines for version 4 OpenPGP keys +having a v5 style fingerprint of the key. + @item --with-icao-spelling @opindex with-icao-spelling Print the ICAO spelling of the fingerprint in addition to the hex digits. diff --git a/g10/gpg.c b/g10/gpg.c index 54e74f5b1..ec6af0eb9 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -203,6 +203,7 @@ enum cmd_and_opt_values oAskCertLevel, oNoAskCertLevel, oFingerprint, + oWithV5Fingerprint, oWithFingerprint, oWithSubkeyFingerprint, oWithICAOSpelling, @@ -816,6 +817,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"), ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"), ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"), + ARGPARSE_s_n (oWithV5Fingerprint, "with-v5-fingerprint", "@"), ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"), ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprint", "@"), ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"), @@ -2887,6 +2889,9 @@ main (int argc, char **argv) opt_log_time = 1; break; + case oWithV5Fingerprint: + opt.with_v5_fingerprint = 1; + break; case oWithFingerprint: opt.with_fingerprint = 1; opt.fingerprint++; @@ -3791,6 +3796,14 @@ main (int argc, char **argv) g10_exit(2); } + /* Set depended fingerprint options. */ + if (opt.with_v5_fingerprint && !opt.with_fingerprint) + { + opt.with_fingerprint = 1; + if (!opt.fingerprint) + opt.fingerprint = 1; + } + /* Process common component options. */ if (parse_comopt (GNUPG_MODULE_NAME_GPG, debug_argparser)) { diff --git a/g10/keydb.h b/g10/keydb.h index 1a66d664e..b18f6e93a 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -570,8 +570,10 @@ const char *colon_datestr_from_pk (PKT_public_key *pk); const char *colon_datestr_from_sig (PKT_signature *sig); const char *colon_expirestr_from_sig (PKT_signature *sig); byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len ); +byte *v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len); void fpr20_from_pk (PKT_public_key *pk, byte array[20]); char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen); +char *v5hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen); char *format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen); gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array); diff --git a/g10/keyid.c b/g10/keyid.c index 7cf9803e2..1dbcd3e0e 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -2,7 +2,7 @@ * Copyright (C) 1998, 1999, 2000, 2001, 2003, * 2004, 2006, 2010 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch - * Copyright (C) 2016 g10 Code GmbH + * Copyright (C) 2016, 2023 g10 Code GmbH * * This file is part of GnuPG. * @@ -18,6 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . + * SPDX-License-Identifier: GPL-3.0-or-later */ #include @@ -144,10 +145,11 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize) } -/* Hash a public key. This function is useful for v4 and v5 - * fingerprints and for v3 or v4 key signing. */ -void -hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) +/* 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. */ +static void +do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5) { unsigned int n; unsigned int nn[PUBKEY_MAX_NPKEY]; @@ -156,9 +158,8 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) unsigned int nbits; size_t nbytes; int npkey = pubkey_get_npkey (pk->pubkey_algo); - int is_v5 = pk->version == 5; - n = is_v5? 10 : 6; + n = use_v5? 10 : 6; /* FIXME: We can avoid the extra malloc by calling only the first mpi_print here which computes the required length and calling the real mpi_print only at the end. The speed advantage would only be @@ -235,13 +236,14 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) } } - if (is_v5) + if (use_v5) { gcry_md_putc ( md, 0x9a ); /* ctb */ gcry_md_putc ( md, n >> 24 ); /* 4 byte length header */ gcry_md_putc ( md, n >> 16 ); gcry_md_putc ( md, n >> 8 ); gcry_md_putc ( md, n ); + /* Note that the next byte may either be 4 or 5. */ gcry_md_putc ( md, pk->version ); } else @@ -258,7 +260,7 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) gcry_md_putc ( md, pk->pubkey_algo ); - if (is_v5) + if (use_v5) { n -= 10; gcry_md_putc ( md, n >> 24 ); @@ -285,6 +287,15 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) } +/* Hash a public key. This function is useful for v4 and v5 + * fingerprints and for v3 or v4 key signing. */ +void +hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) +{ + do_hash_public_key (md, pk, pk->version); +} + + /* fixme: Check whether we can replace this function or if not describe why we need it. */ u32 @@ -893,6 +904,37 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len) } +/* + * Return a byte array with the fingerprint for the given PK/SK The + * length of the array is returned in ret_len. Caller must free the + * array or provide an array of length MAX_FINGERPRINT_LEN. This + * version creates a v5 fingerprint even vor v4 keys. + */ +byte * +v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len) +{ + const byte *dp; + gcry_md_hd_t md; + + if (pk->version == 5) + return fingerprint_from_pk (pk, array, ret_len); + + if (gcry_md_open (&md, GCRY_MD_SHA256, 0)) + BUG (); + do_hash_public_key (md, pk, 1); + gcry_md_final (md); + dp = gcry_md_read (md, 0); + if (!array) + array = xmalloc (32); + memcpy (array, dp, 32); + gcry_md_close (md); + + if (ret_len) + *ret_len = 32; + return array; +} + + /* * Get FPR20 for the given PK/SK into ARRAY. * @@ -952,6 +994,30 @@ hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen) } +/* Same as hexfingerprint but returns a v5 fingerprint also for a v4 + * key. */ +char * +v5hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen) +{ + char fprbuf[32]; + + if (pk->version == 5) + return hexfingerprint (pk, buffer, buflen); + + if (!buffer) + { + buffer = xtrymalloc (2 * 32 + 1); + if (!buffer) + return NULL; + } + else if (buflen < 2 * 32 + 1) + log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen); + + v5_fingerprint_from_pk (pk, fprbuf, NULL); + return bin2hex (fprbuf, 32, buffer); +} + + /* Pretty print a hex fingerprint. If BUFFER is NULL the result is a malloc'd string. If BUFFER is not NULL the result will be copied into this buffer. In the latter case BUFLEN describes the length diff --git a/g10/keylist.c b/g10/keylist.c index 8b7c597cb..d0ebfc86f 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -2413,6 +2413,12 @@ print_fingerprint (ctrl_t ctrl, estream_t override_fp, if (with_colons && !mode) { es_fprintf (fp, "fpr:::::::::%s:", hexfpr); + if (opt.with_v5_fingerprint && pk->version == 4) + { + char *v5fpr = v5hexfingerprint (pk, NULL, 0); + es_fprintf (fp, "\nfp2:::::::::%s:", v5fpr); + xfree (v5fpr); + } } else if (compact && !opt.fingerprint && !opt.with_fingerprint) { diff --git a/g10/options.h b/g10/options.h index 327a6a06f..5326ac8d8 100644 --- a/g10/options.h +++ b/g10/options.h @@ -79,6 +79,7 @@ struct int with_colons; int with_key_data; int with_icao_spelling; /* Print ICAO spelling with fingerprints. */ + int with_v5_fingerprint; /* Option --with-v5-fingerprint active. */ int with_fingerprint; /* Option --with-fingerprint active. */ int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active. */ int with_keygrip; /* Option --with-keygrip active. */ From 1f76cbca35133969ccccfa324d633556e19a386c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 4 Sep 2023 16:34:55 +0200 Subject: [PATCH 174/869] gpg: Add option --with-v5-fingerprint * g10/gpg.c (oWithV5Fingerprint): New. (opts): Add new option. (main): Set option. * g10/options.h (opt): Add with_v5_fingerprint. * g10/keyid.c (hash_public_key): Factor out to ... (do_hash_public_key): this. Add new arg to foce v5 style hashing. (v5_fingerprint_from_pk): New. (v5hexfingerprint): New. * g10/keylist.c (print_fingerprint): Print v5 fingerprint for v4 keys if the option is set. -- GnuPG-bug-id: 6705 --- doc/gpg.texi | 5 +++ g10/gpg.c | 13 ++++++++ g10/keydb.h | 2 ++ g10/keyid.c | 84 +++++++++++++++++++++++++++++++++++++++++++++------ g10/keylist.c | 6 ++++ g10/options.h | 1 + 6 files changed, 102 insertions(+), 9 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 15b3243d0..ce72afbf5 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2849,6 +2849,11 @@ achieved by using the @option{--with-fingerprint} twice but by using this option along with keyid-format "none" a compact fingerprint is printed. +@item --with-v5-fingerprint +@opindex with-v5-fingerprint +In a colon mode listing emit "fp2" lines for version 4 OpenPGP keys +having a v5 style fingerprint of the key. + @item --with-icao-spelling @opindex with-icao-spelling Print the ICAO spelling of the fingerprint in addition to the hex digits. diff --git a/g10/gpg.c b/g10/gpg.c index 2ae3750a9..cb6e42e3c 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -203,6 +203,7 @@ enum cmd_and_opt_values oAskCertLevel, oNoAskCertLevel, oFingerprint, + oWithV5Fingerprint, oWithFingerprint, oWithSubkeyFingerprint, oWithICAOSpelling, @@ -816,6 +817,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"), ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"), ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"), + ARGPARSE_s_n (oWithV5Fingerprint, "with-v5-fingerprint", "@"), ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"), ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprint", "@"), ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"), @@ -2890,6 +2892,9 @@ main (int argc, char **argv) opt_log_time = 1; break; + case oWithV5Fingerprint: + opt.with_v5_fingerprint = 1; + break; case oWithFingerprint: opt.with_fingerprint = 1; opt.fingerprint++; @@ -3794,6 +3799,14 @@ main (int argc, char **argv) g10_exit(2); } + /* Set depended fingerprint options. */ + if (opt.with_v5_fingerprint && !opt.with_fingerprint) + { + opt.with_fingerprint = 1; + if (!opt.fingerprint) + opt.fingerprint = 1; + } + /* Process common component options. */ if (parse_comopt (GNUPG_MODULE_NAME_GPG, debug_argparser)) { diff --git a/g10/keydb.h b/g10/keydb.h index 1a66d664e..b18f6e93a 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -570,8 +570,10 @@ const char *colon_datestr_from_pk (PKT_public_key *pk); const char *colon_datestr_from_sig (PKT_signature *sig); const char *colon_expirestr_from_sig (PKT_signature *sig); byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len ); +byte *v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len); void fpr20_from_pk (PKT_public_key *pk, byte array[20]); char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen); +char *v5hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen); char *format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen); gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array); diff --git a/g10/keyid.c b/g10/keyid.c index 9191fec92..b80ee320e 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -2,7 +2,7 @@ * Copyright (C) 1998, 1999, 2000, 2001, 2003, * 2004, 2006, 2010 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch - * Copyright (C) 2016 g10 Code GmbH + * Copyright (C) 2016, 2023 g10 Code GmbH * * This file is part of GnuPG. * @@ -18,6 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . + * SPDX-License-Identifier: GPL-3.0-or-later */ #include @@ -139,10 +140,11 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize) } -/* Hash a public key. This function is useful for v4 and v5 - * fingerprints and for v3 or v4 key signing. */ -void -hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) +/* 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. */ +static void +do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5) { unsigned int n; unsigned int nn[PUBKEY_MAX_NPKEY]; @@ -151,9 +153,8 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) unsigned int nbits; size_t nbytes; int npkey = pubkey_get_npkey (pk->pubkey_algo); - int is_v5 = pk->version == 5; - n = is_v5? 10 : 6; + n = use_v5? 10 : 6; /* FIXME: We can avoid the extra malloc by calling only the first mpi_print here which computes the required length and calling the real mpi_print only at the end. The speed advantage would only be @@ -230,13 +231,14 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) } } - if (is_v5) + if (use_v5) { gcry_md_putc ( md, 0x9a ); /* ctb */ gcry_md_putc ( md, n >> 24 ); /* 4 byte length header */ gcry_md_putc ( md, n >> 16 ); gcry_md_putc ( md, n >> 8 ); gcry_md_putc ( md, n ); + /* Note that the next byte may either be 4 or 5. */ gcry_md_putc ( md, pk->version ); } else @@ -253,7 +255,7 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) gcry_md_putc ( md, pk->pubkey_algo ); - if (is_v5) + if (use_v5) { n -= 10; gcry_md_putc ( md, n >> 24 ); @@ -280,6 +282,15 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) } +/* Hash a public key. This function is useful for v4 and v5 + * fingerprints and for v3 or v4 key signing. */ +void +hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) +{ + do_hash_public_key (md, pk, pk->version); +} + + /* fixme: Check whether we can replace this function or if not describe why we need it. */ u32 @@ -888,6 +899,37 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len) } +/* + * Return a byte array with the fingerprint for the given PK/SK The + * length of the array is returned in ret_len. Caller must free the + * array or provide an array of length MAX_FINGERPRINT_LEN. This + * version creates a v5 fingerprint even vor v4 keys. + */ +byte * +v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len) +{ + const byte *dp; + gcry_md_hd_t md; + + if (pk->version == 5) + return fingerprint_from_pk (pk, array, ret_len); + + if (gcry_md_open (&md, GCRY_MD_SHA256, 0)) + BUG (); + do_hash_public_key (md, pk, 1); + gcry_md_final (md); + dp = gcry_md_read (md, 0); + if (!array) + array = xmalloc (32); + memcpy (array, dp, 32); + gcry_md_close (md); + + if (ret_len) + *ret_len = 32; + return array; +} + + /* * Get FPR20 for the given PK/SK into ARRAY. * @@ -947,6 +989,30 @@ hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen) } +/* Same as hexfingerprint but returns a v5 fingerprint also for a v4 + * key. */ +char * +v5hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen) +{ + char fprbuf[32]; + + if (pk->version == 5) + return hexfingerprint (pk, buffer, buflen); + + if (!buffer) + { + buffer = xtrymalloc (2 * 32 + 1); + if (!buffer) + return NULL; + } + else if (buflen < 2 * 32 + 1) + log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen); + + v5_fingerprint_from_pk (pk, fprbuf, NULL); + return bin2hex (fprbuf, 32, buffer); +} + + /* Pretty print a hex fingerprint. If BUFFER is NULL the result is a malloc'd string. If BUFFER is not NULL the result will be copied into this buffer. In the latter case BUFLEN describes the length diff --git a/g10/keylist.c b/g10/keylist.c index 8b7c597cb..d0ebfc86f 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -2413,6 +2413,12 @@ print_fingerprint (ctrl_t ctrl, estream_t override_fp, if (with_colons && !mode) { es_fprintf (fp, "fpr:::::::::%s:", hexfpr); + if (opt.with_v5_fingerprint && pk->version == 4) + { + char *v5fpr = v5hexfingerprint (pk, NULL, 0); + es_fprintf (fp, "\nfp2:::::::::%s:", v5fpr); + xfree (v5fpr); + } } else if (compact && !opt.fingerprint && !opt.with_fingerprint) { diff --git a/g10/options.h b/g10/options.h index 914c24849..e0ee99533 100644 --- a/g10/options.h +++ b/g10/options.h @@ -79,6 +79,7 @@ struct int with_colons; int with_key_data; int with_icao_spelling; /* Print ICAO spelling with fingerprints. */ + int with_v5_fingerprint; /* Option --with-v5-fingerprint active. */ int with_fingerprint; /* Option --with-fingerprint active. */ int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active. */ int with_keygrip; /* Option --with-keygrip active. */ From 362a6dfb0a42c41604f173f24ac0f14b03165c6f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 5 Sep 2023 08:08:54 +0200 Subject: [PATCH 175/869] gpg: Fix last commit. * g10/keyid.c (hash_public_key): Do not pass the version. -- Fixes-commit: 1f76cbca35133969ccccfa324d633556e19a386c --- g10/keyid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/keyid.c b/g10/keyid.c index b80ee320e..4a041ce0e 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -287,7 +287,7 @@ do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5) void hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) { - do_hash_public_key (md, pk, pk->version); + do_hash_public_key (md, pk, (pk->version == 5)); } From 34f812475e117c720bcb44571e80f9f8f3de6264 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 5 Sep 2023 08:08:54 +0200 Subject: [PATCH 176/869] gpg: Fix last commit. * g10/keyid.c (hash_public_key): Do not pass the version. -- Fixes-commit: 1be7882344c5b3eae35539f6c3f490df197574bf --- g10/keyid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/keyid.c b/g10/keyid.c index 1dbcd3e0e..ed76818a2 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -292,7 +292,7 @@ do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5) void hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) { - do_hash_public_key (md, pk, pk->version); + do_hash_public_key (md, pk, (pk->version == 5)); } From 0aa32e2429bb4aaae4151567dc9556a01faea637 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 6 Sep 2023 09:36:47 +0200 Subject: [PATCH 177/869] dirmngr: Allow conf files to disable default keyservers. * dirmngr/server.c (ensure_keyserver): Detect special value "none" (cmd_keyserver): Ignore "none" and "hkp://none". -- GnuPG-bug-id: 6708 --- NEWS | 3 +++ dirmngr/server.c | 22 ++++++++++++++++++---- doc/dirmngr.texi | 3 ++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 94cd00c9f..f4ecb1d64 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,9 @@ Noteworthy changes in version 2.4.3 (2023-07-04) * dirmngr: New option --ignore-crl-extensions. [T6545] + * dirmngr: Support config value "none" to disable the default + keyserver. [T6708] + * wkd: Use export-clean for gpg-wks-client's --mirror and --create commands. [rG2c7f7a5a27] diff --git a/dirmngr/server.c b/dirmngr/server.c index ee61f63d6..827c6207f 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -2202,6 +2202,7 @@ ensure_keyserver (ctrl_t ctrl) uri_item_t plain_items = NULL; uri_item_t ui; strlist_t sl; + int none_seen = 1; if (ctrl->server_local->keyservers) return 0; /* Already set for this session. */ @@ -2214,6 +2215,11 @@ ensure_keyserver (ctrl_t ctrl) for (sl = opt.keyserver; sl; sl = sl->next) { + if (!strcmp (sl->d, "none")) + { + none_seen = 1; + continue; + } err = make_keyserver_item (sl->d, &item); if (err) goto leave; @@ -2229,6 +2235,12 @@ ensure_keyserver (ctrl_t ctrl) } } + if (none_seen && !plain_items && !onion_items) + { + err = gpg_error (GPG_ERR_NO_KEYSERVER); + goto leave; + } + /* Decide which to use. Note that the session has no keyservers yet set. */ if (onion_items && !onion_items->next && plain_items && !plain_items->next) @@ -2299,8 +2311,7 @@ cmd_keyserver (assuan_context_t ctx, char *line) gpg_error_t err = 0; int clear_flag, add_flag, help_flag, host_flag, resolve_flag; int dead_flag, alive_flag; - uri_item_t item = NULL; /* gcc 4.4.5 is not able to detect that it - is always initialized. */ + uri_item_t item = NULL; clear_flag = has_option (line, "--clear"); help_flag = has_option (line, "--help"); @@ -2366,13 +2377,16 @@ cmd_keyserver (assuan_context_t ctx, char *line) if (add_flag) { - err = make_keyserver_item (line, &item); + if (!strcmp (line, "none") || !strcmp (line, "hkp://none")) + err = 0; + else + err = make_keyserver_item (line, &item); if (err) goto leave; } if (clear_flag) release_ctrl_keyservers (ctrl); - if (add_flag) + if (add_flag && item) { item->next = ctrl->server_local->keyservers; ctrl->server_local->keyservers = item; diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index fb448752a..398888e71 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -344,7 +344,8 @@ whether Tor is locally running or not. The check for a running Tor is done for each new connection. If no keyserver is explicitly configured, dirmngr will use the -built-in default of @code{https://keyserver.ubuntu.com}. +built-in default of @code{https://keyserver.ubuntu.com}. To avoid the +use of a default keyserver the value @code{none} can be used. Windows users with a keyserver running on their Active Directory may use the short form @code{ldap:///} for @var{name} to access this directory. From a02f3cc4e870bee97dfa54ba665d3db2721cdeb7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 6 Sep 2023 12:09:55 +0200 Subject: [PATCH 178/869] gpg: Fix validity of re-imported keys. * g10/trustdb.c (tdb_clear_ownertrusts): Detect stale validity records. -- GnuPG-bug-id: 6399 This problem was introduced by an actually very useful patch 2002-12-13 David Shaw [...] * import.c (import_keys_internal): Used here so we don't rebuild the trustdb if it is still clean. (import_one, chk_self_sigs): Only mark trustdb dirty if the key that is being imported has any sigs other than self-sigs. Suggested by Adrian von Bidder. [the last part] The bug exhibited itself only after signing a key, deleting that key and then re-importing the original non-signed key. --- g10/trustdb.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/g10/trustdb.c b/g10/trustdb.c index 051a534f9..e846abe82 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -730,7 +730,7 @@ tdb_check_or_update (ctrl_t ctrl) if (opt.interactive) update_trustdb (ctrl); else if (!opt.no_auto_check_trustdb) - check_trustdb (ctrl); + check_trustdb (ctrl); } } @@ -983,6 +983,7 @@ update_min_ownertrust (ctrl_t ctrl, u32 *kid, unsigned int new_trust) /* * Clear the ownertrust and min_ownertrust values. + * Also schedule a revalidation if a stale validity record exists. * * Return: True if a change actually happened. */ @@ -1016,6 +1017,26 @@ tdb_clear_ownertrusts (ctrl_t ctrl, PKT_public_key *pk) do_sync (); return 1; } + else + { + /* Check whether we have a stale RECTYPE_VALID for that key + * and if its validity ist set, schedule a revalidation. */ + ulong recno = rec.r.trust.validlist; + while (recno) + { + read_record (recno, &rec, RECTYPE_VALID); + if (rec.r.valid.validity) + break; + recno = rec.r.valid.next; + } + if (recno) + { + if (DBG_TRUST) + log_debug ("stale validity value detected" + " - scheduling check\n"); + tdb_revalidation_mark (ctrl); + } + } } else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND) { From 7f9e05d73f2ca1ecde1b7ba406d139a19d007998 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 7 Sep 2023 17:21:05 +0200 Subject: [PATCH 179/869] common: Never remove /dev/null. * common/sysutils.c (gnupg_remove): Detect /dev/null. -- GnuPG-bug-id: 6556 --- common/sysutils.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/common/sysutils.c b/common/sysutils.c index c88c02d36..90627b7c8 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -810,7 +810,12 @@ gnupg_remove (const char *fname) return -1; return 0; #else - return remove (fname); + /* It is common to use /dev/null for testing. We better don't + * remove that file. */ + if (fname && !strcmp (fname, "/dev/null")) + return 0; + else + return remove (fname); #endif } From 4fc745bc43a74f2aecd654b6b609ba188de76c25 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 11 Sep 2023 11:24:00 +0200 Subject: [PATCH 180/869] dirmngr: Relax the detection of the "none" keyserver. * dirmngr/server.c (cmd_keyserver): Ignore also hkps://none. (ensure_keyserver): Better ignore also "none" with a hkp or hpks scheme. -- GnuPG-bug-id: 6708 --- dirmngr/server.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dirmngr/server.c b/dirmngr/server.c index 827c6207f..1dbc87878 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -2215,7 +2215,11 @@ ensure_keyserver (ctrl_t ctrl) for (sl = opt.keyserver; sl; sl = sl->next) { - if (!strcmp (sl->d, "none")) + /* Frontends like Kleopatra may prefix option values without a + * scheme with "hkps://". Thus we need to check that too. + * Nobody will be mad enough to call a machine "none". */ + if (!strcmp (sl->d, "none") || !strcmp (sl->d, "hkp://none") + || !strcmp (sl->d, "hkps://none")) { none_seen = 1; continue; @@ -2377,7 +2381,8 @@ cmd_keyserver (assuan_context_t ctx, char *line) if (add_flag) { - if (!strcmp (line, "none") || !strcmp (line, "hkp://none")) + if (!strcmp (line, "none") || !strcmp (line, "hkp://none") + || !strcmp (line, "hkps://none")) err = 0; else err = make_keyserver_item (line, &item); From bf662d0f93af7524fff79116f7917d22f0259793 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson via Gnupg-devel" Date: Sat, 2 Sep 2023 09:59:43 -0700 Subject: [PATCH 181/869] gpg: Add --list-filter properties sig_expires/sig_expires_d Modelled after key_expires/key_expires_d. This should be useful to detect upcoming certification expiry, so the certifications can be renewed in advance of the expiry. Signed-off-by: Robin H. Johnson --- doc/gpg.texi | 6 ++++++ g10/import.c | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/doc/gpg.texi b/doc/gpg.texi index ce72afbf5..b666a72bc 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2715,6 +2715,12 @@ The available properties are: second is the same but given as an ISO date string, e.g. "2016-08-17". (drop-sig) + @item sig_expires + @itemx sig_expires_d + The expiration time of a signature packet or 0 if it does not + expire. The second is the same but given as an ISO date string or + an empty string e.g. "2038-01-19". + @item sig_algo A number with the public key algorithm of a signature packet. (drop-sig) diff --git a/g10/import.c b/g10/import.c index d84a083cc..c1e76c3f0 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1509,6 +1509,20 @@ impex_filter_getval (void *cookie, const char *propname) { result = dateonlystr_from_sig (sig); } + else if (!strcmp (propname, "sig_expires")) + { + snprintf (numbuf, sizeof numbuf, "%lu", (ulong)sig->expiredate); + result = numbuf; + } + else if (!strcmp (propname, "sig_expires_d")) + { + static char exdatestr[MK_DATESTR_SIZE]; + + if (sig->expiredate) + result = mk_datestr (exdatestr, sizeof exdatestr, sig->expiredate); + else + result = ""; + } else if (!strcmp (propname, "sig_algo")) { snprintf (numbuf, sizeof numbuf, "%d", sig->pubkey_algo); From 2a2846959f11053cb63c48626d6eda333868d033 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 18 Sep 2023 11:26:56 +0200 Subject: [PATCH 182/869] gpg: Fix --no-utf8-strings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * g10/gpg.c (main): Ignore --no-utf8-strings only on Windows. -- Fixes-commit: 8c41b8aac3efb78178fe1eaf52d8d1bbc44941a8 Reported-by: Ingo Klöcker --- g10/gpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/gpg.c b/g10/gpg.c index cb6e42e3c..18df7de67 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3489,7 +3489,7 @@ main (int argc, char **argv) break; case oUtf8Strings: utf8_strings = 1; break; case oNoUtf8Strings: -#ifdef HAVE_W32_SYSTEM +#ifndef HAVE_W32_SYSTEM utf8_strings = 0; #endif break; From 26939ea2227b8c05b5721cc4b1ad88117e62d468 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 26 Sep 2023 13:34:50 +0900 Subject: [PATCH 183/869] Use gpgrt_b64* API of libgpg-error. * common/Makefile.am (common_sources): Remove b64enc.c and b64dec.c. (module_maint_tests): Remove t-b64. (t_b64_LDADD): Remove. * common/util.h: Remove the internal API. * common/ssh-utils.c (get_fingerprint): Use the gpgrt_b64 API. (ssh_public_key_in_base64): Likewise. * dirmngr/crlfetch.c (my_es_read, crl_close_reader): Likewise. * dirmngr/dirmngr-client.c (data_cb, do_lookup): Likewise. * dirmngr/misc.c (armor_data): Likewise. * g10/export.c (export_one_ssh_key, export_secret_ssh_key): Likewise. * tools/gpg-card.c (cmd_writecert): Likewise. * tools/mime-parser.c (parse_message_cb, mime_parser_release) (process_part_data): Likewise. * tools/wks-util.c (wks_armor_key): Likewise. -- GnuPG-bug-id: 6734 Signed-off-by: NIIBE Yutaka --- common/Makefile.am | 5 ++--- common/ssh-utils.c | 24 ++++++++++++------------ common/util.h | 29 ----------------------------- dirmngr/crlfetch.c | 16 +++++++++------- dirmngr/dirmngr-client.c | 16 ++++++++-------- dirmngr/misc.c | 14 ++++++++++---- g10/export.c | 20 ++++++++++---------- tools/gpg-card.c | 12 +++++++----- tools/mime-parser.c | 23 ++++++++--------------- tools/wks-util.c | 15 +++++++++------ 10 files changed, 75 insertions(+), 99 deletions(-) diff --git a/common/Makefile.am b/common/Makefile.am index 0d5af3e5c..189874ab5 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -65,7 +65,7 @@ common_sources = \ homedir.c \ gettime.c gettime.h \ yesno.c \ - b64enc.c b64dec.c zb32.c zb32.h \ + zb32.c zb32.h \ convert.c \ percent.c \ mbox-util.c mbox-util.h \ @@ -169,7 +169,7 @@ module_tests += t-exectool endif if MAINTAINER_MODE -module_maint_tests = t-helpfile t-b64 +module_maint_tests = t-helpfile else module_maint_tests = endif @@ -196,7 +196,6 @@ t_gettime_LDADD = $(t_common_ldadd) t_sysutils_LDADD = $(t_common_ldadd) t_helpfile_LDADD = $(t_common_ldadd) t_sexputil_LDADD = $(t_common_ldadd) -t_b64_LDADD = $(t_common_ldadd) t_exechelp_LDADD = $(t_common_ldadd) t_exectool_LDADD = $(t_common_ldadd) t_session_env_LDADD = $(t_common_ldadd) diff --git a/common/ssh-utils.c b/common/ssh-utils.c index ab29558cf..d27e2e200 100644 --- a/common/ssh-utils.c +++ b/common/ssh-utils.c @@ -259,7 +259,7 @@ get_fingerprint (gcry_sexp_t key, int algo, } else { - struct b64state b64s; + gpgrt_b64state_t b64s; estream_t stream; char *p; long int len; @@ -273,15 +273,15 @@ get_fingerprint (gcry_sexp_t key, int algo, goto leave; } - err = b64enc_start_es (&b64s, stream, ""); - if (err) + b64s = gpgrt_b64enc_start (stream, ""); + if (!b64s) { es_fclose (stream); goto leave; } - err = b64enc_write (&b64s, - gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo)); + err = gpgrt_b64enc_write (b64s, gcry_md_read (md, algo), + gcry_md_get_algo_dlen (algo)); if (err) { es_fclose (stream); @@ -289,7 +289,7 @@ get_fingerprint (gcry_sexp_t key, int algo, } /* Finish, get the length, and close the stream. */ - err = b64enc_finish (&b64s); + err = gpgrt_b64enc_finish (b64s); len = es_ftell (stream); es_fclose (stream); if (err) @@ -566,7 +566,7 @@ ssh_public_key_in_base64 (gcry_sexp_t key, estream_t stream, const char *identifier = NULL; void *blob = NULL; size_t bloblen; - struct b64state b64_state; + gpgrt_b64state_t b64_state; algo = get_pk_algo_from_key (key); if (algo == 0) @@ -624,15 +624,15 @@ ssh_public_key_in_base64 (gcry_sexp_t key, estream_t stream, es_fprintf (stream, "%s ", identifier); - err = b64enc_start_es (&b64_state, stream, ""); - if (err) + b64_state = gpgrt_b64enc_start (stream, ""); + if (!b64_state) { es_free (blob); - return err; + return gpg_error_from_syserror (); } - err = b64enc_write (&b64_state, blob, bloblen); - b64enc_finish (&b64_state); + err = gpgrt_b64enc_write (b64_state, blob, bloblen); + gpgrt_b64enc_finish (b64_state); es_free (blob); if (err) return err; diff --git a/common/util.h b/common/util.h index 6b948510e..764030ad8 100644 --- a/common/util.h +++ b/common/util.h @@ -143,35 +143,6 @@ ssize_t read_line (FILE *fp, char **addr_of_buffer, size_t *length_of_buffer, size_t *max_length); - -/*-- b64enc.c and b64dec.c --*/ -struct b64state -{ - unsigned int flags; - int idx; - int quad_count; - FILE *fp; - estream_t stream; - char *title; - unsigned char radbuf[4]; - u32 crc; - int stop_seen:1; - int invalid_encoding:1; - gpg_error_t lasterr; -}; - -gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title); -gpg_error_t b64enc_start_es (struct b64state *state, estream_t fp, - const char *title); -gpg_error_t b64enc_write (struct b64state *state, - const void *buffer, size_t nbytes); -gpg_error_t b64enc_finish (struct b64state *state); - -gpg_error_t b64dec_start (struct b64state *state, const char *title); -gpg_error_t b64dec_proc (struct b64state *state, void *buffer, size_t length, - size_t *r_nbytes); -gpg_error_t b64dec_finish (struct b64state *state); - /*-- sexputil.c */ char *canon_sexp_to_string (const unsigned char *canon, size_t canonlen); void log_printcanon (const char *text, diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c index 5b6b648e2..620edf788 100644 --- a/dirmngr/crlfetch.c +++ b/dirmngr/crlfetch.c @@ -39,10 +39,10 @@ 2008) we need a context in the reader callback. */ struct reader_cb_context_s { - estream_t fp; /* The stream used with the ksba reader. */ - int checked:1; /* PEM/binary detection ahs been done. */ - int is_pem:1; /* The file stream is PEM encoded. */ - struct b64state b64state; /* The state used for Base64 decoding. */ + estream_t fp; /* The stream used with the ksba reader. */ + unsigned int checked:1; /* PEM/binary detection ahs been done. */ + unsigned int is_pem:1; /* The file stream is PEM encoded. */ + gpgrt_b64state_t b64state; /* The state used for Base64 decoding. */ }; @@ -126,14 +126,16 @@ my_es_read (void *opaque, char *buffer, size_t nbytes, size_t *nread) else { cb_ctx->is_pem = 1; - b64dec_start (&cb_ctx->b64state, ""); + cb_ctx->b64state = gpgrt_b64dec_start (""); + if (!cb_ctx->b64state) + return gpg_error_from_syserror (); } } if (cb_ctx->is_pem && *nread) { size_t nread2; - if (b64dec_proc (&cb_ctx->b64state, buffer, *nread, &nread2)) + if (gpgrt_b64dec_proc (cb_ctx->b64state, buffer, *nread, &nread2)) { /* EOF from decoder. */ *nread = 0; @@ -581,7 +583,7 @@ crl_close_reader (ksba_reader_t reader) es_fclose (cb_ctx->fp); /* Release the base64 decoder state. */ if (cb_ctx->is_pem) - b64dec_finish (&cb_ctx->b64state); + gpgrt_b64dec_finish (cb_ctx->b64state); /* Release the callback context. */ xfree (cb_ctx); } diff --git a/dirmngr/dirmngr-client.c b/dirmngr/dirmngr-client.c index f1059c939..ece4fbcc9 100644 --- a/dirmngr/dirmngr-client.c +++ b/dirmngr/dirmngr-client.c @@ -441,11 +441,11 @@ static gpg_error_t data_cb (void *opaque, const void *buffer, size_t length) { gpg_error_t err; - struct b64state *state = opaque; + gpgrt_b64state_t state = opaque; if (buffer) { - err = b64enc_write (state, buffer, length); + err = gpgrt_b64enc_write (state, buffer, length); if (err) log_error (_("error writing base64 encoding: %s\n"), gpg_strerror (err)); @@ -853,14 +853,14 @@ do_lookup (assuan_context_t ctx, const char *pattern) gpg_error_t err; const unsigned char *s; char *line, *p; - struct b64state state; + gpgrt_b64state_t state; if (opt.verbose) log_info (_("looking up '%s'\n"), pattern); - err = b64enc_start (&state, stdout, NULL); - if (err) - return err; + state = gpgrt_b64enc_start (es_stdout, NULL); + if (!state) + return gpg_error_from_syserror (); line = xmalloc (10 + 6 + 13 + strlen (pattern)*3 + 1); @@ -885,13 +885,13 @@ do_lookup (assuan_context_t ctx, const char *pattern) err = assuan_transact (ctx, line, - data_cb, &state, + data_cb, state, NULL, NULL, status_cb, NULL); if (opt.verbose > 1) log_info ("response of dirmngr: %s\n", err? gpg_strerror (err): "okay"); - err = b64enc_finish (&state); + err = gpgrt_b64enc_finish (state); xfree (line); return err; diff --git a/dirmngr/misc.c b/dirmngr/misc.c index 9cedf911c..d1830237d 100644 --- a/dirmngr/misc.c +++ b/dirmngr/misc.c @@ -583,7 +583,7 @@ gpg_error_t armor_data (char **r_string, const void *data, size_t datalen) { gpg_error_t err; - struct b64state b64state; + gpgrt_b64state_t b64state; estream_t fp; long length; char *buffer; @@ -595,9 +595,15 @@ armor_data (char **r_string, const void *data, size_t datalen) if (!fp) return gpg_error_from_syserror (); - if ((err=b64enc_start_es (&b64state, fp, "PGP PUBLIC KEY BLOCK")) - || (err=b64enc_write (&b64state, data, datalen)) - || (err = b64enc_finish (&b64state))) + b64state = gpgrt_b64enc_start (fp, "PGP PUBLIC KEY BLOCK"); + if (!b64state) + { + es_fclose (fp); + return gpg_error_from_syserror (); + } + + if ((err = gpgrt_b64enc_write (b64state, data, datalen)) + || (err = gpgrt_b64enc_finish (b64state))) { es_fclose (fp); return err; diff --git a/g10/export.c b/g10/export.c index b05492b32..2c6eb7bff 100644 --- a/g10/export.c +++ b/g10/export.c @@ -2706,18 +2706,18 @@ export_one_ssh_key (estream_t fp, PKT_public_key *pk) blob = get_membuf (&mb, &bloblen); if (blob) { - struct b64state b64_state; + gpgrt_b64state_t b64_state; es_fprintf (fp, "%s ", identifier); - err = b64enc_start_es (&b64_state, fp, ""); - if (err) + b64_state = gpgrt_b64enc_start (fp, ""); + if (!b64_state) { xfree (blob); goto leave; } - err = b64enc_write (&b64_state, blob, bloblen); - b64enc_finish (&b64_state); + err = gpgrt_b64enc_write (b64_state, blob, bloblen); + gpgrt_b64enc_finish (b64_state); es_fprintf (fp, " openpgp:0x%08lX\n", (ulong)keyid_from_pk (pk, NULL)); xfree (blob); @@ -2961,7 +2961,7 @@ export_secret_ssh_key (ctrl_t ctrl, const char *userid) int pkalgo; int i; gcry_mpi_t keyparam[10] = { NULL }; - struct b64state b64_state; + gpgrt_b64state_t b64_state; init_membuf_secure (&mb, 1024); init_membuf_secure (&mb2, 1024); @@ -3139,11 +3139,11 @@ export_secret_ssh_key (ctrl_t ctrl, const char *userid) goto leave; } - err = b64enc_start_es (&b64_state, fp, "OPENSSH PRIVATE_KEY"); - if (err) + b64_state = gpgrt_b64enc_start (fp, "OPENSSH PRIVATE_KEY"); + if (!b64_state) goto leave; - err = b64enc_write (&b64_state, blob, bloblen); - b64enc_finish (&b64_state); + err = gpgrt_b64enc_write (b64_state, blob, bloblen); + gpgrt_b64enc_finish (b64_state); if (err) goto leave; diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 4002cc185..12b4be25f 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -2080,13 +2080,15 @@ cmd_writecert (card_info_t info, char *argstr) && ascii_memistr (data, datalen, "-----END CERTIFICATE-----") && !memchr (data, 0, datalen) && !memchr (data, 1, datalen)) { - struct b64state b64; + gpgrt_b64state_t b64; - err = b64dec_start (&b64, ""); + b64 = gpgrt_b64dec_start (""); + if (!b64) + err = gpg_error_from_syserror (); + else + err = gpgrt_b64dec_proc (b64, data, datalen, &datalen); if (!err) - err = b64dec_proc (&b64, data, datalen, &datalen); - if (!err) - err = b64dec_finish (&b64); + err = gpgrt_b64dec_finish (b64); if (err) goto leave; } diff --git a/tools/mime-parser.c b/tools/mime-parser.c index 0db1a9c23..31f766ca5 100644 --- a/tools/mime-parser.c +++ b/tools/mime-parser.c @@ -93,7 +93,7 @@ struct mime_parser_context_s unsigned int boundary : 1; } show; - struct b64state *b64state; /* NULL or malloced Base64 decoder state. */ + gpgrt_b64state_t b64state; /* NULL or malloced Base64 decoder state. */ /* A buffer for reading a mail line, */ char line[5000]; @@ -410,15 +410,11 @@ parse_message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg) { ctx->decode_part = 2; if (ctx->b64state) - b64dec_finish (ctx->b64state); /* Reuse state. */ - else - { - ctx->b64state = xtrymalloc (sizeof *ctx->b64state); - if (!ctx->b64state) - rc = gpg_error_from_syserror (); - } - if (!rc) - rc = b64dec_start (ctx->b64state, NULL); + gpgrt_b64dec_finish (ctx->b64state); /* Release. */ + + ctx->b64state = gpgrt_b64dec_start (NULL); + if (!ctx->b64state) + rc = gpg_error_from_syserror (); } free (value); /* Right, we need a plain free. */ } @@ -528,10 +524,7 @@ mime_parser_release (mime_parser_t ctx) return; if (ctx->b64state) - { - b64dec_finish (ctx->b64state); - xfree (ctx->b64state); - } + gpgrt_b64dec_finish (ctx->b64state); xfree (ctx); } @@ -661,7 +654,7 @@ process_part_data (mime_parser_t ctx, char *line, size_t *length) else if (ctx->decode_part == 2) { log_assert (ctx->b64state); - err = b64dec_proc (ctx->b64state, line, *length, &nbytes); + err = gpgrt_b64dec_proc (ctx->b64state, line, *length, &nbytes); if (err) return err; *length = nbytes; diff --git a/tools/wks-util.c b/tools/wks-util.c index ee1305b00..49dbb6f8a 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -598,7 +598,7 @@ wks_armor_key (estream_t *r_newkey, estream_t key, const char *prefix) { gpg_error_t err; estream_t newkey; - struct b64state b64state; + gpgrt_b64state_t b64state; char buffer[4096]; size_t nread; @@ -614,16 +614,19 @@ wks_armor_key (estream_t *r_newkey, estream_t key, const char *prefix) if (prefix) es_fputs (prefix, newkey); - err = b64enc_start_es (&b64state, newkey, "PGP PUBLIC KEY BLOCK"); - if (err) - goto leave; + b64state = gpgrt_b64enc_start (newkey, "PGP PUBLIC KEY BLOCK"); + if (!b64state) + { + err = gpg_error_from_syserror (); + goto leave; + } do { nread = es_fread (buffer, 1, sizeof buffer, key); if (!nread) break; - err = b64enc_write (&b64state, buffer, nread); + err = gpgrt_b64enc_write (b64state, buffer, nread); if (err) goto leave; } @@ -634,7 +637,7 @@ wks_armor_key (estream_t *r_newkey, estream_t key, const char *prefix) goto leave; } - err = b64enc_finish (&b64state); + err = gpgrt_b64enc_finish (b64state); if (err) goto leave; From a8618fdccdab228a8bbe3efeb87223a68fa57219 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 26 Sep 2023 13:42:37 +0900 Subject: [PATCH 184/869] agent: Initialize FP for the case of error return. * agent/findkey.c (agent_write_private_key): Initialize FP. -- Signed-off-by: NIIBE Yutaka --- agent/findkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/findkey.c b/agent/findkey.c index 41f911cf8..c2f6c3d4c 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -118,7 +118,7 @@ agent_write_private_key (const unsigned char *grip, gpg_error_t err; char *fname = NULL; char *tmpfname = NULL; - estream_t fp; + estream_t fp = NULL; int newkey; nvc_t pk = NULL; gcry_sexp_t key = NULL; From 459bd577fc5f10aaa397c679af4611ef54163bd7 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 26 Sep 2023 13:43:24 +0900 Subject: [PATCH 185/869] agent,common,gpg: Use unsigned int for 1-bit field. * agent/trustlist.c (struct trustitem_s): Use unsigned int. * common/audit.c (struct log_item_s): Likewise. * g10/packet.h (struct seckey_info): Likewise. -- Signed-off-by: NIIBE Yutaka --- agent/trustlist.c | 14 +++++++------- common/audit.c | 4 ++-- g10/packet.h | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/agent/trustlist.c b/agent/trustlist.c index 330f233b8..fce23de15 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -38,14 +38,14 @@ struct trustitem_s { struct { - int disabled:1; /* This entry is disabled. */ - int for_pgp:1; /* Set by '*' or 'P' as first flag. */ - int for_smime:1; /* Set by '*' or 'S' as first flag. */ - int relax:1; /* Relax checking of root certificate + unsigned int disabled:1; /* This entry is disabled. */ + unsigned int for_pgp:1; /* Set by '*' or 'P' as first flag. */ + unsigned int for_smime:1; /* Set by '*' or 'S' as first flag. */ + unsigned int relax:1; /* Relax checking of root certificate constraints. */ - int cm:1; /* Use chain model for validation. */ - int qual:1; /* Root CA for qualified signatures. */ - int de_vs:1; /* Root CA for de-vs compliant PKI. */ + unsigned int cm:1; /* Use chain model for validation. */ + unsigned int qual:1; /* Root CA for qualified signatures. */ + unsigned int de_vs:1; /* Root CA for de-vs compliant PKI. */ } flags; unsigned char fpr[20]; /* The binary fingerprint. */ }; diff --git a/common/audit.c b/common/audit.c index ae0d45216..42a2cf6d6 100644 --- a/common/audit.c +++ b/common/audit.c @@ -45,8 +45,8 @@ struct log_item_s int intvalue; /* A logged integer value. */ char *string; /* A malloced string or NULL. */ ksba_cert_t cert; /* A certifciate or NULL. */ - int have_err:1; - int have_intvalue:1; + unsigned int have_err:1; + unsigned int have_intvalue:1; }; typedef struct log_item_s *log_item_t; diff --git a/g10/packet.h b/g10/packet.h index defd1005e..76ec78017 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -342,11 +342,11 @@ struct revoke_info /* Information pertaining to secret keys. */ struct seckey_info { - int is_protected:1; /* The secret info is protected and must */ + unsigned int is_protected:1; /* The secret info is protected and must */ /* be decrypted before use, the protected */ /* MPIs are simply (void*) pointers to memory */ /* and should never be passed to a mpi_xxx() */ - int sha1chk:1; /* SHA1 is used instead of a 16 bit checksum */ + unsigned int sha1chk:1; /* SHA1 is used instead of a 16 bit checksum */ u16 csum; /* Checksum for old protection modes. */ byte algo; /* Cipher used to protect the secret information. */ STRING2KEY s2k; /* S2K parameter. */ From 845d5e61d8e1ed4f25da424cfc5b0bb0fbb8678d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 18 Sep 2023 17:37:42 +0200 Subject: [PATCH 186/869] dirmngr: Cleanup the http module. * configure.ac (NEED_NTBTLS_VERSION): Require at least 0.2.0 so that we can remove a conditional compilation. * dirmngr/http.c (struct proxy_info_s): New. (release_proxy_info): New to keep proxy information in one object. (send_request): Factor some code out to ... (get_proxy_for_url): this, (send_request_basic_checks): this, (send_request_set_sni): this, (run_ntbtls_handshake): this, (run_gnutls_handshake): and this. -- Note that this also removes some never used code. For example the NTBTLS handshake has code taken from GNUTLS which was never used due to the different ways on how the certificates are checked. The proxy code has been factored out to make to prepare further authentication methods. The proxy_info_t was introduced for the same reason. Tested against gnutls and ntbtls builds. No proxy tests yet done, because we need more sophisticated tests anyway. GnuPG-bug-id: 5768 --- configure.ac | 2 +- dirmngr/http.c | 760 +++++++++++++++++++++++++++++-------------------- dirmngr/http.h | 2 + 3 files changed, 448 insertions(+), 316 deletions(-) diff --git a/configure.ac b/configure.ac index 953e2616f..cfe6091b5 100644 --- a/configure.ac +++ b/configure.ac @@ -67,7 +67,7 @@ NEED_KSBA_API=1 NEED_KSBA_VERSION=1.6.3 NEED_NTBTLS_API=1 -NEED_NTBTLS_VERSION=0.1.0 +NEED_NTBTLS_VERSION=0.2.0 NEED_NPTH_API=1 NEED_NPTH_VERSION=1.2 diff --git a/dirmngr/http.c b/dirmngr/http.c index 8153fcef4..2189d7249 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -230,6 +230,14 @@ static es_cookie_io_functions_t simple_cookie_functions = }; #endif +/* An object to store information about a proxy. */ +struct proxy_info_s +{ + parsed_uri_t uri; /* The parsed proxy URL. */ + int is_http_proxy; /* This is an http proxy. */ +}; +typedef struct proxy_info_s *proxy_info_t; + #if SIZEOF_UNSIGNED_LONG == 8 # define HTTP_SESSION_MAGIC 0x0068545470534553 /* "hTTpSES" */ @@ -317,13 +325,13 @@ struct http_context_s static int opt_verbose; static int opt_debug; -/* The global callback for the verification function. */ +/* The global callback for the verification function for GNUTLS. */ static gpg_error_t (*tls_callback) (http_t, http_session_t, int); -/* The list of files with trusted CA certificates. */ +/* The list of files with trusted CA certificates for GNUTLS. */ static strlist_t tls_ca_certlist; -/* The list of files with extra trusted CA certificates. */ +/* The list of files with extra trusted CA certificates for GNUTLS. */ static strlist_t cfg_ca_certlist; /* The global callback for net activity. */ @@ -596,7 +604,7 @@ http_set_verbose (int verbose, int debug) /* Register a non-standard global TLS callback function. If no verification is desired a callback needs to be registered which - always returns NULL. */ + always returns NULL. Only used for GNUTLS. */ void http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int)) { @@ -607,7 +615,7 @@ http_register_tls_callback (gpg_error_t (*cb)(http_t, http_session_t, int)) /* Register a CA certificate for future use. The certificate is expected to be in FNAME. PEM format is assume if FNAME has a suffix of ".pem". If FNAME is NULL the list of CA files is - removed. */ + removed. Only used for GNUTLS. */ void http_register_tls_ca (const char *fname) { @@ -636,7 +644,8 @@ http_register_tls_ca (const char *fname) * expected to be in FNAME. PEM format is assume if FNAME has a * suffix of ".pem". If FNAME is NULL the list of CA files is * removed. This is a variant of http_register_tls_ca which puts the - * certificate into a separate list enabled using HTTP_FLAG_TRUST_CFG. */ + * certificate into a separate list enabled using HTTP_FLAG_TRUST_CFG. + * Only used for GNUTLS. */ void http_register_cfg_ca (const char *fname) { @@ -786,6 +795,8 @@ http_session_new (http_session_t *r_session, int add_system_cas = !!(flags & HTTP_FLAG_TRUST_SYS); int is_hkps_pool; + (void)intended_hostname; + rc = gnutls_certificate_allocate_credentials (&sess->certcred); if (rc < 0) { @@ -1789,34 +1800,114 @@ is_hostname_port (const char *string) } -/* - * Send a HTTP request to the server - * Returns 0 if the request was successful - */ +/* Free the PROXY object. */ +static void +release_proxy_info (proxy_info_t proxy) +{ + if (!proxy) + return; + http_release_parsed_uri (proxy->uri); + xfree (proxy); +} + + +/* Return the proxy to be used for the URL or host specified in HD. + * If OVERRIDE_PROXY is not NULL and not empty, this proxy will be + * used instead of any configured or dynamically determined proxy. If + * the function runs into an error an error code is returned and NULL + * is stored at R_PROXY. If the fucntion was successful and a proxy + * is to be used, information on the procy is stored at R_PROXY; if no + * proxy shall be used R_PROXY is set to NULL. Caller should always + * use release_proxy_info on the value stored at R_PROXY. */ static gpg_error_t -send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, - const char *proxy, const char *srvtag, unsigned int timeout, - strlist_t headers) +get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy) { gpg_error_t err; - const char *server; - char *request, *p; - unsigned short port; - const char *http_proxy = NULL; - char *proxy_authstr = NULL; - char *authstr = NULL; - assuan_fd_t sock; - int have_http_proxy = 0; + const char *proxystr, *s; + proxy_info_t proxy; + + r_proxy = NULL; + + if (override_proxy && *override_proxy) + proxystr = override_proxy; + else if (!(hd->flags & HTTP_FLAG_TRY_PROXY)) + return 0; /* --honor-http-proxy not active */ + else if ((s = getenv (HTTP_PROXY_ENV)) && *s) + proxystr = s; +#ifdef HAVE_W32_SYSTEM +#endif + else + return 0; /* No proxy known. */ + + proxy = xtrycalloc (1, sizeof *proxy); + if (!proxy) + { + err = gpg_error_from_syserror (); + log_error ("error allocating memory for proxy\n"); + return err; + } + + err = parse_uri (&proxy->uri, proxystr, 0, 0); + if (gpg_err_code (err) == GPG_ERR_INV_URI + && is_hostname_port (proxystr)) + { + /* Retry assuming a "hostname:port" string. */ + char *tmpname = strconcat ("http://", proxystr, NULL); + if (!tmpname) + err = gpg_error_from_syserror (); + else if (!parse_uri (&proxy->uri, tmpname, 0, 0)) + err = 0; + xfree (tmpname); + } + + if (!err) + { + /* Get rid of the escapes in the authstring. */ + if (proxy->uri->auth) + remove_escapes (proxy->uri->auth); + + if (!strcmp (proxy->uri->scheme, "http")) + proxy->is_http_proxy = 1; + else if (!strcmp (proxy->uri->scheme, "socks4") + || !strcmp (proxy->uri->scheme, "socks5h")) + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + else + err = gpg_error (GPG_ERR_INV_URI); + + if (err) + { + log_error ("invalid HTTP proxy (%s): %s\n", + proxystr, gpg_strerror (err)); + err = gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION); + } + else if (opt_verbose) + log_info ("using '%s' to proxy '%s'\n", + proxystr, hd->uri? hd->uri->original : NULL); + } + + if (err) + xfree (proxy); + else + *r_proxy = proxy; + return err; +} + + +/* Some checks done by send_request. */ +static gpg_error_t +send_request_basic_checks (http_t hd) +{ + int mode; if (hd->uri->use_tls && !hd->session) { log_error ("TLS requested but no session object provided\n"); - return gpg_err_make (default_errsource, GPG_ERR_INTERNAL); + return gpg_error (GPG_ERR_INTERNAL); } if (hd->uri->use_tls && !hd->session->tls_session) { log_error ("TLS requested but no TLS context available\n"); - return gpg_err_make (default_errsource, GPG_ERR_INTERNAL); + return gpg_error (GPG_ERR_INTERNAL); } if (opt_debug) log_debug ("Using TLS library: %s %s\n", @@ -1827,37 +1918,35 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, #endif /*HTTP_USE_GNUTLS*/ ); - if ((hd->flags & HTTP_FLAG_FORCE_TOR)) + if ((hd->flags & HTTP_FLAG_FORCE_TOR) + && (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode)) { - int mode; - - if (assuan_sock_get_flag (ASSUAN_INVALID_FD, "tor-mode", &mode) || !mode) - { - log_error ("Tor support is not available\n"); - return gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED); - } - /* Non-blocking connects do not work with our Tor proxy because - * we can't continue the Socks protocol after the EINPROGRESS. - * Disable the timeout to use a blocking connect. */ - timeout = 0; + log_error ("Tor support is not available\n"); + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } - server = *hd->uri->host ? hd->uri->host : "localhost"; - port = hd->uri->port ? hd->uri->port : 80; + return 0; +} + + +/* Helper for send_request to set the servername. */ +static gpg_error_t +send_request_set_sni (http_t hd, const char *name) +{ + gpg_error_t err = 0; +# if HTTP_USE_GNUTLS + int rc; +# endif /* Try to use SNI. */ if (hd->uri->use_tls) { -#if HTTP_USE_GNUTLS - int rc; -#endif - xfree (hd->session->servername); - hd->session->servername = xtrystrdup (httphost? httphost : server); + hd->session->servername = xtrystrdup (name); if (!hd->session->servername) { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - return err; + err = gpg_error_from_syserror (); + goto leave; } #if HTTP_USE_NTBTLS @@ -1866,7 +1955,7 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, if (err) { log_info ("ntbtls_set_hostname failed: %s\n", gpg_strerror (err)); - return err; + goto leave; } #elif HTTP_USE_GNUTLS rc = gnutls_server_name_set (hd->session->tls_session, @@ -1878,175 +1967,21 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, #endif /*HTTP_USE_GNUTLS*/ } - if ( (proxy && *proxy) - || ( (hd->flags & HTTP_FLAG_TRY_PROXY) - && (http_proxy = getenv (HTTP_PROXY_ENV)) - && *http_proxy )) - { - parsed_uri_t uri; + leave: + return err; +} - if (proxy) - http_proxy = proxy; - - err = parse_uri (&uri, http_proxy, 0, 0); - if (gpg_err_code (err) == GPG_ERR_INV_URI - && is_hostname_port (http_proxy)) - { - /* Retry assuming a "hostname:port" string. */ - char *tmpname = strconcat ("http://", http_proxy, NULL); - if (tmpname && !parse_uri (&uri, tmpname, 0, 0)) - err = 0; - xfree (tmpname); - } - - if (err) - ; - else if (!strcmp (uri->scheme, "http")) - have_http_proxy = 1; - else if (!strcmp (uri->scheme, "socks4") - || !strcmp (uri->scheme, "socks5h")) - err = gpg_err_make (default_errsource, GPG_ERR_NOT_IMPLEMENTED); - else - err = gpg_err_make (default_errsource, GPG_ERR_INV_URI); - - if (err) - { - log_error ("invalid HTTP proxy (%s): %s\n", - http_proxy, gpg_strerror (err)); - return gpg_err_make (default_errsource, GPG_ERR_CONFIGURATION); - } - - if (uri->auth) - { - remove_escapes (uri->auth); - proxy_authstr = make_header_line ("Proxy-Authorization: Basic ", - "\r\n", - uri->auth, strlen(uri->auth)); - if (!proxy_authstr) - { - err = gpg_err_make (default_errsource, - gpg_err_code_from_syserror ()); - http_release_parsed_uri (uri); - return err; - } - } - - err = connect_server (ctrl, - *uri->host ? uri->host : "localhost", - uri->port ? uri->port : 80, - hd->flags, NULL, timeout, &sock); - http_release_parsed_uri (uri); - } - else - { - err = connect_server (ctrl, - server, port, hd->flags, srvtag, timeout, &sock); - } - - if (err) - { - xfree (proxy_authstr); - return err; - } - hd->sock = my_socket_new (sock); - if (!hd->sock) - { - xfree (proxy_authstr); - return gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - } - - if (have_http_proxy && hd->uri->use_tls) - { - int saved_flags; - cookie_t cookie; - - /* Try to use the CONNECT method to proxy our TLS stream. */ - request = es_bsprintf - ("CONNECT %s:%hu HTTP/1.0\r\nHost: %s:%hu\r\n%s", - httphost ? httphost : server, - port, - httphost ? httphost : server, - port, - proxy_authstr ? proxy_authstr : ""); - xfree (proxy_authstr); - proxy_authstr = NULL; - - if (! request) - return gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - - if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) - log_debug_string (request, "http.c:request:"); - - cookie = xtrycalloc (1, sizeof *cookie); - if (! cookie) - { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - xfree (request); - return err; - } - cookie->sock = my_socket_ref (hd->sock); - hd->write_cookie = cookie; - - hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); - if (! hd->fp_write) - { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - my_socket_unref (cookie->sock, NULL, NULL); - xfree (cookie); - xfree (request); - hd->write_cookie = NULL; - return err; - } - else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - - xfree (request); - request = NULL; - - /* Make sure http_wait_response doesn't close the stream. */ - saved_flags = hd->flags; - hd->flags &= ~HTTP_FLAG_SHUTDOWN; - - /* Get the response. */ - err = http_wait_response (hd); - - /* Restore flags, destroy stream. */ - hd->flags = saved_flags; - es_fclose (hd->fp_read); - hd->fp_read = NULL; - hd->read_cookie = NULL; - - /* Reset state. */ - hd->in_data = 0; - - if (err) - return err; - - if (hd->status_code != 200) - { - request = es_bsprintf - ("CONNECT %s:%hu", - httphost ? httphost : server, - port); - - log_error (_("error accessing '%s': http status %u\n"), - request ? request : "out of core", - http_get_status_code (hd)); - - xfree (request); - return gpg_error (GPG_ERR_NO_DATA); - } - - /* We are done with the proxy, the code below will establish a - * TLS session and talk directly to the target server. */ - http_proxy = NULL; - } +/* Run the NTBTLS handshake if needed. */ #if HTTP_USE_NTBTLS +static gpg_error_t +run_ntbtls_handshake (http_t hd) +{ + gpg_error_t err; + estream_t in, out; + if (hd->uri->use_tls) { - estream_t in, out; - my_socket_ref (hd->sock); /* Until we support send/recv in estream under Windows we need @@ -2060,8 +1995,7 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, if (!in) { err = gpg_error_from_syserror (); - xfree (proxy_authstr); - return err; + goto leave; } # ifdef HAVE_W32_SYSTEM @@ -2074,8 +2008,7 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, { err = gpg_error_from_syserror (); es_fclose (in); - xfree (proxy_authstr); - return err; + goto leave; } err = ntbtls_set_transport (hd->session->tls_session, in, out); @@ -2083,8 +2016,9 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, { log_info ("TLS set_transport failed: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); - xfree (proxy_authstr); - return err; + es_fclose (in); + es_fclose (out); + goto leave; } if (hd->session->verify_cb) @@ -2095,71 +2029,62 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, { log_error ("ntbtls_set_verify_cb failed: %s\n", gpg_strerror (err)); - xfree (proxy_authstr); - return err; + goto leave; } } while ((err = ntbtls_handshake (hd->session->tls_session))) { -#if NTBTLS_VERSION_NUMBER >= 0x000200 unsigned int tlevel, ttype; - const char *s = ntbtls_get_last_alert (hd->session->tls_session, - &tlevel, &ttype); + const char *s; + + s = ntbtls_get_last_alert (hd->session->tls_session, &tlevel, &ttype); if (s) log_info ("TLS alert: %s (%u.%u)\n", s, tlevel, ttype); -#endif switch (err) { default: log_info ("TLS handshake failed: %s <%s>\n", gpg_strerror (err), gpg_strsource (err)); - xfree (proxy_authstr); - return err; + goto leave; } } hd->session->verify.done = 0; - /* Try the available verify callbacks until one returns success - * or a real error. Note that NTBTLS does the verification - * during the handshake via */ - err = 0; /* Fixme check that the CB has been called. */ + /* Note that in contrast to GNUTLS NTBTLS uses a registered + * callback to run the verification as part of the handshake. */ + err = 0; + /* FIXME: We could check that the CB has been called and if not + * error out with this warning: + * if (err) + * { + * log_info ("TLS connection authentication failed: %s <%s>\n", + * gpg_strerror (err), gpg_strsource (err)); + * goto leave; + * } + */ + } + else + err = 0; - if (hd->session->verify_cb - && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR - && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED) - err = hd->session->verify_cb (hd->session->verify_cb_value, - hd, hd->session, - (hd->flags | hd->session->flags), - hd->session->tls_session); + leave: + return err; +} +#endif /*HTTP_USE_NTBTLS*/ - if (tls_callback - && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR - && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED) - err = tls_callback (hd, hd->session, 0); - if (gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR - && gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED) - err = http_verify_server_credentials (hd->session); - - if (err) - { - log_info ("TLS connection authentication failed: %s <%s>\n", - gpg_strerror (err), gpg_strsource (err)); - xfree (proxy_authstr); - return err; - } - - } - -#elif HTTP_USE_GNUTLS +/* Run the GNUTLS handshake if needed. */ +#if HTTP_USE_GNUTLS +static gpg_error_t +run_gnutls_handshake (http_t hd, const char *server) +{ + gpg_error_t err; + int rc; if (hd->uri->use_tls) { - int rc; - my_socket_ref (hd->sock); gnutls_transport_set_ptr (hd->session->tls_session, hd->sock); gnutls_transport_set_pull_function (hd->session->tls_session, @@ -2195,8 +2120,8 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, } else log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc)); - xfree (proxy_authstr); - return gpg_err_make (default_errsource, GPG_ERR_NETWORK); + err = gpg_error (GPG_ERR_NETWORK); + goto leave; } hd->session->verify.done = 0; @@ -2208,13 +2133,195 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, { log_info ("TLS connection authentication failed: %s\n", gpg_strerror (err)); - xfree (proxy_authstr); - return err; + goto leave; } } + else + err =0; + leave: + return err; +} #endif /*HTTP_USE_GNUTLS*/ + +/* + * Send a HTTP request to the server + * Returns 0 if the request was successful + */ +static gpg_error_t +send_request (ctrl_t ctrl, + http_t hd, const char *httphost, const char *auth, + const char *override_proxy, + const char *srvtag, unsigned int timeout, + strlist_t headers) +{ + gpg_error_t err; + const char *server; + char *request = NULL; + char *relpath = NULL; + unsigned short port; + int use_http_proxy = 0; + char *proxy_authstr = NULL; + char *authstr = NULL; + assuan_fd_t sock; + proxy_info_t proxy = NULL; + cookie_t cookie = NULL; + cookie_t cookie2 = NULL; + + err = send_request_basic_checks (hd); + if (err) + goto leave; + + if ((hd->flags & HTTP_FLAG_FORCE_TOR)) + { + /* Non-blocking connects do not work with our Tor proxy because + * we can't continue the Socks protocol after the EINPROGRESS. + * Disable the timeout to use a blocking connect. */ + timeout = 0; + } + + server = *hd->uri->host ? hd->uri->host : "localhost"; + port = hd->uri->port ? hd->uri->port : 80; + + if ((err = send_request_set_sni (hd, httphost? httphost : server))) + goto leave; + + if ((err = get_proxy_for_url (hd, override_proxy, &proxy))) + goto leave; + + if (proxy && proxy->is_http_proxy) + { + use_http_proxy = 1; /* We want to use a proxy for the conenction. */ + err = connect_server (ctrl, + *proxy->uri->host ? proxy->uri->host : "localhost", + proxy->uri->port ? proxy->uri->port : 80, + hd->flags, NULL, timeout, &sock); + } + else + { + err = connect_server (ctrl, + server, port, hd->flags, srvtag, timeout, &sock); + } + if (err) + goto leave; + + hd->sock = my_socket_new (sock); + if (!hd->sock) + { + err = gpg_error_from_syserror (); + goto leave; + } + +#if USE_TLS + if (use_http_proxy && hd->uri->use_tls) + { + int saved_flags; + + log_assert (!proxy_authstr); + if (proxy->uri->auth + && !(proxy_authstr = make_header_line ("Proxy-Authorization: Basic ", + "\r\n", + proxy->uri->auth, + strlen (proxy->uri->auth)))) + { + err = gpg_error_from_syserror (); + goto leave; + } + + /* Try to use the CONNECT method to proxy our TLS stream. */ + xfree (request); + request = es_bsprintf + ("CONNECT %s:%hu HTTP/1.0\r\nHost: %s:%hu\r\n%s", + httphost ? httphost : server, + port, + httphost ? httphost : server, + port, + proxy_authstr ? proxy_authstr : ""); + if (!request) + { + err = gpg_error_from_syserror (); + goto leave; + } + + if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) + log_debug_string (request, "http.c:request:"); + + cookie = xtrycalloc (1, sizeof *cookie); + if (!cookie) + { + err = gpg_error_from_syserror (); + goto leave; + } + cookie->sock = my_socket_ref (hd->sock); + hd->write_cookie = cookie; + + hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); + if (! hd->fp_write) + { + err = gpg_error_from_syserror (); + goto leave; + } + + if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) + { + err = gpg_error_from_syserror (); + goto leave; + } + + /* Make sure http_wait_response doesn't close the stream. */ + saved_flags = hd->flags; + hd->flags &= ~HTTP_FLAG_SHUTDOWN; + + /* Get the response and set hd->fp_read */ + err = http_wait_response (hd); + + /* Restore flags, destroy stream. */ + hd->flags = saved_flags; + es_fclose (hd->fp_read); + hd->fp_read = NULL; + hd->read_cookie = NULL; + + /* Reset state. */ + hd->in_data = 0; + + if (err) + goto leave; + + if (hd->status_code != 200) + { + xfree (request); + request = es_bsprintf + ("CONNECT %s:%hu", + httphost ? httphost : server, + port); + + log_error (_("error accessing '%s': http status %u\n"), + request ? request : "out of core", + http_get_status_code (hd)); + + err = gpg_error (GPG_ERR_NO_DATA); + goto leave; + } + + /* We are done with the proxy, the code below will establish a + * TLS session and talk directly to the target server. Thus we + * clear the flag to indicate this. */ + use_http_proxy = 0; + } +#endif /* USE_TLS */ + +#if HTTP_USE_NTBTLS + err = run_ntbtls_handshake (hd); +#elif HTTP_USE_GNUTLS + err = run_gnutls_handshake (hd, server); +#else + err = 0; +#endif + + if (err) + goto leave; + if (auth || hd->uri->auth) { char *myauth; @@ -2224,9 +2331,8 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, myauth = xtrystrdup (auth); if (!myauth) { - xfree (proxy_authstr); - return gpg_err_make (default_errsource, - gpg_err_code_from_syserror ()); + err = gpg_error_from_syserror (); + goto leave; } remove_escapes (myauth); } @@ -2238,27 +2344,38 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, authstr = make_header_line ("Authorization: Basic ", "\r\n", myauth, strlen (myauth)); - if (auth) + if (auth) /* (Was allocated.) */ xfree (myauth); if (!authstr) { - xfree (proxy_authstr); - return gpg_err_make (default_errsource, - gpg_err_code_from_syserror ()); + err = gpg_error_from_syserror (); + goto leave; } } - p = build_rel_path (hd->uri); - if (!p) + relpath = build_rel_path (hd->uri); + if (!relpath) { - xfree (authstr); - xfree (proxy_authstr); - return gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); + err = gpg_error_from_syserror (); + goto leave; } - if (http_proxy && *http_proxy) + if (use_http_proxy) { + xfree (proxy_authstr); + proxy_authstr = NULL; + if (proxy->uri->auth + && !(proxy_authstr = make_header_line ("Proxy-Authorization: Basic ", + "\r\n", + proxy->uri->auth, + strlen (proxy->uri->auth)))) + { + err = gpg_error_from_syserror (); + goto leave; + } + + xfree (request); request = es_bsprintf ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s", hd->req_type == HTTP_REQ_GET ? "GET" : @@ -2266,9 +2383,14 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", hd->uri->use_tls? "https" : "http", httphost? httphost : server, - port, *p == '/' ? "" : "/", p, + port, *relpath == '/' ? "" : "/", relpath, authstr ? authstr : "", proxy_authstr ? proxy_authstr : ""); + if (!request) + { + err = gpg_error_from_syserror (); + goto leave; + } } else { @@ -2279,23 +2401,21 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, else snprintf (portstr, sizeof portstr, ":%u", port); + xfree (request); request = es_bsprintf ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s", hd->req_type == HTTP_REQ_GET ? "GET" : hd->req_type == HTTP_REQ_HEAD ? "HEAD" : hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", - *p == '/' ? "" : "/", p, + *relpath == '/' ? "" : "/", relpath, httphost? httphost : server, portstr, authstr? authstr:""); - } - xfree (p); - if (!request) - { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - xfree (authstr); - xfree (proxy_authstr); - return err; + if (!request) + { + err = gpg_error_from_syserror (); + goto leave; + } } if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) @@ -2304,53 +2424,63 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth, /* First setup estream so that we can write even the first line using estream. This is also required for the sake of gnutls. */ { - cookie_t cookie; - - cookie = xtrycalloc (1, sizeof *cookie); - if (!cookie) + cookie2 = xtrycalloc (1, sizeof *cookie); + if (!cookie2) { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); + err = gpg_error_from_syserror (); goto leave; } - cookie->sock = my_socket_ref (hd->sock); - hd->write_cookie = cookie; - cookie->use_tls = hd->uri->use_tls; - cookie->session = http_session_ref (hd->session); + cookie2->sock = my_socket_ref (hd->sock); + hd->write_cookie = cookie2; + cookie2->use_tls = hd->uri->use_tls; + cookie2->session = http_session_ref (hd->session); hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); if (!hd->fp_write) { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - my_socket_unref (cookie->sock, NULL, NULL); - xfree (cookie); - hd->write_cookie = NULL; + err = gpg_error_from_syserror (); + goto leave; + } + if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) + { + err = gpg_error_from_syserror (); + goto leave; } - else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - else - err = 0; - if (!err) - { - for (;headers; headers=headers->next) - { - if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) - log_debug_string (headers->d, "http.c:request-header:"); - if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) - || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write))) - { - err = gpg_err_make (default_errsource, - gpg_err_code_from_syserror ()); - break; - } - } - } + for (;headers; headers=headers->next) + { + if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) + log_debug_string (headers->d, "http.c:request-header:"); + if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) + || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write))) + { + err = gpg_error_from_syserror (); + goto leave; + } + } } leave: + if (cookie2) + { + my_socket_unref (cookie2->sock, NULL, NULL); + if (hd) + hd->write_cookie = NULL; + xfree (cookie2); + } + if (cookie) + { + my_socket_unref (cookie->sock, NULL, NULL); + if (hd) + hd->write_cookie = NULL; + xfree (cookie); + } + es_free (request); xfree (authstr); xfree (proxy_authstr); + xfree (relpath); + release_proxy_info (proxy); return err; } @@ -3447,7 +3577,7 @@ cookie_close (void *cookie) /* Verify the credentials of the server. Returns 0 on success and - store the result in the session object. */ + store the result in the session object. Only used by GNUTLS. */ gpg_error_t http_verify_server_credentials (http_session_t sess) { diff --git a/dirmngr/http.h b/dirmngr/http.h index e60212761..2994fdfad 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -132,9 +132,11 @@ typedef gpg_error_t (*http_verify_cb_t) (void *opaque, void http_set_verbose (int verbose, int debug); +/* The next three functions are only used with GNUTLS. */ void http_register_tls_callback (gpg_error_t (*cb)(http_t,http_session_t,int)); void http_register_tls_ca (const char *fname); void http_register_cfg_ca (const char *fname); + void http_register_netactivity_cb (void (*cb)(void)); From fed33baed1cb0c4b09c48277de73becb6aef4bb1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 19 Sep 2023 12:49:04 +0200 Subject: [PATCH 187/869] dirmngr: Further simplify the http code and improve a message. * dirmngr/http.c (make_fp_write, make_fp_read): New. (http_raw_connect): Use new functions. (http_wait_response): Ditto. (send_request): Ditto. Change proxy error diagnostic. (connect_server): Improve error message for host not found. -- GnuPG-bug-id: 5768 --- dirmngr/http.c | 226 ++++++++++++++++++++++--------------------------- 1 file changed, 100 insertions(+), 126 deletions(-) diff --git a/dirmngr/http.c b/dirmngr/http.c index 2189d7249..e8b6ae4d8 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -746,6 +746,64 @@ http_session_release (http_session_t sess) } +/* Create a write stream and store it in the fp_write member. Also + * store the tls flag and the session. */ +static gpg_error_t +make_fp_write (http_t hd, int use_tls, http_session_t session) +{ + cookie_t cookie; + + cookie = xtrycalloc (1, sizeof *cookie); + if (!cookie) + return gpg_error_from_syserror (); + cookie->sock = my_socket_ref (hd->sock); + cookie->use_tls = use_tls; + if (session) + cookie->session = http_session_ref (session); + hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); + if (!hd->fp_write) + { + gpg_error_t err = gpg_error_from_syserror (); + my_socket_unref (cookie->sock, NULL, NULL); + if (session) + http_session_unref (cookie->session); + xfree (cookie); + return err; + } + hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE. */ + return 0; +} + + +/* Create a read stream and store it in the fp_read member. Also + * store the tls flag and the session. */ +static gpg_error_t +make_fp_read (http_t hd, int use_tls, http_session_t session) +{ + cookie_t cookie; + + cookie = xtrycalloc (1, sizeof *cookie); + if (!cookie) + return gpg_error_from_syserror (); + cookie->sock = my_socket_ref (hd->sock); + cookie->use_tls = use_tls; + if (session) + cookie->session = http_session_ref (session); + hd->fp_read = es_fopencookie (cookie, "r", cookie_functions); + if (!hd->fp_read) + { + gpg_error_t err = gpg_error_from_syserror (); + my_socket_unref (cookie->sock, NULL, NULL); + if (session) + http_session_unref (cookie->session); + xfree (cookie); + return err; + } + hd->read_cookie = cookie; /* Cookie now owned by FP_READ. */ + return 0; +} + + /* Create a new session object which is currently used to enable TLS * support. It may eventually allow reusing existing connections. * Valid values for FLAGS are: @@ -1038,7 +1096,6 @@ http_raw_connect (ctrl_t ctrl, http_t *r_hd, { gpg_error_t err = 0; http_t hd; - cookie_t cookie; *r_hd = NULL; @@ -1086,39 +1143,13 @@ http_raw_connect (ctrl_t ctrl, http_t *r_hd, } /* Setup estreams for reading and writing. */ - cookie = xtrycalloc (1, sizeof *cookie); - if (!cookie) - { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - goto leave; - } - cookie->sock = my_socket_ref (hd->sock); - hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); - if (!hd->fp_write) - { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - my_socket_unref (cookie->sock, NULL, NULL); - xfree (cookie); - goto leave; - } - hd->write_cookie = cookie; /* Cookie now owned by FP_WRITE. */ + err = make_fp_write (hd, 0, NULL); + if (err) + goto leave; - cookie = xtrycalloc (1, sizeof *cookie); - if (!cookie) - { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - goto leave; - } - cookie->sock = my_socket_ref (hd->sock); - hd->fp_read = es_fopencookie (cookie, "r", cookie_functions); - if (!hd->fp_read) - { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - my_socket_unref (cookie->sock, NULL, NULL); - xfree (cookie); - goto leave; - } - hd->read_cookie = cookie; /* Cookie now owned by FP_READ. */ + err = make_fp_read (hd, 0, NULL); + if (err) + goto leave; /* Register close notification to interlock the use of es_fclose in http_close and in user code. */ @@ -1190,24 +1221,9 @@ http_wait_response (http_t hd) hd->in_data = 0; /* Create a new cookie and a stream for reading. */ - cookie = xtrycalloc (1, sizeof *cookie); - if (!cookie) - return gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - cookie->sock = my_socket_ref (hd->sock); - cookie->session = http_session_ref (hd->session); - cookie->use_tls = use_tls; - - hd->read_cookie = cookie; - hd->fp_read = es_fopencookie (cookie, "r", cookie_functions); - if (!hd->fp_read) - { - err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); - my_socket_unref (cookie->sock, NULL, NULL); - http_session_unref (cookie->session); - xfree (cookie); - hd->read_cookie = NULL; - return err; - } + err = make_fp_read (hd, use_tls, hd->session); + if (err) + return err; err = parse_response (hd); @@ -2166,8 +2182,6 @@ send_request (ctrl_t ctrl, char *authstr = NULL; assuan_fd_t sock; proxy_info_t proxy = NULL; - cookie_t cookie = NULL; - cookie_t cookie2 = NULL; err = send_request_basic_checks (hd); if (err) @@ -2247,21 +2261,9 @@ send_request (ctrl_t ctrl, if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) log_debug_string (request, "http.c:request:"); - cookie = xtrycalloc (1, sizeof *cookie); - if (!cookie) - { - err = gpg_error_from_syserror (); - goto leave; - } - cookie->sock = my_socket_ref (hd->sock); - hd->write_cookie = cookie; - - hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); - if (! hd->fp_write) - { - err = gpg_error_from_syserror (); - goto leave; - } + err = make_fp_write (hd, 0, NULL); + if (err) + goto leave; if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) { @@ -2290,16 +2292,13 @@ send_request (ctrl_t ctrl, if (hd->status_code != 200) { - xfree (request); - request = es_bsprintf - ("CONNECT %s:%hu", - httphost ? httphost : server, - port); + char *tmpstr; + tmpstr = es_bsprintf ("%s:%hu", httphost ? httphost : server, port); log_error (_("error accessing '%s': http status %u\n"), - request ? request : "out of core", + tmpstr ? tmpstr : "out of core", http_get_status_code (hd)); - + xfree (tmpstr); err = gpg_error (GPG_ERR_NO_DATA); goto leave; } @@ -2318,7 +2317,6 @@ send_request (ctrl_t ctrl, #else err = 0; #endif - if (err) goto leave; @@ -2423,59 +2421,29 @@ send_request (ctrl_t ctrl, /* First setup estream so that we can write even the first line using estream. This is also required for the sake of gnutls. */ - { - cookie2 = xtrycalloc (1, sizeof *cookie); - if (!cookie2) - { - err = gpg_error_from_syserror (); - goto leave; - } - cookie2->sock = my_socket_ref (hd->sock); - hd->write_cookie = cookie2; - cookie2->use_tls = hd->uri->use_tls; - cookie2->session = http_session_ref (hd->session); + err = make_fp_write (hd, hd->uri->use_tls, hd->session); + if (err) + goto leave; - hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); - if (!hd->fp_write) - { - err = gpg_error_from_syserror (); - goto leave; - } - if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) - { - err = gpg_error_from_syserror (); - goto leave; - } + if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) + { + err = gpg_error_from_syserror (); + goto leave; + } - for (;headers; headers=headers->next) - { - if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) - log_debug_string (headers->d, "http.c:request-header:"); - if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) + for (;headers; headers=headers->next) + { + if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) + log_debug_string (headers->d, "http.c:request-header:"); + if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write))) - { - err = gpg_error_from_syserror (); - goto leave; - } - } - } + { + err = gpg_error_from_syserror (); + goto leave; + } + } leave: - if (cookie2) - { - my_socket_unref (cookie2->sock, NULL, NULL); - if (hd) - hd->write_cookie = NULL; - xfree (cookie2); - } - if (cookie) - { - my_socket_unref (cookie->sock, NULL, NULL); - if (hd) - hd->write_cookie = NULL; - xfree (cookie); - } - es_free (request); xfree (authstr); xfree (proxy_authstr); @@ -3231,8 +3199,14 @@ connect_server (ctrl_t ctrl, const char *server, unsigned short port, if (!connected) { if (!hostfound) - log_error ("can't connect to '%s': %s\n", - server, "host not found"); + { + log_error ("can't connect to '%s': %s\n", + server, "host not found"); + /* If the resolver told us "no name" translate this in this + * case to "unknown host". */ + if (gpg_err_code (last_err) == GPG_ERR_NO_NAME) + last_err = 0; + } else if (!anyhostaddr) log_error ("can't connect to '%s': %s\n", server, "no IP address for host"); From 1e120f5a8d529150cd0268eb104b8f0d84f7b5ae Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 19 Sep 2023 15:04:49 +0200 Subject: [PATCH 188/869] dirmngr: Implement automatic proxy detection on Windows. * dirmngr/http.c [W32]: Include winhttp.h (w32_get_internet_session): New. (w32_get_proxy): New. (get_proxy_for_url): Implement automatic proxy detection and fix error in last patch. (http_reinitialize): New. * dirmngr/dirmngr.c (dirmngr_sighup_action): Call reinitialize. * dirmngr/Makefile.am (NETLIBS) [W32]: Link with winhttp. -- GnuPG-bug-id: 5768 --- dirmngr/Makefile.am | 1 + dirmngr/dirmngr.c | 1 + dirmngr/http-common.h | 2 + dirmngr/http.c | 162 +++++++++++++++++++++++++++++++++++++++++- doc/dirmngr.texi | 4 +- 5 files changed, 166 insertions(+), 4 deletions(-) diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index 3846fdf35..9665b5dfd 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -68,6 +68,7 @@ AM_CFLAGS = $(USE_C99_CFLAGS) \ if HAVE_W32_SYSTEM ldap_url = ldap-url.h ldap-url.c +NETLIBS += -lwinhttp else ldap_url = endif diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 97c2dc490..f79a0f877 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -2045,6 +2045,7 @@ dirmngr_sighup_action (void) crl_cache_deinit (); cert_cache_init (hkp_cacert_filenames); crl_cache_init (); + http_reinitialize (); reload_dns_stuff (0); ks_hkp_reload (); } diff --git a/dirmngr/http-common.h b/dirmngr/http-common.h index 5e6657b16..ddb340de6 100644 --- a/dirmngr/http-common.h +++ b/dirmngr/http-common.h @@ -22,4 +22,6 @@ const char *get_default_keyserver (int name_only); +void http_reinitialize (void); + #endif /* HTTP_COMMON_H */ diff --git a/dirmngr/http.c b/dirmngr/http.c index e8b6ae4d8..7cab1c2e5 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -64,6 +64,7 @@ # include # endif # include +# include # ifndef EHOSTUNREACH # define EHOSTUNREACH WSAEHOSTUNREACH # endif @@ -1827,6 +1828,141 @@ release_proxy_info (proxy_info_t proxy) } +/* Return an http session object. If clear is set, the object is + * destroyed. On error nULL is returned. */ +#ifdef HAVE_W32_SYSTEM +static HINTERNET +w32_get_internet_session (int clear) +{ + static HINTERNET session; + + if (clear) + { + if (session) + { + WinHttpCloseHandle (session); + session = NULL; + } + return NULL; + } + + if (!session) + { + session = WinHttpOpen (L"GnuPG dirmngr", + WINHTTP_ACCESS_TYPE_NO_PROXY, + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, + 0); + if (!session) + { + log_error ("WinHttpOpen failed: %s\n", w32_strerror (-1)); + return NULL; + } + } + + return session; +} +#endif /*HAVE_W32_SYSTEM*/ + + +/* Return a proxy using a Windows API. */ +#ifdef HAVE_W32_SYSTEM +static char * +w32_get_proxy (const char *url) +{ + WINHTTP_AUTOPROXY_OPTIONS options = {0}; + WINHTTP_PROXY_INFO info; + char *result = NULL; + char *p; + wchar_t *wurl; + int defaultcfg = 0; + + wurl = utf8_to_wchar (url); + if (!wurl) + { + log_error ("utf8_to_wchar failed: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + return NULL; + } + + options.dwFlags = (WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG + | WINHTTP_AUTOPROXY_ALLOW_CM + | WINHTTP_AUTOPROXY_ALLOW_STATIC + | WINHTTP_AUTOPROXY_AUTO_DETECT + | WINHTTP_AUTOPROXY_SORT_RESULTS); + options.dwAutoDetectFlags = (WINHTTP_AUTO_DETECT_TYPE_DHCP + | WINHTTP_AUTO_DETECT_TYPE_DNS_A); + options.fAutoLogonIfChallenged = TRUE; + + if (opt_debug) + log_debug ("calling WinHttpGetProxyForUrl (%s)\n", url); + if (!WinHttpGetProxyForUrl (w32_get_internet_session (0), + wurl, &options, &info)) + { + int ec = (int)GetLastError (); + if (ec == ERROR_WINHTTP_AUTODETECTION_FAILED) + { + if (opt_debug) + log_debug ("calling WinHttpGetDefaultProxyConfiguration\n"); + if (!WinHttpGetDefaultProxyConfiguration (&info)) + { + if (opt_verbose) + log_info ("WinHttpGetDefaultProxyConfiguration failed: " + "%s (%d)\n", w32_strerror (ec), ec); + xfree (wurl); + return NULL; + } + defaultcfg = 1; + } + else + { + if (opt_verbose) + log_info ("WinHttpGetProxyForUrl failed: %s (%d)\n", + w32_strerror (ec), ec); + xfree (wurl); + return NULL; + } + } + xfree (wurl); + + if (info.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY) + { + result = wchar_to_utf8 (info.lpszProxy); + if (!result) + log_error ("wchar_to_utf8 failed: %s\n", + gpg_strerror (gpg_error_from_syserror ())); + else + { + if (opt_debug) + log_debug ("proxies to use: '%s'\n", result); + /* The returned proxies are delimited by whitespace or + * semicolons. We return only the first proxy. */ + for (p=result; *p; p++) + if (spacep (p) || *p == ';') + { + *p = 0; + break; + } + } + } + else if (info.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY) + { + /* No proxy shall be used. */ + } + else + log_error ("%s returned unexpected code %lu\n", + defaultcfg? "WinHttpGetDefaultProxyConfiguration" + :"WinHttpGetProxyForUrl", info.dwAccessType); + + if (info.lpszProxy) + GlobalFree (info.lpszProxy); + if (info.lpszProxyBypass) + GlobalFree (info.lpszProxyBypass); + return result; +} +#endif /*HAVE_W32_SYSTEM*/ + + /* Return the proxy to be used for the URL or host specified in HD. * If OVERRIDE_PROXY is not NULL and not empty, this proxy will be * used instead of any configured or dynamically determined proxy. If @@ -1838,11 +1974,14 @@ release_proxy_info (proxy_info_t proxy) static gpg_error_t get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy) { - gpg_error_t err; + gpg_error_t err = 0; const char *proxystr, *s; proxy_info_t proxy; +#ifdef HAVE_W32_SYSTEM + char *proxystrbuf = NULL; +#endif - r_proxy = NULL; + *r_proxy = NULL; if (override_proxy && *override_proxy) proxystr = override_proxy; @@ -1851,6 +1990,9 @@ get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy) else if ((s = getenv (HTTP_PROXY_ENV)) && *s) proxystr = s; #ifdef HAVE_W32_SYSTEM + else if (hd->uri && hd->uri->original + && (proxystrbuf = w32_get_proxy (hd->uri->original))) + proxystr = proxystrbuf; #endif else return 0; /* No proxy known. */ @@ -1860,7 +2002,7 @@ get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy) { err = gpg_error_from_syserror (); log_error ("error allocating memory for proxy\n"); - return err; + goto leave; } err = parse_uri (&proxy->uri, proxystr, 0, 0); @@ -1901,6 +2043,10 @@ get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy) proxystr, hd->uri? hd->uri->original : NULL); } + leave: +#ifdef HAVE_W32_SYSTEM + xfree (proxystrbuf); +#endif if (err) xfree (proxy); else @@ -3938,3 +4084,13 @@ http_status2string (unsigned int status) return ""; } + + +/* Fucntion called on SIGHUP to flush internal variables. */ +void +http_reinitialize (void) +{ +#ifdef HAVE_W32_SYSTEM + w32_get_internet_session (1); /* Clear our session. */ +#endif /*HAVE_W32_SYSTEM*/ +} diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 398888e71..cd7969828 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -427,7 +427,9 @@ force the use of the default responder. @item --honor-http-proxy @opindex honor-http-proxy If the environment variable @env{http_proxy} has been set, use its -value to access HTTP servers. +value to access HTTP servers. If on Windows the option is used but +the environment variable is not set, the proxy settings are taken +from the system. @item --http-proxy @var{host}[:@var{port}] @opindex http-proxy From 668deeded9742e811a786f97a917c59793fcd9ff Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 19 Sep 2023 16:14:01 +0200 Subject: [PATCH 189/869] dirmngr: Improve error codes returned from http fetching. * dirmngr/ks-engine-http.c (ks_http_fetch): Return better error codes. * dirmngr/ks-engine-hkp.c (send_request): Ditto. * dirmngr/t-http.c (main): New option --try-proxy. --- dirmngr/ks-engine-hkp.c | 17 ++++++++--------- dirmngr/ks-engine-http.c | 12 +++++++----- dirmngr/t-http.c | 5 +++++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 66291bc02..a75cc1aee 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1340,18 +1340,17 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, } goto once_more; - case 501: - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - goto leave; - - case 413: /* Payload too large */ - err = gpg_error (GPG_ERR_TOO_LARGE); - goto leave; - default: log_error (_("error accessing '%s': http status %u\n"), request, http_get_status_code (http)); - err = gpg_error (GPG_ERR_NO_DATA); + switch (http_get_status_code (http)) + { + case 401: err = gpg_error (GPG_ERR_NO_AUTH); break; + case 407: err = gpg_error (GPG_ERR_BAD_AUTH); break; + case 413: err = gpg_error (GPG_ERR_TOO_LARGE); break; + case 501: err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); break; + default: err = gpg_error (GPG_ERR_NO_DATA); break; + } goto leave; } diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 3dca80ee6..48a734786 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -193,14 +193,16 @@ ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags, } goto once_more; - case 413: /* Payload too large */ - err = gpg_error (GPG_ERR_TOO_LARGE); - goto leave; - default: log_error (_("error accessing '%s': http status %u\n"), url, http_get_status_code (http)); - err = gpg_error (GPG_ERR_NO_DATA); + switch (http_get_status_code (http)) + { + case 401: err = gpg_error (GPG_ERR_NO_AUTH); break; + case 407: err = gpg_error (GPG_ERR_BAD_AUTH); break; + case 413: err = gpg_error (GPG_ERR_TOO_LARGE); break; + default: err = gpg_error (GPG_ERR_NO_DATA); break; + } goto leave; } diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index 7f3aa005d..f9c59783f 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -288,6 +288,11 @@ main (int argc, char **argv) my_http_flags |= HTTP_FLAG_FORCE_TOR; argc--; argv++; } + else if (!strcmp (*argv, "--try-proxy")) + { + my_http_flags |= HTTP_FLAG_TRY_PROXY; + argc--; argv++; + } else if (!strcmp (*argv, "--no-out")) { no_out = 1; From 3054016db9da31f3c18aed8158f764b14e021754 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 21 Sep 2023 13:32:56 +0200 Subject: [PATCH 190/869] dirmngr: Require gnutls 3.2 * dirmngr/http.c: Remove gnutls version specific code. (send_request): Factor some code out to ... (run_proxy_connect): new. (mk_proxy_request): new. (mk_std_request): new. * configure.ac (NEED_GNUTLS_VERSION): Require 3.2. -- This patch is to factor out some code and also to remove support for legacy gnutls versions. Note that gnutls 3.2 was released 10 years ago. --- configure.ac | 2 +- dirmngr/http.c | 331 ++++++++++++++++++++++++++++--------------------- 2 files changed, 194 insertions(+), 139 deletions(-) diff --git a/configure.ac b/configure.ac index cfe6091b5..6f544bf98 100644 --- a/configure.ac +++ b/configure.ac @@ -73,7 +73,7 @@ NEED_NPTH_API=1 NEED_NPTH_VERSION=1.2 -NEED_GNUTLS_VERSION=3.0 +NEED_GNUTLS_VERSION=3.2 NEED_SQLITE_VERSION=3.27 diff --git a/dirmngr/http.c b/dirmngr/http.c index 7cab1c2e5..33eb69804 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -920,7 +920,6 @@ http_session_new (http_session_t *r_session, /* Add system certificates to the session. */ if (add_system_cas) { -#if GNUTLS_VERSION_NUMBER >= 0x030014 static int shown; rc = gnutls_certificate_set_x509_system_trust (sess->certcred); @@ -931,7 +930,6 @@ http_session_new (http_session_t *r_session, shown = 1; log_info ("number of system provided CAs: %d\n", rc); } -#endif /* gnutls >= 3.0.20 */ } /* Add other configured certificates to the session. */ @@ -2307,6 +2305,184 @@ run_gnutls_handshake (http_t hd, const char *server) #endif /*HTTP_USE_GNUTLS*/ +/* Use the CONNECT method to proxy our TLS stream. */ +#ifdef USE_TLS +static gpg_error_t +run_proxy_connect (http_t hd, proxy_info_t proxy, + const char *httphost, const char *server, + unsigned short port) +{ + gpg_error_t err; + int saved_flags; + char *authhdr = NULL; + char *request = NULL; + + if (proxy->uri->auth + && !(authhdr = make_header_line ("Proxy-Authorization: Basic ", + "\r\n", + proxy->uri->auth, + strlen (proxy->uri->auth)))) + { + err = gpg_error_from_syserror (); + goto leave; + } + + request = es_bsprintf ("CONNECT %s:%hu HTTP/1.0\r\nHost: %s:%hu\r\n%s", + httphost ? httphost : server, + port, + httphost ? httphost : server, + port, + authhdr ? authhdr : ""); + if (!request) + { + err = gpg_error_from_syserror (); + goto leave; + } + + if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) + log_debug_with_string (request, "http.c:proxy:request:"); + + err = make_fp_write (hd, 0, NULL); + if (err) + goto leave; + + if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) + { + err = gpg_error_from_syserror (); + goto leave; + } + + /* Make sure http_wait_response doesn't close the stream. */ + saved_flags = hd->flags; + hd->flags &= ~HTTP_FLAG_SHUTDOWN; + + /* Get the response and set hd->fp_read */ + err = http_wait_response (hd); + + /* Restore flags, destroy stream. */ + hd->flags = saved_flags; + es_fclose (hd->fp_read); + hd->fp_read = NULL; + hd->read_cookie = NULL; + + /* Reset state. */ + hd->in_data = 0; + + if (err) + goto leave; + + if (hd->status_code != 200) + { + char *tmpstr; + + tmpstr = es_bsprintf ("%s:%hu", httphost ? httphost : server, port); + log_error (_("error accessing '%s': http status %u\n"), + tmpstr ? tmpstr : "out of core", + http_get_status_code (hd)); + xfree (tmpstr); + err = gpg_error (GPG_ERR_NO_DATA); + goto leave; + } + + leave: + xfree (request); + xfree (authhdr); + return err; +} +#endif /*USE_TLS*/ + + +/* Make a request string using a standard proxy. On success the + * request is stored at R_REQUEST (and will never be NULL). */ +static gpg_error_t +mk_proxy_request (http_t hd, proxy_info_t proxy, + const char *httphost, const char *server, + unsigned short port, const char *relpath, + const char *authstr, + char **r_request) +{ + gpg_error_t err = 0; + char *authhdr = NULL; + char *request = NULL; + + *r_request = NULL; + + if (proxy->uri->auth + && !(authhdr = make_header_line ("Proxy-Authorization: Basic ", + "\r\n", + proxy->uri->auth, + strlen (proxy->uri->auth)))) + { + err = gpg_error_from_syserror (); + goto leave; + } + + request = es_bsprintf ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s", + hd->req_type == HTTP_REQ_GET ? "GET" : + hd->req_type == HTTP_REQ_HEAD ? "HEAD" : + hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", + hd->uri->use_tls? "https" : "http", + httphost? httphost : server, + port, *relpath == '/' ? "" : "/", relpath, + authstr ? authstr : "", + authhdr ? authhdr : ""); + if (!request) + { + err = gpg_error_from_syserror (); + goto leave; + } + *r_request = request; + request = NULL; + + leave: + xfree (request); + xfree (authhdr); + return err; +} + + +/* Make a request string using. On success the request is stored at + * R_REQUEST (and will never be NULL). */ +static gpg_error_t +mk_std_request (http_t hd, + const char *httphost, const char *server, + unsigned short port, const char *relpath, + const char *authstr, + char **r_request) +{ + gpg_error_t err = 0; + char portstr[35]; + char *request = NULL; + + *r_request = NULL; + + if (port == (hd->uri->use_tls? 443 : 80)) + *portstr = 0; + else + snprintf (portstr, sizeof portstr, ":%u", port); + + request = es_bsprintf ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s", + hd->req_type == HTTP_REQ_GET ? "GET" : + hd->req_type == HTTP_REQ_HEAD ? "HEAD" : + hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", + *relpath == '/' ? "" : "/", relpath, + httphost? httphost : server, + portstr, + authstr? authstr:""); + if (!request) + { + err = gpg_error_from_syserror (); + goto leave; + } + *r_request = request; + request = NULL; + + leave: + xfree (request); + return err; +} + + /* * Send a HTTP request to the server * Returns 0 if the request was successful @@ -2376,79 +2552,10 @@ send_request (ctrl_t ctrl, #if USE_TLS if (use_http_proxy && hd->uri->use_tls) { - int saved_flags; - - log_assert (!proxy_authstr); - if (proxy->uri->auth - && !(proxy_authstr = make_header_line ("Proxy-Authorization: Basic ", - "\r\n", - proxy->uri->auth, - strlen (proxy->uri->auth)))) - { - err = gpg_error_from_syserror (); - goto leave; - } - - /* Try to use the CONNECT method to proxy our TLS stream. */ - xfree (request); - request = es_bsprintf - ("CONNECT %s:%hu HTTP/1.0\r\nHost: %s:%hu\r\n%s", - httphost ? httphost : server, - port, - httphost ? httphost : server, - port, - proxy_authstr ? proxy_authstr : ""); - if (!request) - { - err = gpg_error_from_syserror (); - goto leave; - } - - if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) - log_debug_string (request, "http.c:request:"); - - err = make_fp_write (hd, 0, NULL); + err = run_proxy_connect (hd, proxy, httphost, server, port); if (err) goto leave; - if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) - { - err = gpg_error_from_syserror (); - goto leave; - } - - /* Make sure http_wait_response doesn't close the stream. */ - saved_flags = hd->flags; - hd->flags &= ~HTTP_FLAG_SHUTDOWN; - - /* Get the response and set hd->fp_read */ - err = http_wait_response (hd); - - /* Restore flags, destroy stream. */ - hd->flags = saved_flags; - es_fclose (hd->fp_read); - hd->fp_read = NULL; - hd->read_cookie = NULL; - - /* Reset state. */ - hd->in_data = 0; - - if (err) - goto leave; - - if (hd->status_code != 200) - { - char *tmpstr; - - tmpstr = es_bsprintf ("%s:%hu", httphost ? httphost : server, port); - log_error (_("error accessing '%s': http status %u\n"), - tmpstr ? tmpstr : "out of core", - http_get_status_code (hd)); - xfree (tmpstr); - err = gpg_error (GPG_ERR_NO_DATA); - goto leave; - } - /* We are done with the proxy, the code below will establish a * TLS session and talk directly to the target server. Thus we * clear the flag to indicate this. */ @@ -2506,61 +2613,13 @@ send_request (ctrl_t ctrl, } if (use_http_proxy) - { - xfree (proxy_authstr); - proxy_authstr = NULL; - if (proxy->uri->auth - && !(proxy_authstr = make_header_line ("Proxy-Authorization: Basic ", - "\r\n", - proxy->uri->auth, - strlen (proxy->uri->auth)))) - { - err = gpg_error_from_syserror (); - goto leave; - } - - xfree (request); - request = es_bsprintf - ("%s %s://%s:%hu%s%s HTTP/1.0\r\n%s%s", - hd->req_type == HTTP_REQ_GET ? "GET" : - hd->req_type == HTTP_REQ_HEAD ? "HEAD" : - hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", - hd->uri->use_tls? "https" : "http", - httphost? httphost : server, - port, *relpath == '/' ? "" : "/", relpath, - authstr ? authstr : "", - proxy_authstr ? proxy_authstr : ""); - if (!request) - { - err = gpg_error_from_syserror (); - goto leave; - } - } + err = mk_proxy_request (hd, proxy, httphost, server, port, + relpath, authstr, &request); else - { - char portstr[35]; - - if (port == (hd->uri->use_tls? 443 : 80)) - *portstr = 0; - else - snprintf (portstr, sizeof portstr, ":%u", port); - - xfree (request); - request = es_bsprintf - ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s", - hd->req_type == HTTP_REQ_GET ? "GET" : - hd->req_type == HTTP_REQ_HEAD ? "HEAD" : - hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", - *relpath == '/' ? "" : "/", relpath, - httphost? httphost : server, - portstr, - authstr? authstr:""); - if (!request) - { - err = gpg_error_from_syserror (); - goto leave; - } - } + err = mk_std_request (hd, httphost, server, port, + relpath, authstr, &request); + if (err) + goto leave; if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) log_debug_string (request, "http.c:request:"); @@ -3731,19 +3790,15 @@ http_verify_server_credentials (http_session_t sess) } else if (status) { - log_error ("%s: status=0x%04x\n", errprefix, status); -#if GNUTLS_VERSION_NUMBER >= 0x030104 - { - gnutls_datum_t statusdat; + gnutls_datum_t statusdat; - if (!gnutls_certificate_verification_status_print - (status, GNUTLS_CRT_X509, &statusdat, 0)) - { - log_info ("%s: %s\n", errprefix, statusdat.data); - gnutls_free (statusdat.data); - } - } -#endif /*gnutls >= 3.1.4*/ + log_error ("%s: status=0x%04x\n", errprefix, status); + if (!gnutls_certificate_verification_status_print + (status, GNUTLS_CRT_X509, &statusdat, 0)) + { + log_info ("%s: %s\n", errprefix, statusdat.data); + gnutls_free (statusdat.data); + } sess->verify.status = status; if (!err) From c91f759bafcae2a19808b642316d1e2447b6073d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 26 Sep 2023 09:35:25 +0200 Subject: [PATCH 191/869] common: Add gnupg_memstr to replace static versions. * common/stringhelp.c (gnupg_memstr): New. * common/mbox-util.c (my_memstr): Remove. (is_valid_mailbox_mem): Use gnupg_memstr. * common/recsel.c (my_memstr): Remove. (recsel_select): Use gnupg_memstr. --- common/mbox-util.c | 31 +------------------------------ common/recsel.c | 33 +-------------------------------- common/stringhelp.c | 29 +++++++++++++++++++++++++++++ common/stringhelp.h | 1 + 4 files changed, 32 insertions(+), 62 deletions(-) diff --git a/common/mbox-util.c b/common/mbox-util.c index a9086a3f5..fb6d06780 100644 --- a/common/mbox-util.c +++ b/common/mbox-util.c @@ -57,35 +57,6 @@ mem_count_chr (const void *buffer, int c, size_t length) } -/* This is a case-sensitive version of our memistr. I wonder why no - standard function memstr exists but I better do not use the name - memstr to avoid future conflicts. */ -static const char * -my_memstr (const void *buffer, size_t buflen, const char *sub) -{ - const unsigned char *buf = buffer; - const unsigned char *t = (const unsigned char *)buf; - const unsigned char *s = (const unsigned char *)sub; - size_t n = buflen; - - for ( ; n ; t++, n-- ) - { - if (*t == *s) - { - for (buf = t++, buflen = n--, s++; n && *t ==*s; t++, s++, n--) - ; - if (!*s) - return (const char*)buf; - t = (const unsigned char *)buf; - s = (const unsigned char *)sub ; - n = buflen; - } - } - return NULL; -} - - - static int string_has_ctrl_or_space (const char *string) { @@ -159,7 +130,7 @@ is_valid_mailbox_mem (const void *name_arg, size_t namelen) || *name == '@' || name[namelen-1] == '@' || name[namelen-1] == '.' - || my_memstr (name, namelen, "..")); + || gnupg_memstr (name, namelen, "..")); } diff --git a/common/recsel.c b/common/recsel.c index ea0858c84..fa3debaaf 100644 --- a/common/recsel.c +++ b/common/recsel.c @@ -85,37 +85,6 @@ my_error (gpg_err_code_t ec) } -/* This is a case-sensitive version of our memistr. I wonder why no - * standard function memstr exists but I better do not use the name - * memstr to avoid future conflicts. - * - * FIXME: Move this to a stringhelp.c - */ -static const char * -my_memstr (const void *buffer, size_t buflen, const char *sub) -{ - const unsigned char *buf = buffer; - const unsigned char *t = (const unsigned char *)buf; - const unsigned char *s = (const unsigned char *)sub; - size_t n = buflen; - - for ( ; n ; t++, n-- ) - { - if (*t == *s) - { - for (buf = t++, buflen = n--, s++; n && *t ==*s; t++, s++, n--) - ; - if (!*s) - return (const char*)buf; - t = (const unsigned char *)buf; - s = (const unsigned char *)sub ; - n = buflen; - } - } - return NULL; -} - - /* Return a pointer to the next logical connection operator or NULL if * none. */ static char * @@ -560,7 +529,7 @@ recsel_select (recsel_expr_t selector, break; case SELECT_SUB: if (se->xcase) - result = !!my_memstr (value, valuelen, se->value); + result = !!gnupg_memstr (value, valuelen, se->value); else result = !!memistr (value, valuelen, se->value); break; diff --git a/common/stringhelp.c b/common/stringhelp.c index 1049c78e2..5407653de 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -161,6 +161,35 @@ ascii_memistr ( const void *buffer, size_t buflen, const char *sub ) } +/* This is a case-sensitive version of our memistr. I wonder why no + * standard function memstr exists but we better do not use the name + * memstr to avoid future conflicts. + */ +const char * +gnupg_memstr (const void *buffer, size_t buflen, const char *sub) +{ + const unsigned char *buf = buffer; + const unsigned char *t = (const unsigned char *)buf; + const unsigned char *s = (const unsigned char *)sub; + size_t n = buflen; + + for ( ; n ; t++, n-- ) + { + if (*t == *s) + { + for (buf = t++, buflen = n--, s++; n && *t ==*s; t++, s++, n--) + ; + if (!*s) + return (const char*)buf; + t = (const unsigned char *)buf; + s = (const unsigned char *)sub ; + n = buflen; + } + } + return NULL; +} + + /* This function is similar to strncpy(). However it won't copy more * than N - 1 characters and makes sure that a '\0' is appended. With * N given as 0, nothing will happen. With DEST given as NULL, memory diff --git a/common/stringhelp.h b/common/stringhelp.h index cd185e49a..d93373ec5 100644 --- a/common/stringhelp.h +++ b/common/stringhelp.h @@ -40,6 +40,7 @@ char *has_leading_keyword (const char *string, const char *keyword); const char *memistr (const void *buf, size_t buflen, const char *sub); +const char *gnupg_memstr (const void *buffer, size_t buflen, const char *sub); char *mem2str( char *, const void *, size_t); char *trim_spaces( char *string ); char *ascii_trim_spaces (char *string); From a5e33618f4211557e60c1b2d013ea8c8d1923e46 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 26 Sep 2023 12:33:09 +0200 Subject: [PATCH 192/869] dirmngr: Fix handling of the HTTP Content-Length * dirmngr/http.c (cookie_s): Add fields pending, up_to_empty_line, last_was_lf, and last_was_lfcr. (http_context_s): Add field keep-alive. (http_wait_response): Set up_to_empty_line. Take care of keep_alive flag. (coookie_read): Implement detection of empty lines. (cookie_write): Free the pending buffer. -- The problem we fix here is that we already buffered stuff beyond the empty line which marks the start of the content-length counting. Thus we tried to wait for more bytes despite that everything had already been read. This bug might have showed up more often in the real world since the we changed the BUFSIZ on Windows from 512 byte to 8k. It also depends on the length of the headers and whether the server closed the connection so that we ignored the Content-Length. The bug was introduced earlier than 2010 and could have the effect that a connection got stuck until the network layer timed out. Note that the keep-alive parts of the patch are not yet used. --- dirmngr/http.c | 156 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 140 insertions(+), 16 deletions(-) diff --git a/dirmngr/http.c b/dirmngr/http.c index 33eb69804..a44b0d244 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2,7 +2,7 @@ * Copyright (C) 1999, 2001-2004, 2006, 2009, 2010, * 2011 Free Software Foundation, Inc. * Copyright (C) 1999, 2001-2004, 2006, 2009, 2010, 2011, 2014 Werner Koch - * Copyright (C) 2015-2017, 2021 g10 Code GmbH + * Copyright (C) 2015-2017, 2021, 2023 g10 Code GmbH * * This file is part of GnuPG. * @@ -211,10 +211,29 @@ struct cookie_s /* True if TLS is to be used. */ int use_tls; + /* Optional malloced buffer holding pending bytes for the read + * function. LEN gives the used length, SIZE the allocated length. + * Used by the up_to_empty_line machinery. */ + struct { + size_t size; + size_t len; + char *data; + } pending; + /* The remaining content length and a flag telling whether to use the content length. */ uint64_t content_length; unsigned int content_length_valid:1; + + /* If the next flag is set the read function will limit the returned + * buffer to an empty line. That is the the pattern "\n\r\n" is + * detected and any further bytes are not returned to the caller. + * The flag is then reset. For technical reason we might have + * already read more which will be then saved for the next call in + * the PENDING buffer. */ + unsigned int up_to_empty_line:1; + unsigned int last_was_lf:1; /* Helper to detect empty line. */ + unsigned int last_was_lfcr:1; /* Helper to detect empty line. */ }; typedef struct cookie_s *cookie_t; @@ -306,6 +325,7 @@ struct http_context_s my_socket_t sock; unsigned int in_data:1; unsigned int is_http_0_9:1; + unsigned int keep_alive:1; /* Keep the connection alive. */ estream_t fp_read; estream_t fp_write; void *write_cookie; @@ -1180,7 +1200,7 @@ http_start_data (http_t hd) if (!hd->in_data) { if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) - log_debug_string ("\r\n", "http.c:request-header:"); + log_debug ("http.c:request-header:start_data:\n"); es_fputs ("\r\n", hd->fp_write); es_fflush (hd->fp_write); hd->in_data = 1; @@ -1196,6 +1216,7 @@ http_wait_response (http_t hd) gpg_error_t err; cookie_t cookie; int use_tls; + int newfpread; /* Make sure that we are in the data. */ http_start_data (hd); @@ -1207,26 +1228,36 @@ http_wait_response (http_t hd) return gpg_err_make (default_errsource, GPG_ERR_INTERNAL); use_tls = cookie->use_tls; - es_fclose (hd->fp_write); - hd->fp_write = NULL; - /* The close has released the cookie and thus we better set it to NULL. */ - hd->write_cookie = NULL; + if (!hd->keep_alive) + { + es_fclose (hd->fp_write); + hd->fp_write = NULL; + /* The close has released the cookie and thus we better set it + * to NULL. */ + hd->write_cookie = NULL; + } /* Shutdown one end of the socket is desired. As per HTTP/1.0 this is not required but some very old servers (e.g. the original pksd keyserver didn't worked without it. */ - if ((hd->flags & HTTP_FLAG_SHUTDOWN)) + if (!hd->keep_alive && (hd->flags & HTTP_FLAG_SHUTDOWN)) shutdown (FD2INT (hd->sock->fd), 1); hd->in_data = 0; /* Create a new cookie and a stream for reading. */ - err = make_fp_read (hd, use_tls, hd->session); - if (err) - return err; + newfpread = 0; + if (!hd->keep_alive || !hd->fp_read) + { + err = make_fp_read (hd, use_tls, hd->session); + if (err) + return err; + newfpread = 1; + ((cookie_t)(hd->read_cookie))->up_to_empty_line = 1; + } err = parse_response (hd); - if (!err) + if (!err && newfpread) err = es_onclose (hd->fp_read, 1, fp_onclose_notification, hd); return err; @@ -3532,31 +3563,48 @@ cookie_read (void *cookie, void *buffer, size_t size) { cookie_t c = cookie; int nread; + size_t offset = 0; if (c->content_length_valid) { if (!c->content_length) - return 0; /* EOF */ + { + c->content_length_valid = 0; + return 0; /* EOF */ + } if (c->content_length < size) size = c->content_length; } + if (c->pending.len) + { + offset = c->pending.len > size? size : c->pending.len; + memcpy (buffer, c->pending.data, offset); + c->pending.len -= offset; + } + + if (offset >= size) + nread = offset; + else #if HTTP_USE_NTBTLS if (c->use_tls && c->session && c->session->tls_session) { estream_t in, out; ntbtls_get_stream (c->session->tls_session, &in, &out); - nread = es_fread (buffer, 1, size, in); + nread = es_fread ((char*)buffer+offset, 1, size-offset, in); if (opt_debug) - log_debug ("TLS network read: %d/%zu\n", nread, size); + log_debug ("TLS network read: %d/%zu\n", nread, size-offset); + if (nread >= 0) + nread += offset; } else #elif HTTP_USE_GNUTLS if (c->use_tls && c->session && c->session->tls_session) { again: - nread = gnutls_record_recv (c->session->tls_session, buffer, size); + nread = gnutls_record_recv (c->session->tls_session, + (char*)buffer+offset, size-offset); if (nread < 0) { if (nread == GNUTLS_E_INTERRUPTED) @@ -3583,11 +3631,86 @@ cookie_read (void *cookie, void *buffer, size_t size) gpg_err_set_errno (EIO); return -1; } + if (nread >= 0) + nread += offset; } else #endif /*HTTP_USE_GNUTLS*/ { - nread = read_server (c->sock->fd, buffer, size); + nread = read_server (c->sock->fd, (char*)buffer+offset, size-offset); + if (opt_debug) + log_debug ("network read: %d/%zu\n", nread, size); + if (nread >= 0) + nread += offset; + } + + if (nread > 0 && c->up_to_empty_line) + { + gpg_error_t err; + const char *s; + size_t n; + int extra; + int lfcr_pending = 0; + char *bufp = buffer; + + if (c->last_was_lf && nread > 1 && bufp[0] == '\r' && bufp[1] == '\n') + { + s = buffer; + extra = 2; + } + else if (c->last_was_lf && bufp[0] == '\r') + { + lfcr_pending = 1; + s = buffer; /* Only to avoid the call to gnupg_memstr. */ + } + else if (c->last_was_lfcr && bufp[0] == '\n') + { + s = buffer; + extra = 1; + } + else + s = NULL; + + c->last_was_lfcr = c->last_was_lf = 0; + + if (!s) + { + s = gnupg_memstr (buffer, nread, "\n\r\n"); + extra = 3; + } + + if (lfcr_pending) + c->last_was_lfcr = 1; + else if (s) + { + /* Save away the rest and return up to the LF. */ + log_assert (!c->pending.len); + n = (s+extra) - bufp; + log_assert (n <= nread); + c->pending.len = nread - n; + if (!c->pending.data || c->pending.len >= c->pending.size) + { + xfree (c->pending.data); + c->pending.size = c->pending.len + 256; /* Some extra space. */ + c->pending.data = xtrymalloc (c->pending.size); + if (!c->pending.data) + { + err = gpg_error_from_syserror (); + log_error ("error allocating network read buffer: %s\n", + gpg_strerror (err)); + return -1; + } + memcpy (c->pending.data, bufp + n, c->pending.len); + } + else + memcpy (c->pending.data, bufp + n, c->pending.len); + nread = n; /* Return everything up to the empty line. */ + c->up_to_empty_line = 0; + } + else if (bufp[nread-1] == '\n') + c->last_was_lf = 1; + else if (nread > 1 && bufp[nread-2] == '\n' && bufp[nread-1] == '\r') + c->last_was_lfcr = 1; } if (c->content_length_valid && nread > 0) @@ -3748,6 +3871,7 @@ cookie_close (void *cookie) if (c->session) http_session_unref (c->session); + xfree (c->pending.data); xfree (c); return 0; } From eda3997b439e415f1bebaa3be20c8bdb43d3a1d0 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 28 Sep 2023 11:59:14 +0900 Subject: [PATCH 193/869] agent: fix tpm2d keytotpm handling * agent/divert-tpm2.c (agent_write_tpm2_shadow_key): Call agent_delete_key before agent_write_private_key. Recover from an error. -- Fixes-commit: a1015bf2fc07dabb1200eab5fa41f13e7bf98202 Signed-off-by: James Bottomley --- agent/divert-tpm2.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index b2f884f93..e7c6a8aae 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -26,9 +26,10 @@ divert_tpm2_pksign (ctrl_t ctrl, static gpg_error_t agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, - unsigned char *shadow_info) + unsigned char *shadow_info, + gcry_sexp_t s_key) { - gpg_error_t err; + gpg_error_t err, err1; unsigned char *shdkey; unsigned char *pkbuf; size_t len; @@ -44,7 +45,14 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, xfree (pkbuf); if (err) { - log_error ("shadowing the key failed: %s\n", gpg_strerror (err)); + log_error ("shadowing the tpm key failed: %s\n", gpg_strerror (err)); + return err; + } + + err = agent_delete_key (ctrl, NULL, grip, 1, 0); + if (err) + { + log_error ("failed to delete unshadowed key: %s\n", gpg_strerror (err)); return err; } @@ -53,7 +61,22 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, NULL, NULL, NULL, 0); xfree (shdkey); if (err) - log_error ("error writing key: %s\n", gpg_strerror (err)); + { + log_error ("error writing tpm key: %s\n", gpg_strerror (err)); + + len = gcry_sexp_sprint(s_key, GCRYSEXP_FMT_CANON, NULL, 0); + pkbuf = xtrymalloc(len); + if (!pkbuf) + return GPG_ERR_ENOMEM; + + gcry_sexp_sprint(s_key, GCRYSEXP_FMT_CANON, pkbuf, len); + err1 = agent_write_private_key (grip, pkbuf, len, 1 /*force*/, + NULL, NULL, NULL, 0); + xfree(pkbuf); + if (err1) + log_error ("error trying to restore private key: %s\n", + gpg_strerror (err1)); + } return err; } @@ -68,7 +91,7 @@ divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip, ret = agent_tpm2d_writekey(ctrl, &shadow_info, s_skey); if (!ret) { - ret = agent_write_tpm2_shadow_key (ctrl, grip, shadow_info); + ret = agent_write_tpm2_shadow_key (ctrl, grip, shadow_info, s_skey); xfree (shadow_info); } return ret; From 1da40db03eba4aa056f7cdf8ef90292272a4147d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 28 Sep 2023 13:26:52 +0900 Subject: [PATCH 194/869] tpm2d: Check SWTPM environment variable for swtpm support. * tpm2d/intel-tss.h (TSS_Create): Check SWTPM. -- Signed-off-by: James Bottomley --- tpm2d/intel-tss.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tpm2d/intel-tss.h b/tpm2d/intel-tss.h index 615f81e2f..53da5cee2 100644 --- a/tpm2d/intel-tss.h +++ b/tpm2d/intel-tss.h @@ -285,9 +285,15 @@ TSS_Create(TSS_CONTEXT **tssContext) */ if (intType) { - if (strcmp("socsim", intType) == 0) { - tctildr = "mssim"; - } + if (strcmp("socsim", intType) == 0) + { + char *swtpm = getenv("SWTPM"); + + if (!swtpm || strlen(swtpm) == 0) + tctildr = "mssim"; + else + tctildr = "swtpm"; + } else if (strcmp("dev", intType) == 0) { tctildr = "device"; From 78afc209ccb72efcfb60aa3468c2c12fe026f8a7 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 2 Oct 2023 10:32:04 +0900 Subject: [PATCH 195/869] tpm2d: Fix call to assuan_control. * tpm2d/tpm2daemon.c (main): Use ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP. -- Fixes-commit: 9e4d52223945d677c1ffcb0e20dae48299e9aae1 Signed-off-by: NIIBE Yutaka --- tpm2d/tpm2daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tpm2d/tpm2daemon.c b/tpm2d/tpm2daemon.c index a8c83cd8b..8e16e931a 100644 --- a/tpm2d/tpm2daemon.c +++ b/tpm2d/tpm2daemon.c @@ -737,7 +737,7 @@ main (int argc, char **argv ) npth_init (); gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); - assuan_control (ASSUAN_REINIT_SYSCALL_CLAMP, NULL); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); /* Detach from tty and put process into a new session. */ if (!nodetach ) From 52b7a60cf9f3cd2e5900396b0e3e65cbd335bc23 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 29 Sep 2023 11:34:06 +0200 Subject: [PATCH 196/869] common: Add new function b64decode. * common/b64dec.c (b64decode): New. * common/t-b64.c: Change license to LGPL. (oops): New macro. (hex2buffer): New. (test_b64decode): New. (main): Default to run the new test. * common/Makefile.am (module_maint_tests): Move t-b64 to ... (module_tests): here. -- Sometimes we have a short base64 encoded string we need todecode. This function makes it simpler. License change of the test module justified because I am the single author of the code. --- common/Makefile.am | 4 +- common/b64dec.c | 45 +++++++++++++++ common/b64enc.c | 1 + common/t-b64.c | 134 +++++++++++++++++++++++++++++++++++++++------ common/util.h | 2 + 5 files changed, 168 insertions(+), 18 deletions(-) diff --git a/common/Makefile.am b/common/Makefile.am index d5ab038bf..7c78708da 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -161,7 +161,7 @@ module_tests = t-stringhelp t-timestuff \ t-convert t-percent t-gettime t-sysutils t-sexputil \ t-session-env t-openpgp-oid t-ssh-utils \ t-mapstrings t-zb32 t-mbox-util t-iobuf t-strlist \ - t-name-value t-ccparray t-recsel t-w32-cmdline + t-name-value t-ccparray t-recsel t-w32-cmdline t-b64 if HAVE_W32_SYSTEM module_tests += t-w32-reg else @@ -169,7 +169,7 @@ module_tests += t-exechelp t-exectool endif if MAINTAINER_MODE -module_maint_tests = t-helpfile t-b64 +module_maint_tests = t-helpfile else module_maint_tests = endif diff --git a/common/b64dec.c b/common/b64dec.c index 6af494b79..2904b0471 100644 --- a/common/b64dec.c +++ b/common/b64dec.c @@ -16,6 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1-or-later */ #include @@ -252,3 +253,47 @@ b64dec_finish (struct b64state *state) return state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0; } + + +/* Convert STRING consisting of base64 characters into its binary + * representation and store the result in a newly allocated buffer at + * R_BUFFER with its length at R_BUFLEN. If TITLE is NULL a plain + * base64 decoding is done. If it is the empty string the decoder + * will skip everything until a "-----BEGIN " line has been seen, + * decoding then ends at a "----END " line. On failure the function + * returns an error code and sets R_BUFFER to NULL. If the decoded + * data has a length of 0 a dummy buffer will still be allocated and + * the length is set to 0. */ +gpg_error_t +b64decode (const char *string, const char *title, + void **r_buffer, size_t *r_buflen) +{ + gpg_error_t err; + struct b64state state; + size_t nbytes; + char *buffer; + + *r_buffer = NULL; + *r_buflen = 0; + + buffer = xtrystrdup (string); + if (!buffer) + return gpg_error_from_syserror(); + + err = b64dec_start (&state, title); + if (err) + { + xfree (buffer); + return err; + } + b64dec_proc (&state, buffer, strlen (buffer), &nbytes); + err = b64dec_finish (&state); + if (err) + xfree (buffer); + else + { + *r_buffer = buffer; + *r_buflen = nbytes; + } + return err; +} diff --git a/common/b64enc.c b/common/b64enc.c index d633048ea..7846dcb3e 100644 --- a/common/b64enc.c +++ b/common/b64enc.c @@ -18,6 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1-or-later */ #include diff --git a/common/t-b64.c b/common/t-b64.c index 3b6387246..16c079d1d 100644 --- a/common/t-b64.c +++ b/common/t-b64.c @@ -1,30 +1,24 @@ /* t-b64.c - Module tests for b64enc.c and b64dec.c - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008, 2023 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. + * 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. * - * GnuPG is distributed in the hope that it will be useful, + * 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 General Public License + * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - - As of now this is only a test program for manual tests. - - */ - - - #include #include #include @@ -36,10 +30,112 @@ __FILE__,__LINE__, (a)); \ errcount++; \ } while(0) +#define oops() do { fprintf (stderr, "%s:%d: ooops\n", \ + __FILE__,__LINE__); \ + exit (2); \ + } while(0) static int verbose; static int errcount; + +/* Convert STRING consisting of hex characters into its binary + * representation and return it as an allocated buffer. The valid + * length of the buffer is returned at R_LENGTH. The string is + * delimited by end of string. The function returns NULL on + * error. */ +static void * +hex2buffer (const char *string, size_t *r_length) +{ + const char *s; + unsigned char *buffer; + size_t length; + + buffer = xmalloc (strlen(string)/2+1); + length = 0; + for (s=string; *s; s +=2 ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + return NULL; /* Invalid hex digits. */ + ((unsigned char*)buffer)[length++] = xtoi_2 (s); + } + *r_length = length; + return buffer; +} + + +static void +test_b64decode (void) +{ + static struct { + const char *string; /* String to test. */ + const char *title; /* title parameter. */ + gpg_error_t err; /* expected error. */ + const char *datastr; /* Expected data (hex encoded) */ + } tests[] = { + { "YQ==", NULL, 0, + "61" }, + { "YWE==", NULL, 0, + "6161" }, + { "YWFh", NULL, 0, + "616161" }, + { "YWFhYQ==", NULL, 0, + "61616161" }, + { "YWJjZA==", NULL, 0, + "61626364" }, + { "AA=", NULL, 0, + "00" }, + { "AAEA=", NULL, 0, + "000100" }, + { "/w==", NULL, 0, + "ff" }, + { "oRQwEqADCgEDoQsGCSqGSIL3EgECAg==", NULL, 0, + "a1143012a0030a0103a10b06092a864882f712010202" }, + { "oRQwEqADCgEDoQsGCSqGSIL3EgECA-==", NULL, GPG_ERR_BAD_DATA, + "a1143012a0030a0103a10b06092a864882f712010202" }, + { "oRQwEqADCgEDoQsGCSqGSIL3EgECAg==", "", 0, + "" }, + { "-----BEGIN PGP\n\n" + "oRQwEqADCgEDoQsGCSqGSIL3EgECAg==\n" + "-----END PGP\n", "", 0, + "a1143012a0030a0103a10b06092a864882f712010202" }, + + { "", NULL, 0, + "" } + }; + int tidx; + gpg_error_t err; + void *data = NULL; + size_t datalen; + char *wantdata = NULL; + size_t wantdatalen; + + for (tidx = 0; tidx < DIM(tests); tidx++) + { + xfree (wantdata); + if (!(wantdata = hex2buffer (tests[tidx].datastr, &wantdatalen))) + oops (); + xfree (data); + err = b64decode (tests[tidx].string, tests[tidx].title, &data, &datalen); + if (verbose) + fprintf (stderr, "%s:%d: test %d, err=%d, datalen=%zu\n", + __FILE__, __LINE__, tidx, err, datalen); + if (gpg_err_code (err) != tests[tidx].err) + fail (tidx); + else if (err) + pass (); + else if (wantdatalen != datalen) + fail (tidx); + else if (memcmp (wantdata, data, datalen)) + fail (tidx); + else + pass (); + } + xfree (wantdata); + xfree (data); +} + + static void test_b64enc_pgp (const char *string) { @@ -101,6 +197,7 @@ test_b64enc_file (const char *fname) pass (); } + static void test_b64dec_file (const char *fname) { @@ -150,6 +247,7 @@ main (int argc, char **argv) { int do_encode = 0; int do_decode = 0; + int do_pgpdecode = 0; if (argc) { argc--; argv++; } @@ -169,13 +267,17 @@ main (int argc, char **argv) do_decode = 1; argc--; argv++; } + else if (argc) + do_pgpdecode = 1; if (do_encode) test_b64enc_file (argc? *argv: NULL); else if (do_decode) test_b64dec_file (argc? *argv: NULL); - else + else if (do_pgpdecode) test_b64enc_pgp (argc? *argv: NULL); + else + test_b64decode (); return !!errcount; } diff --git a/common/util.h b/common/util.h index aa24e39e6..83882caf2 100644 --- a/common/util.h +++ b/common/util.h @@ -171,6 +171,8 @@ gpg_error_t b64dec_start (struct b64state *state, const char *title); gpg_error_t b64dec_proc (struct b64state *state, void *buffer, size_t length, size_t *r_nbytes); gpg_error_t b64dec_finish (struct b64state *state); +gpg_error_t b64decode (const char *string, const char *title, + void **r_buffer, size_t *r_buflen); /*-- sexputil.c */ char *canon_sexp_to_string (const unsigned char *canon, size_t canonlen); From 53bdb7440cbe18f73548169528167190d70998ed Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 2 Oct 2023 12:53:41 +0200 Subject: [PATCH 197/869] dirmngr: Extended the http_get_header function. * dirmngr/http.c (send_request): Add arg 'skip'. Adjust all callers. -- GnuPG-bug-id: 6719 --- dirmngr/http.c | 25 +++++++++++++++++-------- dirmngr/http.h | 2 +- dirmngr/ks-engine-hkp.c | 2 +- dirmngr/ks-engine-http.c | 2 +- dirmngr/ocsp.c | 2 +- dirmngr/t-http.c | 4 ++-- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/dirmngr/http.c b/dirmngr/http.c index a44b0d244..32e6a6cb8 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2845,18 +2845,27 @@ store_header (http_t hd, char *line) /* Return the header NAME from the last response. The returned value - is valid as along as HD has not been closed and no other request - has been send. If the header was not found, NULL is returned. NAME - must be canonicalized, that is the first letter of each dash - delimited part must be uppercase and all other letters lowercase. */ + * is valid as along as HD has not been closed and no other request + * has been send. If the header was not found, NULL is returned. NAME + * must be canonicalized, that is the first letter of each dash + * delimited part must be uppercase and all other letters lowercase. + * SKIP gives the number of entries of the requested NAME to skip + * before returning; this can be used to enumerate headers with the + * same name (see store_header). +*/ const char * -http_get_header (http_t hd, const char *name) +http_get_header (http_t hd, const char *name, unsigned int skip) { header_t h; for (h=hd->headers; h; h = h->next) - if ( !strcmp (h->name, name) ) - return h->value; + if (!strcmp (h->name, name)) + { + if (skip) + skip--; + else + return h->value; + } return NULL; } @@ -2979,7 +2988,7 @@ parse_response (http_t hd) cookie->content_length_valid = 0; if (!(hd->flags & HTTP_FLAG_IGNORE_CL)) { - s = http_get_header (hd, "Content-Length"); + s = http_get_header (hd, "Content-Length", 0); if (s) { cookie->content_length_valid = 1; diff --git a/dirmngr/http.h b/dirmngr/http.h index 2994fdfad..28406694e 100644 --- a/dirmngr/http.h +++ b/dirmngr/http.h @@ -195,7 +195,7 @@ estream_t http_get_read_ptr (http_t hd); estream_t http_get_write_ptr (http_t hd); unsigned int http_get_status_code (http_t hd); const char *http_get_tls_info (http_t hd, const char *what); -const char *http_get_header (http_t hd, const char *name); +const char *http_get_header (http_t hd, const char *name, unsigned int skip); const char **http_get_header_names (http_t hd); gpg_error_t http_verify_server_credentials (http_session_t sess); diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index a75cc1aee..75fe19987 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1327,7 +1327,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, { xfree (request_buffer); err = http_prepare_redirect (&redirinfo, http_get_status_code (http), - http_get_header (http, "Location"), + http_get_header (http, "Location", 0), &request_buffer); if (err) goto leave; diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 48a734786..5091ddf27 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -180,7 +180,7 @@ ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags, { xfree (request_buffer); err = http_prepare_redirect (&redirinfo, http_get_status_code (http), - http_get_header (http, "Location"), + http_get_header (http, "Location", 0), &request_buffer); if (err) goto leave; diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c index 483b6f32d..ad7ed962a 100644 --- a/dirmngr/ocsp.c +++ b/dirmngr/ocsp.c @@ -227,7 +227,7 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, case 301: case 302: { - const char *s = http_get_header (http, "Location"); + const char *s = http_get_header (http, "Location", 0); log_info (_("URL '%s' redirected to '%s' (%u)\n"), url, s?s:"[none]", http_get_status_code (http)); diff --git a/dirmngr/t-http.c b/dirmngr/t-http.c index f9c59783f..3cc4be23a 100644 --- a/dirmngr/t-http.c +++ b/dirmngr/t-http.c @@ -463,7 +463,7 @@ main (int argc, char **argv) log_fatal ("http_get_header_names failed: %s\n", gpg_strerror (gpg_error_from_syserror ())); for (i = 0; names[i]; i++) - printf ("HDR: %s: %s\n", names[i], http_get_header (hd, names[i])); + printf ("HDR: %s: %s\n", names[i], http_get_header (hd, names[i], 0)); xfree (names); } fflush (stdout); @@ -489,7 +489,7 @@ main (int argc, char **argv) case 301: case 302: case 307: - log_info ("Redirected to: %s\n", http_get_header (hd, "Location")); + log_info ("Redirected to: %s\n", http_get_header (hd, "Location", 0)); break; } http_close (hd, 0); From d7a1577a252466c89a87a547bc7f3e9a3d3a2a76 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 2 Oct 2023 13:00:35 +0200 Subject: [PATCH 198/869] dirmngr: Add code to support the negotiation auth method. * dirmngr/http.c (enum auth_negotiate_states): New. (struct proxy_info_s): Add new fields. (release_proxy_info): Free Windows stuff. (proxy_get_token): New. Implemented only for Windows for now. (run_proxy_connect): Add support for auth method Negotiation. (store_header): Keep some header lines separate. -- The code does something but I have not yet been able to test it due to problems setting up Squid with AD authentication. As of now it will respond with a failure but that should not be worse than not to implement Negotiation. Supporting Negotiation using GSS for Unix should eventually also be done. GnuPG-bug-id: 6719 --- dirmngr/Makefile.am | 2 +- dirmngr/http.c | 410 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 371 insertions(+), 41 deletions(-) diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index 9665b5dfd..a0f8d5a79 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -68,7 +68,7 @@ AM_CFLAGS = $(USE_C99_CFLAGS) \ if HAVE_W32_SYSTEM ldap_url = ldap-url.h ldap-url.c -NETLIBS += -lwinhttp +NETLIBS += -lwinhttp -lsecurity else ldap_url = endif diff --git a/dirmngr/http.c b/dirmngr/http.c index 32e6a6cb8..4899a5d55 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -65,12 +65,8 @@ # endif # include # include -# ifndef EHOSTUNREACH -# define EHOSTUNREACH WSAEHOSTUNREACH -# endif -# ifndef EAFNOSUPPORT -# define EAFNOSUPPORT WSAEAFNOSUPPORT -# endif +# define SECURITY_WIN32 1 +# include #else /*!HAVE_W32_SYSTEM*/ # include # include @@ -250,11 +246,30 @@ static es_cookie_io_functions_t simple_cookie_functions = }; #endif +enum auth_negotiate_states + { + AUTH_NGT_NONE = 0, + AUTH_NGT_RCVD = 1, + AUTH_NGT_SENT = 2 + }; + /* An object to store information about a proxy. */ struct proxy_info_s { parsed_uri_t uri; /* The parsed proxy URL. */ int is_http_proxy; /* This is an http proxy. */ + +#ifdef HAVE_W32_SYSTEM + CredHandle cred_handle; /* Credential handle. */ + wchar_t *spn; /* Service principal name. */ + CtxtHandle ctxt_handle; /* Security context. */ + unsigned long token_size; /* Max. length of a token. */ + unsigned int cred_handle_valid:1; + unsigned int ctxt_handle_valid:1; +#endif /*HAVE_W32_SYSTEM*/ + + unsigned char *outtoken; /* The output token allocated with token_size. */ + unsigned long outtoklen; /* The current length of the token. */ }; typedef struct proxy_info_s *proxy_info_t; @@ -1853,6 +1868,13 @@ release_proxy_info (proxy_info_t proxy) if (!proxy) return; http_release_parsed_uri (proxy->uri); + xfree (proxy->outtoken); +#ifdef HAVE_W32_SYSTEM + if (proxy->ctxt_handle_valid) + DeleteSecurityContext (&proxy->ctxt_handle); + if (proxy->cred_handle_valid) + FreeCredentialsHandle (&proxy->cred_handle); +#endif xfree (proxy); } @@ -2336,6 +2358,181 @@ run_gnutls_handshake (http_t hd, const char *server) #endif /*HTTP_USE_GNUTLS*/ +/* It INPUTSTRING is NULL get the intial token. If INPUTSTRING is not + * NULL, decode the string and use this as input from teh server. On + * success the final output token is stored at PROXY->OUTTOKEN and + * OUTTOKLEN. IF the authentication succeeded OUTTOKLEN is zero. */ +#ifdef USE_TLS +static gpg_error_t +proxy_get_token (proxy_info_t proxy, const char *inputstring) +{ +#ifdef HAVE_W32_SYSTEM + gpg_error_t err; + int rc; + SecBuffer chlg_buf; /* challenge buffer */ + SecBufferDesc chlg_desc; /* challenge descriptor */ + SecBuffer resp_buf; /* response buffer */ + SecBufferDesc resp_desc; /* response descriptor */ + unsigned long attrs; + TimeStamp expiry; /* (value not used) */ + void *intoken = NULL; + size_t intoklen; + + if (inputstring) + { + /* The input is expected in the token parameter but the paremter + * name is often forgotten. Thus we simply detect the parameter + * name and skip it, assuming no other parameters are given. */ + if (!strncmp (inputstring, "token=", 6)) + inputstring += 6; + + err = b64decode (inputstring, NULL, &intoken, &intoklen); + /* Just to be safe that we don't overflow an ulong we check the + * actual size against an arbitrary limit. */ + if (!err && intoklen > 65535) + err = gpg_error (GPG_ERR_ERANGE); + if (err || !intoklen) + { + log_error ("error decoding received auth token: %s\n", + err? gpg_strerror (err):"empty challenge token received"); + if (!err) + err = gpg_error (GPG_ERR_BAD_AUTH); + goto leave; + } + } + + if (!proxy->spn) + { + char *buffer = strconcat ("HTTP/", (*proxy->uri->host + ?proxy->uri->host:"localhost"), NULL); + if (!buffer) + { + err = gpg_error_from_syserror (); + goto leave; + } + if (opt_debug) + log_debug ("http.c:proxy_connect: using '%s' as SPN\n", buffer); + proxy->spn = utf8_to_wchar (buffer); + xfree (buffer); + if (!proxy->spn) + { + err = gpg_error_from_syserror (); + goto leave; + } + } + + if (!proxy->token_size || !proxy->outtoken) /* Not yet initialized. */ + { + PSecPkgInfoW pinfo; + + rc = QuerySecurityPackageInfoW (NEGOSSP_NAME_W, &pinfo); + if (rc) + { + log_error ("QSPI(Negotiate) failed: %s (%d)\n", + w32_strerror (rc), rc); + err = gpg_error (GPG_ERR_BAD_AUTH); + goto leave; + } + proxy->token_size = pinfo->cbMaxToken; + FreeContextBuffer (pinfo); + + proxy->outtoken = xtrymalloc (proxy->token_size); + if (!proxy->outtoken) + { + err = gpg_error_from_syserror (); + goto leave; + } + } + + if (!proxy->cred_handle_valid) + { + rc = AcquireCredentialsHandleW (NULL, NEGOSSP_NAME_W, + SECPKG_CRED_OUTBOUND, NULL, + NULL, /* Current user */ + NULL, /* reserved */ + NULL, /* reserved */ + &proxy->cred_handle, + NULL /* expiry */); + if (rc) + { + log_error ("ACH(Negotiate) failed: %s (%d)\n", w32_strerror (rc), rc); + err = gpg_error (GPG_ERR_NO_AUTH); + goto leave; + } + proxy->cred_handle_valid = 1; + } + + /* Now generate our challenge-response message. */ + if (intoken) + { + chlg_buf.BufferType = SECBUFFER_TOKEN; + chlg_buf.pvBuffer = intoken; + chlg_buf.cbBuffer = intoklen; + chlg_desc.ulVersion = SECBUFFER_VERSION; + chlg_desc.cBuffers = 1; + chlg_desc.pBuffers = &chlg_buf; + } + + resp_buf.BufferType = SECBUFFER_TOKEN; + resp_buf.pvBuffer = proxy->outtoken; + resp_buf.cbBuffer = proxy->token_size; + resp_desc.ulVersion = SECBUFFER_VERSION; + resp_desc.cBuffers = 1; + resp_desc.pBuffers = &resp_buf; + rc = InitializeSecurityContextW (&proxy->cred_handle, + (intoken && proxy->ctxt_handle_valid) + ? &proxy->ctxt_handle : NULL, + proxy->spn, /* service principal name */ + ISC_REQ_CONFIDENTIALITY, + 0, /* reserved */ + SECURITY_NATIVE_DREP, + intoken? &chlg_desc : NULL, + 0, /* reserved */ + &proxy->ctxt_handle, /* new context */ + &resp_desc, /* the output. */ + &attrs, /* attribs of the context. */ + &expiry); + switch (rc) + { + case SEC_E_OK: /* All done and no more ISC expected. */ + break; + + case SEC_I_COMPLETE_AND_CONTINUE: /* Need to call CompleteAuthToken. */ + case SEC_I_COMPLETE_NEEDED: + rc = CompleteAuthToken (&proxy->ctxt_handle, &resp_desc); + log_error ("CompleteAuthToken failed: %s (%d)\n", w32_strerror (rc), rc); + err = gpg_error (GPG_ERR_NO_AUTH); + goto leave; + break; + + case SEC_I_CONTINUE_NEEDED: /* Send the new token to the client. */ + break; + + default: + log_error ("ISC(Negotiate) failed: %s (%d)\n", w32_strerror (rc), rc); + err = gpg_error (GPG_ERR_NO_AUTH); + goto leave; + } + + proxy->outtoklen = resp_buf.cbBuffer; + proxy->ctxt_handle_valid = 1; + err = 0; + + leave: + xfree (intoken); + return err; + +#else /*!HAVE_W32_SYSTEM*/ + + (void)proxy; + (void)inputstring; + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + +#endif /*!HAVE_W32_SYSTEM*/ +} +#endif /*USE_TLS*/ + + /* Use the CONNECT method to proxy our TLS stream. */ #ifdef USE_TLS static gpg_error_t @@ -2344,11 +2541,24 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, unsigned short port) { gpg_error_t err; - int saved_flags; + int saved_flags = hd->flags; char *authhdr = NULL; char *request = NULL; + char *tmpstr = NULL; + const char *s, *parms; + unsigned int idx; + int auth_basic = 0; + enum auth_negotiate_states authstate = 0; + unsigned int authpasses = 0; - if (proxy->uri->auth + /* Authentication methods implemented here: + * RFC-2617 - HTTP Authentication: Basic and Digest Access Authentication + * RFC-4559 - SPNEGO-based Kerberos and NTLM HTTP Authentication + */ + auth_basic = !!proxy->uri->auth; + + /* For basic authentication we need to send just one request. */ + if (auth_basic && !(authhdr = make_header_line ("Proxy-Authorization: Basic ", "\r\n", proxy->uri->auth, @@ -2358,24 +2568,32 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, goto leave; } - request = es_bsprintf ("CONNECT %s:%hu HTTP/1.0\r\nHost: %s:%hu\r\n%s", + again: + xfree (request); + request = es_bsprintf ("CONNECT %s:%hu HTTP/1.%c\r\nHost: %s:%hu\r\n%s%s", httphost ? httphost : server, port, + auth_basic? '0' : '1', httphost ? httphost : server, port, - authhdr ? authhdr : ""); + authhdr ? authhdr : "", + auth_basic? "" : "Connection: keep-alive\r\n"); if (!request) { err = gpg_error_from_syserror (); goto leave; } + hd->keep_alive = !auth_basic; /* We may need to send more requests. */ if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) log_debug_with_string (request, "http.c:proxy:request:"); - err = make_fp_write (hd, 0, NULL); - if (err) - goto leave; + if (!hd->fp_write) + { + err = make_fp_write (hd, 0, NULL); + if (err) + goto leave; + } if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) { @@ -2389,35 +2607,140 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, /* Get the response and set hd->fp_read */ err = http_wait_response (hd); - - /* Restore flags, destroy stream. */ - hd->flags = saved_flags; - es_fclose (hd->fp_read); - hd->fp_read = NULL; - hd->read_cookie = NULL; - - /* Reset state. */ - hd->in_data = 0; - if (err) goto leave; - if (hd->status_code != 200) - { - char *tmpstr; + { + unsigned long count = 0; + while (es_getc (hd->fp_read) != EOF) + count++; + if (opt_debug) + log_debug ("http.c:proxy_connect: skipped %lu bytes of response-body\n", + count); + } + + /* Reset state. */ + es_clearerr (hd->fp_read); + ((cookie_t)(hd->read_cookie))->up_to_empty_line = 1; + hd->in_data = 0; + + if (hd->status_code >= 200 && hd->status_code < 300 ) + err = 0; /* Success. */ + else if (hd->status_code == 407) + { + if (opt_debug) + log_debug ("http.c:proxy_connect: 407 seen\n"); + parms = NULL; + for (idx=0; (s = http_get_header (hd, "Proxy-Authenticate", idx)); idx++) + { + if (opt_debug) + log_debug ("http.c:proxy_connect: method=%s\n", s); + if (!parms) + parms = has_leading_keyword (s, "Negotiate"); + } + if (!parms) + authstate = AUTH_NGT_NONE; + else if (authstate == AUTH_NGT_NONE) + authstate = AUTH_NGT_RCVD; + + switch (authstate) + { + case AUTH_NGT_NONE: + if (opt_debug) + log_debug ("http.c:proxy_connect: no supported auth method\n"); + err = gpg_error (GPG_ERR_NO_AUTH); + break; + + case AUTH_NGT_RCVD: + if (opt_debug) + log_debug ("http.c:proxy_connect: using negotiate - init\n"); + err = proxy_get_token (proxy, NULL); + if (err) + goto leave; + if (proxy->outtoklen) /* Authentication needs to continue. */ + { + xfree (authhdr); + authhdr = make_header_line ("Proxy-Authorization: Negotiate ", + "\r\n", + proxy->outtoken, proxy->outtoklen); + if (!authhdr) + { + err = gpg_error_from_syserror (); + goto leave; + } + authstate = AUTH_NGT_SENT; + authpasses++; + goto again; + } + break; + + case AUTH_NGT_SENT: + if (opt_debug) + log_debug ("http.c:proxy_connect: using negotiate - next\n"); + if (!*parms) + { + log_debug ("proxy authentication failed" + " due to server not accepting our challenge\n"); + err = gpg_error (GPG_ERR_BAD_AUTH); + goto leave; + } + if (authpasses > 5) + { + log_error ("proxy authentication failed" + " due to too many passes\n"); + err = gpg_error (GPG_ERR_BAD_AUTH); + goto leave; + + } + err = proxy_get_token (proxy, parms); + if (err) + goto leave; + if (proxy->outtoklen) /* Authentication needs to continue. */ + { + xfree (authhdr); + authhdr = make_header_line ("Proxy-Authorization: Negotiate ", + "\r\n", + proxy->outtoken, proxy->outtoklen); + if (!authhdr) + { + err = gpg_error_from_syserror (); + goto leave; + } + authpasses++; + goto again; + } + break; + + default: + BUG(); + } + } + else + err = gpg_error (GPG_ERR_NO_DATA); + + if (err) + { + xfree (tmpstr); tmpstr = es_bsprintf ("%s:%hu", httphost ? httphost : server, port); log_error (_("error accessing '%s': http status %u\n"), tmpstr ? tmpstr : "out of core", http_get_status_code (hd)); - xfree (tmpstr); - err = gpg_error (GPG_ERR_NO_DATA); goto leave; } leave: + /* Restore flags, destroy stream, reset state. */ + hd->flags = saved_flags; + es_fclose (hd->fp_read); + hd->fp_read = NULL; + hd->read_cookie = NULL; + hd->keep_alive = 0; + hd->in_data = 0; + xfree (request); xfree (authhdr); + xfree (tmpstr); return err; } #endif /*USE_TLS*/ @@ -2810,19 +3133,26 @@ store_header (http_t hd, char *line) p++; value = p; - for (h=hd->headers; h; h = h->next) - if ( !strcmp (h->name, line) ) - break; - if (h) + /* Check whether we have already seen a line with that name. In + * that case we assume it is a comma separated list and merge + * them. Of course there are a few exceptions. */ + if (!strcmp (line, "Proxy-Authenticate") + || !strcmp (line, "Www-Authenticate")) + ; /* Better to have them separate. */ + else { - /* We have already seen a line with that name. Thus we assume - * it is a comma separated list and merge them. */ - p = strconcat (h->value, ",", value, NULL); - if (!p) - return gpg_err_code_from_syserror (); - xfree (h->value); - h->value = p; - return 0; + for (h=hd->headers; h; h = h->next) + if ( !strcmp (h->name, line) ) + break; + if (h) + { + p = strconcat (h->value, ",", value, NULL); + if (!p) + return gpg_err_code_from_syserror (); + xfree (h->value); + h->value = p; + return 0; + } } /* Append a new header. */ From 9a3e41c151febbbe5506283e2edef85d1d4ea94f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 2 Oct 2023 12:53:41 +0200 Subject: [PATCH 199/869] common: Improve lock strategy for dotlock. * common/dotlock.c (next_wait_interval): New. (dotlock_take_unix): Use new function. (dotlock_take_w32): Ditto. -- In particular when using a dotlock file for protecting the spawning and several processes try to spawn the agent or another component, we often run into long delays. The solution is to is to exponential backoff and also to reduce the initial delay from 50ms to 4ms. We further limit the maximum wait period to about 2 seconds and then repeat at intervals of 512, 1024 and 2048ms. In the wait-forever case we add a small random value to have different intervals per process. GnuPG-bug-id: 3380 For testing this code snippet in the spawning function might be useful: const char *s; if ((s=getenv("hold_gpg_file"))) while (!gnupg_access (s, F_OK)) gnupg_sleep (1); --- common/dotlock.c | 90 ++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/common/dotlock.c b/common/dotlock.c index ab0a5a6a3..74186b776 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -1011,6 +1011,48 @@ dotlock_destroy (dotlock_t h) } +/* Return true if H has been taken. */ +int +dotlock_is_locked (dotlock_t h) +{ + return h && !!h->locked; +} + + +/* Return the next interval to wait. WTIME and TIMEOUT are pointers + * to the current state and are updated by this function. The + * returned value might be different from the value of WTIME. */ +static int +next_wait_interval (int *wtime, long *timeout) +{ + int result; + + /* Wait until lock has been released. We use retry intervals of 4, + * 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 512, 1024, 2048ms, and + * so on. If wait-forever was requested we add a small random value + * to have different timeouts per process. */ + if (!*wtime) + *wtime = 4; + else if (*wtime < 2048) + *wtime *= 2; + else + *wtime = 512; + + result = *wtime; + if (*wtime > 8 && *timeout < 0) + result += ((unsigned int)getpid() % 37); + + if (*timeout > 0) + { + if (result > *timeout) + result = *timeout; + *timeout -= result; + } + + return result; +} + + #ifdef HAVE_POSIX_SYSTEM /* Unix specific code of make_dotlock. Returns 0 on success and -1 on @@ -1170,27 +1212,14 @@ dotlock_take_unix (dotlock_t h, long timeout) if (timeout) { struct timeval tv; + int wtimereal; - /* Wait until lock has been released. We use increasing retry - intervals of 50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s - but reset it if the lock owner meanwhile changed. */ - if (!wtime || ownerchanged) - wtime = 50; - else if (wtime < 800) - wtime *= 2; - else if (wtime == 800) - wtime = 2000; - else if (wtime < 8000) - wtime *= 2; + if (ownerchanged) + wtime = 0; /* Reset because owner chnaged. */ - if (timeout > 0) - { - if (wtime > timeout) - wtime = timeout; - timeout -= wtime; - } + wtimereal = next_wait_interval (&wtime, &timeout); - sumtime += wtime; + sumtime += wtimereal; if (sumtime >= 1500) { sumtime = 0; @@ -1198,9 +1227,8 @@ dotlock_take_unix (dotlock_t h, long timeout) pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):""); } - - tv.tv_sec = wtime / 1000; - tv.tv_usec = (wtime % 1000) * 1000; + tv.tv_sec = wtimereal / 1000; + tv.tv_usec = (wtimereal % 1000) * 1000; select (0, NULL, NULL, NULL, &tv); goto again; } @@ -1242,28 +1270,14 @@ dotlock_take_w32 (dotlock_t h, long timeout) if (timeout) { - /* Wait until lock has been released. We use retry intervals of - 50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s. */ - if (!wtime) - wtime = 50; - else if (wtime < 800) - wtime *= 2; - else if (wtime == 800) - wtime = 2000; - else if (wtime < 8000) - wtime *= 2; + int wtimereal; - if (timeout > 0) - { - if (wtime > timeout) - wtime = timeout; - timeout -= wtime; - } + wtimereal = next_wait_interval (&wtime, &timeout); if (wtime >= 800) my_info_1 (_("waiting for lock %s...\n"), h->lockname); - Sleep (wtime); + Sleep (wtimereal); goto again; } From 4206d89003d13af1385d5d2d957378cfc2c7fd4c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 3 Oct 2023 11:44:11 +0900 Subject: [PATCH 200/869] tests:gpgscm: Fix process select loop. * tests/gpgscm/ffi.c (do_process_spawn_io): Clear READ_FDSET in the loop. -- Signed-off-by: NIIBE Yutaka --- tests/gpgscm/ffi.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index cac052138..36b0b98d2 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -1025,19 +1025,13 @@ do_process_spawn_io (scheme *sc, pointer args) fd_set read_fdset; ssize_t bytes_read; - if (out_fd < 0) - goto errout; - - if (err_fd < 0) - goto errout; - - FD_ZERO (&read_fdset); - while (1) { int nfd; int ret; + FD_ZERO (&read_fdset); + if (out_fd >= 0) FD_SET (out_fd, &read_fdset); From 321f9c0a3f2873cb3007e2bc2a542bbd0b2cc974 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 3 Oct 2023 11:53:00 +0900 Subject: [PATCH 201/869] tests:tpm2dtests: Fix tests with TPM2D. * tests/tpm2dtests/Makefile.am (TESTS_ENVIRONMENT): Fix. * tests/tpm2dtests/all-tests.scm: Follow the change of gpgscm. * tests/tpm2dtests/run-tests.scm: Likewise. -- GnuPG-bug-id: 6052 Signed-off-by: NIIBE Yutaka --- tests/tpm2dtests/Makefile.am | 4 ++-- tests/tpm2dtests/all-tests.scm | 21 ++++++++++++--------- tests/tpm2dtests/run-tests.scm | 2 ++ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/tests/tpm2dtests/Makefile.am b/tests/tpm2dtests/Makefile.am index 72ad11d9b..6048d201c 100644 --- a/tests/tpm2dtests/Makefile.am +++ b/tests/tpm2dtests/Makefile.am @@ -34,10 +34,10 @@ TESTS_ENVIRONMENT = LC_ALL=C \ PATH="../gpgscm:$(PATH)" \ abs_top_srcdir="$(abs_top_srcdir)" \ objdir="$(abs_top_builddir)" \ - TPMSERVER="$(TPMSERVER)" \ + TPMSERVER="$(TPMSERVER)" TSSSTARTUP="$(TSSSTARTUP)" \ SWTPM="$(SWTPM)" \ SWTPM_IOCTL="$(SWTPM_IOCTL)" \ - GNUPG_BUILD_ROOT="$(abs_top_builddir)/tests" \ + GNUPG_BUILD_ROOT="$(abs_top_builddir)" \ GNUPG_IN_TEST_SUITE=fact \ GPGSCM_PATH="$(abs_top_srcdir)/tests/gpgscm" diff --git a/tests/tpm2dtests/all-tests.scm b/tests/tpm2dtests/all-tests.scm index bf7a981ca..8934f01f2 100644 --- a/tests/tpm2dtests/all-tests.scm +++ b/tests/tpm2dtests/all-tests.scm @@ -30,8 +30,9 @@ (make-environment-cache (test::scm #f - (path-join "tests" "openpgp" "setup.scm") - (in-srcdir "tests" "openpgp" "setup.scm")))) + #f + (path-join "tests" "tpm2dtests" "setup.scm") + (in-srcdir "tests" "tpm2dtests" "setup.scm")))) (define (qualify path variant) (string-append "<" variant ">" path)) @@ -40,8 +41,9 @@ (make-environment-cache (test::scm #f - (qualify (path-join "tests" "openpgp" "setup.scm") variant) - (in-srcdir "tests" "openpgp" "setup.scm") + variant + (path-join "tests" "tpm2dtests" "setup.scm") + (in-srcdir "tests" "tpm2dtests" "setup.scm") (string-append "--" variant)))) (define setup-use-keyring (setup* "use-keyring")) @@ -55,7 +57,8 @@ (define tests (map (lambda (name) (test::scm setup - (qualify (path-join "tests" "tpm2dtests" name) "standard") + "standards" + (path-join "tests" "tpm2dtests" name) (in-srcdir "tests" "tpm2dtests" name))) all-tests)) (when *run-all-tests* @@ -65,15 +68,15 @@ ;; The second pass uses the keyboxd (map (lambda (name) (test::scm setup-use-keyboxd - (qualify (path-join "tests" "tpm2dtests" name) - "keyboxd") + "keyboxd" + (path-join "tests" "tpm2dtests" name) (in-srcdir "tests" "tpm2dtests" name) "--use-keyboxd")) all-tests) ;; The third pass uses the legact pubring.gpg (map (lambda (name) (test::scm setup-use-keyring - (qualify (path-join "tests" "tpm2dtests" name) - "keyring") + "keyring" + (path-join "tests" "tpm2dtests" name) (in-srcdir "tests" "tpm2dtests" name) "--use-keyring")) all-tests) ))) diff --git a/tests/tpm2dtests/run-tests.scm b/tests/tpm2dtests/run-tests.scm index fdf1859a8..638d3a8a1 100644 --- a/tests/tpm2dtests/run-tests.scm +++ b/tests/tpm2dtests/run-tests.scm @@ -29,6 +29,7 @@ (define setup (make-environment-cache (test::scm #f + #f (path-join "tests" "tpm2dtests" "setup.scm") (in-srcdir "tests" "tpm2dtests" "setup.scm")))) @@ -38,6 +39,7 @@ (load-tests "tests" "tpm2dtests") (map (lambda (name) (test::scm setup + #f (path-join "tests" "tpm2dtests" name) (in-srcdir "tests" "tpm2dtests" name) "--use-keyring")) tests))) From 25c84ffd1078e6619761aa731a82dbaf4175c02e Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 3 Oct 2023 16:51:46 +0900 Subject: [PATCH 202/869] tools: Add TPM2DAEMON_SOCK_NAME for --remove-socketdir. * tools/gpgconf.c (main): Care about tpm2d. Emit correct ERR. -- Signed-off-by: NIIBE Yutaka --- tools/gpgconf.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 522ce517b..30dd8edfd 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -963,7 +963,8 @@ main (int argc, char **argv) GPG_AGENT_SSH_SOCK_NAME, SCDAEMON_SOCK_NAME, KEYBOXD_SOCK_NAME, - DIRMNGR_SOCK_NAME + DIRMNGR_SOCK_NAME, + TPM2DAEMON_SOCK_NAME }; int i; char *p; @@ -976,8 +977,11 @@ main (int argc, char **argv) xfree (p); } if (gnupg_rmdir (socketdir)) - gc_error (1, 0, "error removing '%s': %s", - socketdir, gpg_strerror (err)); + { + err = gpg_error_from_syserror (); + gc_error (1, 0, "error removing '%s': %s", + socketdir, gpg_strerror (err)); + } } else if (gpg_err_code (err) == GPG_ERR_ENOENT) gc_error (0, 0, "warning: removing '%s' failed: %s", From f2ca727978da5b1ed84f97bf37d604e8a4e60091 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 3 Oct 2023 16:55:02 +0900 Subject: [PATCH 203/869] build: Simplify detecting a TPM emulator. * configure.ac (TPMSERVER): Don't supply hard-coded path. (SWTPM, SWTPM_IOCTL, TSSSTARTUP): Likewise. -- Having hard-coded path has bad side effect; It may not be detected even if it's available with PATH. Signed-off-by: NIIBE Yutaka --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 1729cf4f5..118e588f7 100644 --- a/configure.ac +++ b/configure.ac @@ -1615,10 +1615,10 @@ if test "$build_tpm2d" = "yes"; then if test "$have_libtss" != no; then AC_DEFINE(HAVE_LIBTSS, 1, [Defined if we have TPM2 support library]) # look for a TPM emulator for testing - AC_PATH_PROG(TPMSERVER, tpm_server,,/bin:/usr/bin:/usr/lib/ibmtss:/usr/libexec/ibmtss) - AC_PATH_PROG(SWTPM, swtpm,,/bin:/usr/bin:/usr/lib/ibmtss:/usr/libexec/ibmtss) - AC_PATH_PROG(SWTPM_IOCTL, swtpm_ioctl,,/bin:/usr/bin:/usr/lib/ibmtss:/usr/libexec/ibmtss) - AC_PATH_PROG(TSSSTARTUP, tssstartup,,/bin:/usr/bin:/usr/lib/ibmtss:/usr/libexec/ibmtss) + AC_PATH_PROG(TPMSERVER, tpm_server) + AC_PATH_PROG(SWTPM, swtpm) + AC_PATH_PROG(SWTPM_IOCTL, swtpm_ioctl) + AC_PATH_PROG(TSSSTARTUP, tssstartup) fi fi if test "$have_libtss" = no; then From 08e529fa7cfa8f55256337dd525fe8724c78cd92 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 4 Oct 2023 10:23:30 +0900 Subject: [PATCH 204/869] agent: Fix agent_update_private_key. * agent/findkey.c (agent_update_private_key): Check FNAME0. -- Fixes-commit: a216e9c028ee389c4bf0250b822d567ffe9ad85e Signed-off-by: NIIBE Yutaka --- agent/findkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/findkey.c b/agent/findkey.c index c2f6c3d4c..a5f022574 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -333,7 +333,7 @@ agent_update_private_key (const unsigned char *grip, nvc_t pk) int blocksigs = 0; fname0 = fname_from_keygrip (grip, 0); - if (!fname) + if (!fname0) { err = gpg_error_from_syserror (); goto leave; From 68b7aff9ce345c1f73f84d6b1106eab956d75510 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 4 Oct 2023 10:23:30 +0900 Subject: [PATCH 205/869] agent: Fix agent_update_private_key. * agent/findkey.c (agent_update_private_key): Check FNAME0. -- Cherry-pick master commit of: 08e529fa7cfa8f55256337dd525fe8724c78cd92 Fixes-commit: a216e9c028ee389c4bf0250b822d567ffe9ad85e Signed-off-by: NIIBE Yutaka --- agent/findkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/findkey.c b/agent/findkey.c index 41f911cf8..eb2b7a17a 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -333,7 +333,7 @@ agent_update_private_key (const unsigned char *grip, nvc_t pk) int blocksigs = 0; fname0 = fname_from_keygrip (grip, 0); - if (!fname) + if (!fname0) { err = gpg_error_from_syserror (); goto leave; From 98dd6f7af6aa3dcce19f20c22e3f825676e6b184 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 4 Oct 2023 18:30:33 +0900 Subject: [PATCH 206/869] tests:tpm2dtests: Fix tests with SWTPM. * configure.ac (TEST_LIBTSS): Fix the condition with SWTPM. * tests/tpm2dtests/start_sw_tpm.sh: Use --daemon and --pid to run SWTPM. -- GnuPG-bug-id: 6052 Signed-off-by: NIIBE Yutaka --- configure.ac | 2 +- tests/tpm2dtests/start_sw_tpm.sh | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 118e588f7..8f09bb06a 100644 --- a/configure.ac +++ b/configure.ac @@ -1627,7 +1627,7 @@ fi AC_SUBST(LIBTSS_LIBS) AC_SUBST(LIBTSS_CFLAGS) AM_CONDITIONAL(HAVE_LIBTSS, test "$have_libtss" != no) -AM_CONDITIONAL(TEST_LIBTSS, test -n "$TPMSERVER" || test -n "$SWTPM" && test -n "$TSSSTARTUP") +AM_CONDITIONAL(TEST_LIBTSS, test -n "$TPMSERVER" -o -n "$SWTPM" -a -n "$TSSSTARTUP" -a -n "$SWTPM_IOCTL") AC_SUBST(HAVE_LIBTSS) # diff --git a/tests/tpm2dtests/start_sw_tpm.sh b/tests/tpm2dtests/start_sw_tpm.sh index 36e1a806e..fc86801e2 100755 --- a/tests/tpm2dtests/start_sw_tpm.sh +++ b/tests/tpm2dtests/start_sw_tpm.sh @@ -3,12 +3,15 @@ # remove any prior TPM contents rm -f NVChip h*.bin *.permall if [ -x "${SWTPM}" ]; then - ${SWTPM} socket --tpm2 --server type=tcp,port=2321 \ - --ctrl type=tcp,port=2322 --tpmstate dir=`pwd` & + ${SWTPM} socket --tpm2 --daemon \ + --pid file=swtpm.pid \ + --server type=tcp,port=2321 \ + --ctrl type=tcp,port=2322 --tpmstate dir=`pwd` + pid=$(cat swtpm.pid) else ${TPMSERVER} > /dev/null 2>&1 & + pid=$! fi -pid=$! ## # This powers on the tpm and starts it # then we derive the RSA version of the storage seed and From 227b3b14f4be2f33ed721818c2186e7fca4cebdf Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 5 Oct 2023 10:21:35 +0900 Subject: [PATCH 207/869] tests:tpm2dtests: Modify tests with SWTPM and relax the condition. * configure.ac (SWTPM_IOCTL): Remove. (TEST_LIBTSS): Fix the condition. * tests/tpm2dtests/Makefile.am (TESTS_ENVIRONMENT): Remove SWTPM_IOCTL. * tests/tpm2dtests/start_sw_tpm.sh: Add --flags to invoke SWTPM, not requiring SWTPM_IOCTL and TSSSTARTUP any more. -- GnuPG-bug-id: 6052 Signed-off-by: NIIBE Yutaka --- configure.ac | 5 ++- tests/tpm2dtests/Makefile.am | 1 - tests/tpm2dtests/start_sw_tpm.sh | 55 ++++++++++++++++---------------- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/configure.ac b/configure.ac index 8f09bb06a..299d39664 100644 --- a/configure.ac +++ b/configure.ac @@ -1616,9 +1616,8 @@ if test "$build_tpm2d" = "yes"; then AC_DEFINE(HAVE_LIBTSS, 1, [Defined if we have TPM2 support library]) # look for a TPM emulator for testing AC_PATH_PROG(TPMSERVER, tpm_server) - AC_PATH_PROG(SWTPM, swtpm) - AC_PATH_PROG(SWTPM_IOCTL, swtpm_ioctl) AC_PATH_PROG(TSSSTARTUP, tssstartup) + AC_PATH_PROG(SWTPM, swtpm) fi fi if test "$have_libtss" = no; then @@ -1627,7 +1626,7 @@ fi AC_SUBST(LIBTSS_LIBS) AC_SUBST(LIBTSS_CFLAGS) AM_CONDITIONAL(HAVE_LIBTSS, test "$have_libtss" != no) -AM_CONDITIONAL(TEST_LIBTSS, test -n "$TPMSERVER" -o -n "$SWTPM" -a -n "$TSSSTARTUP" -a -n "$SWTPM_IOCTL") +AM_CONDITIONAL(TEST_LIBTSS, test -n "$SWTPM" -o -n "$TPMSERVER" -a -n "$TSSSTARTUP") AC_SUBST(HAVE_LIBTSS) # diff --git a/tests/tpm2dtests/Makefile.am b/tests/tpm2dtests/Makefile.am index 6048d201c..ceaf56420 100644 --- a/tests/tpm2dtests/Makefile.am +++ b/tests/tpm2dtests/Makefile.am @@ -36,7 +36,6 @@ TESTS_ENVIRONMENT = LC_ALL=C \ objdir="$(abs_top_builddir)" \ TPMSERVER="$(TPMSERVER)" TSSSTARTUP="$(TSSSTARTUP)" \ SWTPM="$(SWTPM)" \ - SWTPM_IOCTL="$(SWTPM_IOCTL)" \ GNUPG_BUILD_ROOT="$(abs_top_builddir)" \ GNUPG_IN_TEST_SUITE=fact \ GPGSCM_PATH="$(abs_top_srcdir)/tests/gpgscm" diff --git a/tests/tpm2dtests/start_sw_tpm.sh b/tests/tpm2dtests/start_sw_tpm.sh index fc86801e2..a44833e28 100755 --- a/tests/tpm2dtests/start_sw_tpm.sh +++ b/tests/tpm2dtests/start_sw_tpm.sh @@ -3,36 +3,35 @@ # remove any prior TPM contents rm -f NVChip h*.bin *.permall if [ -x "${SWTPM}" ]; then - ${SWTPM} socket --tpm2 --daemon \ - --pid file=swtpm.pid \ - --server type=tcp,port=2321 \ - --ctrl type=tcp,port=2322 --tpmstate dir=`pwd` - pid=$(cat swtpm.pid) + ${SWTPM} socket --tpm2 --daemon \ + --pid file=swtpm.pid \ + --server type=tcp,port=2321 \ + --ctrl type=tcp,port=2322 \ + --flags not-need-init,startup-clear \ + --tpmstate dir=`pwd` + cat swtpm.pid else ${TPMSERVER} > /dev/null 2>&1 & pid=$! -fi -## -# This powers on the tpm and starts it -# then we derive the RSA version of the storage seed and -# store it permanently at handle 81000001 and flush the transient -## -a=0; while [ $a -lt 10 ]; do - if [ -x "${SWTPM_IOCTL}" ]; then - ${SWTPM_IOCTL} --tcp 127.0.0.1:2322 -i > /dev/null 2>&1 - else - tsspowerup > /dev/null 2>&1 + ## + # This powers on the tpm and starts it + # then we derive the RSA version of the storage seed and + # store it permanently at handle 81000001 and flush the transient + ## + a=0 + while [ $a -lt 10 ]; do + tsspowerup > /dev/null 2>&1 + if [ $? -eq 0 ]; then + break; + fi + sleep 1 + a=$[$a+1] + done + if [ $a -eq 10 ]; then + echo "Waited 10s for tpm_server to come up; exiting" + exit 1 fi - if [ $? -eq 0 ]; then - break; - fi - sleep 1 - a=$[$a+1] -done -if [ $a -eq 10 ]; then - echo "Waited 10s for tpm_server to come up; exiting" - exit 1 -fi -tssstartup || exit 1 -echo -n $pid + ${TSSSTARTUP} || exit 1 + echo -n $pid +fi From 16b6b7753229a41fb3b4bf77d34873db8f3cb682 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 5 Oct 2023 14:00:46 +0900 Subject: [PATCH 208/869] Minor style fixes. -- Signed-off-by: NIIBE Yutaka --- doc/debugging.texi | 4 +-- doc/dirmngr.texi | 32 ++++++++--------- doc/gpg-agent.texi | 24 ++++++------- doc/gpg.texi | 56 ++++++++++++++--------------- doc/gpgsm.texi | 28 +++++++-------- doc/howto-create-a-server-cert.texi | 2 +- doc/scdaemon.texi | 8 ++--- doc/specify-user-id.texi | 4 +-- doc/tools.texi | 10 +++--- doc/wks.texi | 2 +- 10 files changed, 85 insertions(+), 85 deletions(-) diff --git a/doc/debugging.texi b/doc/debugging.texi index 6639e184b..a389bdf50 100644 --- a/doc/debugging.texi +++ b/doc/debugging.texi @@ -91,7 +91,7 @@ should not occur but sometimes things go wrong), run it using @item How to find the IP address of a keyserver If a round robin URL of is used for a keyserver -(e.g. subkeys.gnupg.org); it is not easy to see what server is actually +(e.g., subkeys.gnupg.org); it is not easy to see what server is actually used. Using the keyserver debug option as in @smallexample @@ -130,7 +130,7 @@ but Dirmngr's OCSP feature has not been enabled using The far most common reason for this is that the environment variable @code{GPG_TTY} has not been set correctly. Make sure that it has been set to a real tty device and not just to @samp{/dev/tty}; -i.e. @samp{GPG_TTY=tty} is plainly wrong; what you want is +i.e., @samp{GPG_TTY=tty} is plainly wrong; what you want is @samp{GPG_TTY=`tty`} --- note the back ticks. Also make sure that this environment variable gets exported, that is you should follow up the setting with an @samp{export GPG_TTY} (assuming a Bourne style diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index fb448752a..0d0cb018d 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -180,7 +180,7 @@ available flags the sole word "help" can be used. This option is only useful for testing; it sets the system time back or forth to @var{epoch} which is the number of seconds elapsed since the year 1970. Alternatively @var{epoch} may be given as a full ISO time string -(e.g. "20070924T154812"). +(e.g., "20070924T154812"). @item --debug-level @var{level} @opindex debug-level @@ -213,7 +213,7 @@ however carefully selected to best aid in debugging. @item --debug @var{flags} @opindex debug Set debug flags. All flags are or-ed and @var{flags} may be given in -C syntax (e.g. 0x0042) or as a comma separated list of flag names. To +C syntax (e.g., 0x0042) or as a comma separated list of flag names. To get a list of all supported flags the single word "help" can be used. This option is only useful for debugging and the behavior may change at any time without notice. @@ -374,7 +374,7 @@ there for details; here is an example: as given. Replace USERNAME, PASSWORD, and the 'dc' parts according to the instructions received from your LDAP administrator. Note that only simple authentication - (i.e. cleartext passwords) is supported and thus using ldaps is + (i.e., cleartext passwords) is supported and thus using ldaps is strongly suggested (since 2.2.28 "ldaps" defaults to port 389 and uses STARTTLS). On Windows authentication via AD can be requested by adding @code{gpgNtds=1} after the fourth question @@ -465,7 +465,7 @@ Lines starting with a @samp{#} are comments. Note that as usual all strings entered are expected to be UTF-8 encoded. Obviously this will lead to problems if the password has originally been encoded as Latin-1. There is no other solution here than to put such a -password in the binary encoding into the file (i.e. non-ascii characters +password in the binary encoding into the file (i.e., non-ascii characters won't show up readable).@footnote{The @command{gpgconf} tool might be helpful for frontends as it enables editing this configuration file using percent-escaped strings.} @@ -681,7 +681,7 @@ those certificates on startup and when given a SIGHUP. Certificates which are not readable or do not make up a proper X.509 certificate are ignored; see the log file for details. -Applications using dirmngr (e.g. gpgsm) can request these +Applications using dirmngr (e.g., gpgsm) can request these certificates to complete a trust chain in the same way as with the extra-certs directory (see below). @@ -690,7 +690,7 @@ Note that for OCSP responses the certificate specified using the option @item /etc/gnupg/extra-certs This directory may contain extra certificates which are preloaded -into the internal cache on startup. Applications using dirmngr (e.g. gpgsm) +into the internal cache on startup. Applications using dirmngr (e.g., gpgsm) can request cached certificates to complete a trust chain. This is convenient in cases you have a couple intermediate CA certificates or certificates usually used to sign OCSP responses. @@ -799,7 +799,7 @@ Enter @code{HELP} at the prompt to see a list of commands and enter @node Dirmngr Signals @section Use of signals -A running @command{dirmngr} may be controlled by signals, i.e. using +A running @command{dirmngr} may be controlled by signals, i.e., using the @command{kill} command to send a signal to the process. Here is a list of supported signals: @@ -1031,7 +1031,7 @@ includes a local certificate store as well as a list of trusted root certificates. @noindent -The return code is 0 for success; i.e. the certificate has not been +The return code is 0 for success; i.e., the certificate has not been revoked or one of the usual error codes from libgpg-error. @node Dirmngr CHECKOCSP @@ -1066,7 +1066,7 @@ of the global option @option{--ignore-ocsp-service-url}. @noindent -The return code is 0 for success; i.e. the certificate has not been +The return code is 0 for success; i.e., the certificate has not been revoked or one of the usual error codes from libgpg-error. @node Dirmngr CACHECERT @@ -1088,7 +1088,7 @@ Thus the caller is expected to return the certificate for the request as a binary blob. @noindent -The return code is 0 for success; i.e. the certificate has not been +The return code is 0 for success; i.e., the certificate has not been successfully cached or one of the usual error codes from libgpg-error. @node Dirmngr VALIDATE @@ -1188,7 +1188,7 @@ as a binary blob. @c does not yet end up in memory. @c * @code{crl_cache_insert} is called with that descriptor to @c actually read the CRL into the cache. See below for a -@c description of this function. If there is any error (e.g. read +@c description of this function. If there is any error (e.g., read @c problem, CRL not correctly signed or verification of signature @c not possible), this descriptor is rejected and we continue @c with the next name. If the CRL has been successfully loaded, @@ -1214,7 +1214,7 @@ as a binary blob. @c a) An authorityKeyIdentifier with an issuer and serialno exits: The @c certificate is retrieved using @code{find_cert_bysn}. If @c the certificate is in the certificate cache, it is directly -@c returned. Then the requester (i.e. the client who requested the +@c returned. Then the requester (i.e., the client who requested the @c CRL check) is asked via the Assuan inquiry ``SENDCERT'' whether @c he can provide this certificate. If this succeed the returned @c certificate gets cached and returned. Note, that dirmngr does not @@ -1293,7 +1293,7 @@ as a binary blob. @c expiration time of all certificates in the chain. @c @c We first check that the certificate may be used for the requested -@c purpose (i.e. OCSP or CRL signing). If this is not the case +@c purpose (i.e., OCSP or CRL signing). If this is not the case @c GPG_ERR_WRONG_KEY_USAGE is returned. @c @c The next step is to find the trust anchor (root certificate) and to @@ -1317,7 +1317,7 @@ as a binary blob. @c Now the issuer's certificate is looked up: If an @c authorityKeyIdentifier is available, this one is used to locate the @c certificate either using issuer and serialnumber or subject DN -@c (i.e. the issuer's DN) and the keyID. The functions +@c (i.e., the issuer's DN) and the keyID. The functions @c @code{find_cert_bysn) and @code{find_cert_bysubject} are used @c respectively. The have already been described above under the @c description of @code{crl_cache_insert}. If no certificate was found @@ -1331,13 +1331,13 @@ as a binary blob. @c actual certificate is checked and in case this fails the error @c #code{GPG_ERR_BAD_CERT_CHAIN} is returned. If the signature checks out, the @c maximum chain length of the issuing certificate is checked as well as -@c the capability of the certificate (i.e. whether he may be used for +@c the capability of the certificate (i.e., whether he may be used for @c certificate signing). Then the certificate is prepended to our list @c representing the certificate chain. Finally the loop is continued now @c with the issuer's certificate as the current certificate. @c @c After the end of the loop and if no error as been encountered -@c (i.e. the certificate chain has been assempled correctly), a check is +@c (i.e., the certificate chain has been assempled correctly), a check is @c done whether any certificate expired or a critical policy has not been @c met. In any of these cases the validation terminates with an @c appropriate error. diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 902de56f4..6d6cf97ec 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -72,7 +72,7 @@ the included Secure Shell Agent you may start the agent using: @c One way of enforcing this split is a per-key or per-session @c passphrase, known only by the owner, which must be supplied to the @c agent to permit the use of the secret key material. Another way is -@c with an out-of-band permission mechanism (e.g. a button or GUI +@c with an out-of-band permission mechanism (e.g@:. a button or GUI @c interface that the owner has access to, but the supplicant does not). @c @c The rationale for this separation is that it allows access to the @@ -111,8 +111,8 @@ Please make sure that a proper pinentry program has been installed under the default filename (which is system dependent) or use the option @option{pinentry-program} to specify the full name of that program. It is often useful to install a symbolic link from the actual used -pinentry (e.g. @file{@value{BINDIR}/pinentry-gtk}) to the expected -one (e.g. @file{@value{BINDIR}/pinentry}). +pinentry (e.g., @file{@value{BINDIR}/pinentry-gtk}) to the expected +one (e.g., @file{@value{BINDIR}/pinentry}). @manpause @noindent @@ -178,7 +178,7 @@ If in @file{common.conf} the option @option{no-autostart} is set, any start attempts will be ignored. In --supervised mode, different file descriptors can be provided for -use as different socket types (e.g. ssh, extra) as long as they are +use as different socket types (e.g., ssh, extra) as long as they are identified in the environment variable @code{LISTEN_FDNAMES} (see sd_listen_fds(3) on some Linux distributions for more information on this convention). @@ -259,7 +259,7 @@ however carefully selected to best aid in debugging. @item --debug @var{flags} @opindex debug Set debug flags. All flags are or-ed and @var{flags} may be given -in C syntax (e.g. 0x0042) or as a comma separated list of flag names. +in C syntax (e.g., 0x0042) or as a comma separated list of flag names. To get a list of all supported flags the single word "help" can be used. This option is only useful for debugging and the behavior may change at any time without notice. @@ -345,7 +345,7 @@ specify the logging output. @anchor{option --no-allow-mark-trusted} @item --no-allow-mark-trusted @opindex no-allow-mark-trusted -Do not allow clients to mark keys as trusted, i.e. put them into the +Do not allow clients to mark keys as trusted, i.e., put them into the @file{trustlist.txt} file. This makes it harder for users to inadvertently accept Root-CA keys. @@ -705,7 +705,7 @@ The order in which keys are presented to ssh are: Editing the "Use-for-ssh" values can be done with an editor or using @command{gpg-connect-agent} and "KEYATTR" (Remember to append a colon -to the key; i.e. use "Use-for-ssh:"). +to the key; i.e., use "Use-for-ssh:"). @anchor{option --ssh-fingerprint-digest} @@ -713,7 +713,7 @@ to the key; i.e. use "Use-for-ssh:"). @opindex ssh-fingerprint-digest Select the digest algorithm used to compute ssh fingerprints that are -communicated to the user, e.g. in pinentry dialogs. OpenSSH has +communicated to the user, e.g., in pinentry dialogs. OpenSSH has transitioned from using MD5 to the more secure SHA256. @@ -819,7 +819,7 @@ It might even be advisable to change the permissions to read-only so that this file can't be changed inadvertently. As a special feature a line @code{include-default} will include a global -list of trusted certificates (e.g. @file{@value{SYSCONFDIR}/trustlist.txt}). +list of trusted certificates (e.g., @file{@value{SYSCONFDIR}/trustlist.txt}). This global list is also used if the local list is not available; the @ref{option --no-user-trustlist} enforces the use of only this global list. @@ -881,7 +881,7 @@ The keygrip may be prefixed with a @code{!} to disable an entry. The following example lists exactly one key. Note that keys available through a OpenPGP smartcard in the active smartcard reader are -implicitly added to this list; i.e. there is no need to list them. +implicitly added to this list; i.e., there is no need to list them. @cartouche @smallexample @@ -914,7 +914,7 @@ a small helper script is provided to create these files (@pxref{addgnupghome}). @mansect signals @node Agent Signals @section Use of some signals -A running @command{gpg-agent} may be controlled by signals, i.e. using +A running @command{gpg-agent} may be controlled by signals, i.e., using the @command{kill} command to send a signal to the process. Here is a list of supported signals: @@ -1396,7 +1396,7 @@ convention either the hexified fingerprint of the key shall be used for calling application and a colon: Like @code{gpg:somestring}. @var{error_message} is either a single @code{X} for no error message or -a string to be shown as an error message like (e.g. "invalid +a string to be shown as an error message like (e.g., "invalid passphrase"). Blanks must be percent escaped or replaced by @code{+}'. @var{prompt} is either a single @code{X} for a default prompt or the diff --git a/doc/gpg.texi b/doc/gpg.texi index ce72afbf5..b5a9ccc51 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -330,21 +330,21 @@ The status of the verification is indicated by a flag directly following the "sig" tag (and thus before the flags described below. A "!" indicates that the signature has been successfully verified, a "-" denotes a bad signature and a "%" is used if an error occurred while -checking the signature (e.g. a non supported algorithm). Signatures +checking the signature (e.g., a non supported algorithm). Signatures where the public key is not available are not listed; to see their keyids the command @option{--list-sigs} can be used. For each signature listed, there are several flags in between the signature status flag and keyid. These flags give additional information about each key signature. From left to right, they are -the numbers 1-3 for certificate check level (see +the numbers 1--3 for certificate check level (see @option{--ask-cert-level}), "L" for a local or non-exportable signature (see @option{--lsign-key}), "R" for a nonRevocable signature (see the @option{--edit-key} command "nrsign"), "P" for a signature that contains a policy URL (see @option{--cert-policy-url}), "N" for a signature that contains a notation (see @option{--cert-notation}), "X" for an eXpired signature (see @option{--ask-cert-expire}), and the -numbers 1-9 or "T" for 10 and above to indicate trust signature levels +numbers 1--9 or "T" for 10 and above to indicate trust signature levels (see the @option{--edit-key} command "tsign"). @@ -405,7 +405,7 @@ description, please see the Card HOWTO at https://gnupg.org/documentation/howtos.html#GnuPG-cardHOWTO . Please note that the command "openpgp" can be used to switch to the OpenPGP application of cards which by default are presenting another -application (e.g. PIV). +application (e.g., PIV). @item --card-status @opindex card-status @@ -589,7 +589,7 @@ corrupted trustdb. Example: Update the trustdb with the ownertrust values stored in @code{files} (or STDIN if not given); existing values will be overwritten. In case of a severely damaged trustdb and if you have a recent backup of the -ownertrust values (e.g. in the file @file{otrust.txt}), you may re-create +ownertrust values (e.g., in the file @file{otrust.txt}), you may re-create the trustdb using these commands: @c man:.RS @example @@ -893,7 +893,7 @@ signing. @item delsig @opindex keyedit:delsig Delete a signature. Note that it is not possible to retract a signature, - once it has been send to the public (i.e. to a keyserver). In that case + once it has been send to the public (i.e., to a keyserver). In that case you better use @code{revsig}. @item revsig @@ -927,7 +927,7 @@ signing. @opindex keyedit:deluid Delete a user ID or photographic user ID. Note that it is not possible to retract a user id, once it has been send to the public - (i.e. to a keyserver). In that case you better use @code{revuid}. + (i.e., to a keyserver). In that case you better use @code{revuid}. @item revuid @opindex keyedit:revuid @@ -1047,7 +1047,7 @@ signing. @item delkey @opindex keyedit:delkey Remove a subkey (secondary key). Note that it is not possible to retract - a subkey, once it has been send to the public (i.e. to a keyserver). In + a subkey, once it has been send to the public (i.e., to a keyserver). In that case you better use @code{revkey}. Also note that this only deletes the public part of a key. @@ -1099,7 +1099,7 @@ signing. @item clean @opindex keyedit:clean Compact (by removing all signatures except the selfsig) any user ID - that is no longer usable (e.g. revoked, or expired). Then, remove any + that is no longer usable (e.g., revoked, or expired). Then, remove any signatures that are not usable by the trust calculations. Specifically, this removes any signature that does not validate, any signature that is superseded by a later signature, revoked signatures, @@ -1113,7 +1113,7 @@ signing. @item change-usage @opindex keyedit:change-usage Change the usage flags (capabilities) of the primary key or of - subkeys. These usage flags (e.g. Certify, Sign, Authenticate, + subkeys. These usage flags (e.g., Certify, Sign, Authenticate, Encrypt) are set during key creation. Sometimes it is useful to have the opportunity to change them (for example to add Authenticate) after they have been created. Please take care when @@ -1538,9 +1538,9 @@ will be expanded to a filename containing the photo. "%I" does the same, except the file will not be deleted once the viewer exits. Other flags are "%k" for the key ID, "%K" for the long key ID, "%f" for the key fingerprint, "%t" for the extension of the image type -(e.g. "jpg"), "%T" for the MIME type of the image (e.g. "image/jpeg"), +(e.g., "jpg"), "%T" for the MIME type of the image (e.g., "image/jpeg"), "%v" for the single-character calculated validity of the image being -viewed (e.g. "f"), "%V" for the calculated validity as a string (e.g. +viewed (e.g., "f"), "%V" for the calculated validity as a string (e.g., "full"), "%U" for a base32 encoded hash of the user ID, and "%%" for an actual percent sign. If neither %i or %I are present, then the photo will be supplied to the viewer on standard input. @@ -2019,7 +2019,7 @@ default), that keyserver is tried. Note that the creator of the signature uses the option @option{--sig-keyserver-url} to specify the preferred keyserver for data signatures. -3. If the signature has the Signer's UID set (e.g. using +3. If the signature has the Signer's UID set (e.g., using @option{--sender} while creating the signature) a Web Key Directory (WKD) lookup is done. This is the default configuration but can be disabled by removing WKD from the auto-key-locate list or by using the @@ -2267,7 +2267,7 @@ suppressed on the command line. @itemx --no-require-secmem @opindex require-secmem Refuse to run if GnuPG cannot get secure memory. Defaults to no -(i.e. run, but give a warning). +(i.e., run, but give a warning). @item --require-cross-certification @@ -2397,7 +2397,7 @@ id used to make the signature and embeds that user ID into the created signature (using OpenPGP's ``Signer's User ID'' subpacket). If the option is given multiple times a suitable user ID is picked. However, if the signing key was specified directly by using a mail address -(i.e. not by using a fingerprint or key ID) this option is used and +(i.e., not by using a fingerprint or key ID) this option is used and the mail address is embedded in the created signature. When verifying a signature @var{mbox} is used to restrict the @@ -2506,7 +2506,7 @@ the @option{--status-fd} line ``PROGRESS'' to provide a value for @item --key-origin @var{string}[,@var{url}] @opindex key-origin gpg can track the origin of a key. Certain origins are implicitly -known (e.g. keyserver, web key directory) and set. For a standard +known (e.g., keyserver, web key directory) and set. For a standard import the origin of the keys imported can be set with this option. To list the possible values use "help" for @var{string}. Some origins can store an optional @var{url} argument. That URL can appended to @@ -2674,13 +2674,13 @@ The available properties are: @itemx key_created_d The first is the timestamp a public key or subkey packet was created. The second is the same but given as an ISO string, - e.g. "2016-08-17". (drop-subkey) + e.g., "2016-08-17". (drop-subkey) @item key_expires @itemx key_expires_d The expiration time of a public key or subkey or 0 if it does not expire. The second is the same but given as an ISO date string or - an empty string e.g. "2038-01-19". + an empty string e.g., "2038-01-19". @item fpr The hexified fingerprint of the current subkey or primary key. @@ -2713,7 +2713,7 @@ The available properties are: @itemx sig_created_d The first is the timestamp a signature packet was created. The second is the same but given as an ISO date string, - e.g. "2016-08-17". (drop-sig) + e.g., "2016-08-17". (drop-sig) @item sig_algo A number with the public key algorithm of a signature packet. (drop-sig) @@ -2833,7 +2833,7 @@ obsolete; it does not harm to use it though. @opindex legacy-list-mode Revert to the pre-2.1 public key list mode. This only affects the human readable output and not the machine interface -(i.e. @code{--with-colons}). Note that the legacy format does not +(i.e., @code{--with-colons}). Note that the legacy format does not convey suitable information for elliptic curves. @item --with-fingerprint @@ -2969,7 +2969,7 @@ to safely override the algorithm chosen by the recipient key preferences, as GPG will only select an algorithm that is usable by all recipients. The most highly ranked digest algorithm in this list is also used when signing without encryption -(e.g. @option{--clear-sign} or @option{--sign}). +(e.g., @option{--clear-sign} or @option{--sign}). @item --personal-compress-preferences @var{string} @opindex personal-compress-preferences @@ -2980,7 +2980,7 @@ allows the user to safely override the algorithm chosen by the recipient key preferences, as GPG will only select an algorithm that is usable by all recipients. The most highly ranked compression algorithm in this list is also used when there are no recipient keys -to consider (e.g. @option{--symmetric}). +to consider (e.g., @option{--symmetric}). @item --s2k-cipher-algo @var{name} @opindex s2k-cipher-algo @@ -3006,7 +3006,7 @@ of times (see @option{--s2k-count}). Specify how many times the passphrases mangling for symmetric encryption is repeated. This value may range between 1024 and 65011712 inclusive. The default is inquired from gpg-agent. Note -that not all values in the 1024-65011712 range are legal and if an +that not all values in the 1024--65011712 range are legal and if an illegal value is selected, GnuPG will round up to the nearest legal value. This option is only meaningful if @option{--s2k-mode} is set to the default of 3. @@ -3176,7 +3176,7 @@ however carefully selected to best aid in debugging. @item --debug @var{flags} @opindex debug Set debug flags. All flags are or-ed and @var{flags} may be given -in C syntax (e.g. 0x0042) or as a comma separated list of flag names. +in C syntax (e.g., 0x0042) or as a comma separated list of flag names. To get a list of all supported flags the single word "help" can be used. This option is only useful for debugging and the behavior may change at any time without notice. @@ -3211,7 +3211,7 @@ only useful for certain regression tests. This option is only useful for testing; it sets the system time back or forth to @var{epoch} which is the number of seconds elapsed since the year 1970. Alternatively @var{epoch} may be given as a full ISO -time string (e.g. "20070924T154812"). +time string (e.g., "20070924T154812"). If you suffix @var{epoch} with an exclamation mark (!), the system time will appear to be frozen at the specified time. @@ -3537,7 +3537,7 @@ are: @opindex no-symkey-cache Disable the passphrase cache used for symmetrical en- and decryption. This cache is based on the message specific salt value -(cf. @option{--s2k-mode}). +(cf.@: @option{--s2k-mode}). @item --request-origin @var{origin} @opindex request-origin @@ -4606,7 +4606,7 @@ If you don't give any of them, no user ID is created. @item Expire-Date: @var{iso-date}|(@var{number}[d|w|m|y]) Set the expiration date for the key (and the subkey). It may either -be entered in ISO date format (e.g. "20000815T145012") or as number of +be entered in ISO date format (e.g., "20000815T145012") or as number of days, weeks, month or years after the creation date. The special notation "seconds=N" is also allowed to specify a number of seconds since creation. Without a letter days are assumed. Note that there @@ -4631,7 +4631,7 @@ in the @option{--edit-key} menu. @item Revoker: @var{algo}:@var{fpr} [sensitive] Add a designated revoker to the generated key. Algo is the public key -algorithm of the designated revoker (i.e. RSA=1, DSA=17, etc.) +algorithm of the designated revoker (i.e., RSA=1, DSA=17, etc.) @var{fpr} is the fingerprint of the designated revoker. The optional @samp{sensitive} flag marks the designated revoker as sensitive information. Only v4 keys may be designated revokers. diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index e976767f6..41eb08d16 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -136,7 +136,7 @@ Run in server mode and wait for commands on the @code{stdin}. Behave as a Dirmngr client issuing the request @var{command} with the optional list of @var{args}. The output of the Dirmngr is printed stdout. Please note that file names given as arguments should have an -absolute file name (i.e. commencing with @code{/}) because they are +absolute file name (i.e., commencing with @code{/}) because they are passed verbatim to the Dirmngr and the working directory of the Dirmngr might not be the same as the one of this client. Currently it is not possible to pass data via stdin to the Dirmngr. @var{command} @@ -259,7 +259,7 @@ optional @var{pattern}. Those pattern consist of a list of user ids @option{--armor} option a few informational lines are prepended before each block. There is one limitation: As there is no commonly agreed upon way to pack more than one certificate into an ASN.1 structure, -the binary export (i.e. without using @option{armor}) works only for +the binary export (i.e., without using @option{armor}) works only for the export of one certificate. Thus it is required to specify a @var{pattern} which yields exactly one certificate. Ephemeral certificate are only exported if all @var{pattern} are given as @@ -462,7 +462,7 @@ line of the @file{trustlist.txt} @opindex force-crl-refresh Tell the dirmngr to reload the CRL for each request. For better performance, the dirmngr will actually optimize this by suppressing -the loading for short time intervals (e.g. 30 minutes). This option +the loading for short time intervals (e.g., 30 minutes). This option is useful to make sure that a fresh CRL is available for certificates hold in the keybox. The suggested way of doing this is by using it along with the option @option{--with-validation} for a key listing @@ -539,7 +539,7 @@ Create PEM encoded output. Default is binary output. @item --base64 @opindex base64 -Create Base-64 encoded output; i.e. PEM without the header lines. +Create Base-64 encoded output; i.e., PEM without the header lines. @item --assume-armor @opindex assume-armor @@ -639,7 +639,7 @@ done with @code{--with-colons}. @item --no-pretty-dn @opindex no-pretty-dn By default gpgsm prints distinguished names (DNs) like the Issuer or -Subject in a more readable format (e.g. using a well defined order of +Subject in a more readable format (e.g., using a well defined order of the parts). However, this format can't be used as input strings. This option reverts printing to standard RFC-2253 format and thus avoids the need to use --dump-cert or --with-colons to get the @@ -747,7 +747,7 @@ key database clear of unneeded certificates stored on smartcards. This option is only useful for testing; it sets the system time back or forth to @var{epoch} which is the number of seconds elapsed since the year 1970. Alternatively @var{epoch} may be given as a full ISO time string -(e.g. "20070924T154812"). +(e.g., "20070924T154812"). @item --with-ephemeral-keys @opindex with-ephemeral-keys @@ -794,7 +794,7 @@ however carefully selected to best aid in debugging. @item --debug @var{flags} @opindex debug Set debug flags. All flags are or-ed and @var{flags} may be given -in C syntax (e.g. 0x0042) or as a comma separated list of flag names. +in C syntax (e.g., 0x0042) or as a comma separated list of flag names. To get a list of all supported flags the single word "help" can be used. This option is only useful for debugging and the behavior may change at any time without notice. @@ -967,9 +967,9 @@ This is plain text file with a few help entries used with @command{gpg} and @command{gpgsm}. The standard file has English help texts; to install localized versions use filenames like @file{help.LL.txt} with LL denoting the locale. GnuPG comes with a set of predefined help -files in the data directory (e.g. @file{@value{DATADIR}/gnupg/help.de.txt}) +files in the data directory (e.g., @file{@value{DATADIR}/gnupg/help.de.txt}) and allows overriding of any help item by help files stored in the -system configuration directory (e.g. @file{@value{SYSCONFDIR}/help.de.txt}). +system configuration directory (e.g., @file{@value{SYSCONFDIR}/help.de.txt}). For a reference of the help file's syntax, please see the installed @file{help.txt} file. @@ -980,7 +980,7 @@ This file is a collection of common certificates used to populated a newly created @file{pubring.kbx}. An administrator may replace this file with a custom one. The format is a concatenation of PEM encoded X.509 certificates. This global file is installed in the data directory -(e.g. @file{@value{DATADIR}/com-certs.pem}). +(e.g., @file{@value{DATADIR}/com-certs.pem}). @end table @@ -1093,7 +1093,7 @@ of a transfer error, a program error or tampering with the message). @end table @item Error verifying a signature -For some reason the signature could not be verified, i.e. it cannot be +For some reason the signature could not be verified, i.e., it cannot be decided whether the signature is valid or invalid. A common reason for this is a missing certificate. @@ -1274,7 +1274,7 @@ provides a regular command line interface which exhibits a full client to this protocol (but uses internal linking). To start @command{gpgsm} as a server the command line the option @code{--server} must be used. Additional options are provided to -select the communication method (i.e. the name of the socket). +select the communication method (i.e., the name of the socket). We assume that the connection has already been established; see the Assuan manual for details. @@ -1338,7 +1338,7 @@ correct. OUTPUT FD[=@var{n}] [--armor|--base64] @end example -Set the file descriptor to be used for the output (i.e. the encrypted +Set the file descriptor to be used for the output (i.e., the encrypted message). Obviously the pipe must be open at that point, the server establishes its own end. If the server returns an error the client should consider this session failed. @@ -1382,7 +1382,7 @@ The decryption is done by using the command @end example It performs the decrypt operation after doing some check on the internal -state (e.g. that all needed data has been set). Because it utilizes +state (e.g., that all needed data has been set). Because it utilizes the GPG-Agent for the session key decryption, there is no need to ask the client for a protecting passphrase - GpgAgent takes care of this by requesting this from the user. diff --git a/doc/howto-create-a-server-cert.texi b/doc/howto-create-a-server-cert.texi index 30e28bdd0..de5a9470f 100644 --- a/doc/howto-create-a-server-cert.texi +++ b/doc/howto-create-a-server-cert.texi @@ -80,7 +80,7 @@ would anyway ignore such a request. Thus just hit enter. If you want to create a client certificate for email encryption, this would be the place to enter your mail address -(e.g. @email{joe@@example.org}). You may enter as many addresses as you like, +(e.g., @email{joe@@example.org}). You may enter as many addresses as you like, however the CA may not accept them all or reject the entire request. @cartouche diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 6f56585e6..2c5444e40 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -161,7 +161,7 @@ helpers to debug problems. @item --debug @var{flags} @opindex debug Set debug flags. All flags are or-ed and @var{flags} may be given -in C syntax (e.g. 0x0042) or as a comma separated list of flag names. +in C syntax (e.g., 0x0042) or as a comma separated list of flag names. To get a list of all supported flags the single word "help" can be used. This option is only useful for debugging and the behavior may change at any time without notice. @@ -238,7 +238,7 @@ this option only if you know what you are doing. Use @var{library} to access the smartcard reader. The current default on Unix is @file{libpcsclite.so} and on Windows @file{winscard.dll}. Instead of using this option you might also want to install a symbolic -link to the default file name (e.g. from @file{libpcsclite.so.1}). +link to the default file name (e.g., from @file{libpcsclite.so.1}). A Unicode file name may not be used on Windows. @item --ctapi-driver @var{library} @@ -505,7 +505,7 @@ will return an error when a card change has been detected and the use of this function is therefore required. Background: We want to keep the client clear of handling card changes -between operations; i.e. the client can assume that all operations are +between operations; i.e., the client can assume that all operations are done on the same card unless he call this function. @example @@ -719,7 +719,7 @@ reset the card. This is used by gpg-agent to reuse a primary pipe connection and may be used by clients to backup from a conflict in the serial -command; i.e. to select another application. +command; i.e., to select another application. diff --git a/doc/specify-user-id.texi b/doc/specify-user-id.texi index 64e354bdf..1dc91b6d8 100644 --- a/doc/specify-user-id.texi +++ b/doc/specify-user-id.texi @@ -39,7 +39,7 @@ using the option @option{--with-colons}. @item By fingerprint. This format is deduced from the length of the string and its content or the @code{0x} prefix. Note, that only the 20 byte version fingerprint -is available with @command{gpgsm} (i.e. the SHA-1 hash of the +is available with @command{gpgsm} (i.e., the SHA-1 hash of the certificate). When using @command{gpg} an exclamation mark (!) may be appended to @@ -88,7 +88,7 @@ with left and right angles. @item By partial match on an email address. This is indicated by prefixing the search string with an @code{@@}. This uses a substring search but considers only the mail address -(i.e. inside the angle brackets). +(i.e., inside the angle brackets). @cartouche @example diff --git a/doc/tools.texi b/doc/tools.texi index eefa4f9d6..9cac81e4c 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -124,7 +124,7 @@ $ watchgnupg --time-only @end example This waits for connections on the local socket -(e.g. @file{/var/run/user/1234/gnupg/S.log}) and shows all log +(e.g., @file{/var/run/user/1234/gnupg/S.log}) and shows all log entries. To make this work the option @option{log-file} needs to be used with all modules which logs are to be shown. The suggested entry for the configuration files is: @@ -1247,7 +1247,7 @@ Alternatively an arbitrary string may be used to identify a passphrase; it is suggested that such a string is prefixed with the name of the application (e.g @code{foo:12346}). Scripts should always use the option @option{--with-colons}, which provides the keygrip in a -"grp" line (cf. @file{doc/DETAILS})/ +"grp" line (cf.@: @file{doc/DETAILS})/ @noindent One of the following command options must be given: @@ -1728,7 +1728,7 @@ The return value of this command is @table @code @item 0 -The certificate under question is valid; i.e. there is a valid CRL +The certificate under question is valid; i.e., there is a valid CRL available and it is not listed there or the OCSP request returned that that certificate is valid. @@ -2051,9 +2051,9 @@ This option is deprecated in favor of option @option{--directory}. @item --no-compress @opindex no-compress -This option tells gpg to disable compression (i.e. using option -z0). +This option tells gpg to disable compression (i.e., using option -z0). It is useful for archiving only large files which are are already -compressed (e.g. a set of videos). +compressed (e.g., a set of videos). @item --gpg @var{gpgcmd} @opindex gpg diff --git a/doc/wks.texi b/doc/wks.texi index 26d8b96f6..1959151a1 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -212,7 +212,7 @@ The default is @file{openpgpkey}. @opindex blacklist This option is used to exclude certain mail addresses from a mirror operation. The format of @var{file} is one mail address (just the -addrspec, e.g. "postel@@isi.edu") per line. Empty lines and lines +addrspec, e.g., "postel@@isi.edu") per line. Empty lines and lines starting with a '#' are ignored. @item --add-revocs From c1f78634ec3927ddcfdc4687bc6e408c658a0ece Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 5 Oct 2023 10:02:59 +0200 Subject: [PATCH 209/869] sm: Improve the octet string cramming for pkcs#12 * sm/minip12.c (need_octet_string_cramming): New. (tlv_expect_object, tlv_expect_octet_string): Run the test before cramming. * sm/minip12.c (ENABLE_DER_STRUCT_DUMPING): New but undefined macro for debug purposes. (bag_decrypted_data_p, bag_data_p): Use macro to allow dumping. -- This bug was exhibited by importing a gpgsm exported EC certificate. We use an extra test instead of retrying to allow retruning an error from malloc failure. And well, for easier reading of the code. GnuPG-bug-id: 6536 --- sm/minip12.c | 79 ++++++++++++++---- tests/cms/Makefile.am | 1 + tests/cms/samplekeys/Description-p12 | 10 +++ .../edward.tester@demo.gnupg.com.p12 | Bin 0 -> 1561 bytes 4 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 tests/cms/samplekeys/edward.tester@demo.gnupg.com.p12 diff --git a/sm/minip12.c b/sm/minip12.c index 265243f3e..ed80534b6 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -50,6 +50,8 @@ #define DIM(v) (sizeof(v)/sizeof((v)[0])) #endif +/* Enable the next macro to dump stuff for debugging. */ +#undef ENABLE_DER_STRUCT_DUMPING static unsigned char const oid_data[9] = { @@ -111,6 +113,8 @@ static unsigned char const data_mactemplate[51] = { #define DATA_MACTEMPLATE_MAC_OFF 17 #define DATA_MACTEMPLATE_SALT_OFF 39 +/* Note that the BMP String in this template reads: + * "GnuPG exported certificate ffffffff" */ static unsigned char const data_attrtemplate[106] = { 0x31, 0x7c, 0x30, 0x55, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, 0x31, @@ -210,6 +214,8 @@ static int opt_verbose; static unsigned char *cram_octet_string (const unsigned char *input, size_t length, size_t *r_newlength); +static int need_octet_string_cramming (const unsigned char *input, + size_t length); @@ -560,7 +566,7 @@ tlv_expect_sequence (struct tlv_ctx_s *tlv) return _tlv_push (tlv); } -/* Variant of tlv_expect_sequence to be used for the ouyter sequence +/* Variant of tlv_expect_sequence to be used for the outer sequence * of an object which might have padding after the ASN.1 data. */ static gpg_error_t tlv_expect_top_sequence (struct tlv_ctx_s *tlv) @@ -618,7 +624,8 @@ tlv_expect_object (struct tlv_ctx_s *tlv, int class, int tag, if (!tlv->ti.length) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - if (class == CLASS_CONTEXT && tag == 0 && tlv->ti.is_constructed) + if (class == CLASS_CONTEXT && tag == 0 && tlv->ti.is_constructed + && need_octet_string_cramming (p, tlv->ti.length)) { char *newbuffer; @@ -665,7 +672,8 @@ tlv_expect_octet_string (struct tlv_ctx_s *tlv, int encapsulates, if (!(n=tlv->ti.length)) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - if (encapsulates && tlv->ti.is_constructed) + if (encapsulates && tlv->ti.is_constructed + && need_octet_string_cramming (p, n)) { char *newbuffer; @@ -859,6 +867,39 @@ cram_octet_string (const unsigned char *input, size_t length, } +/* Return true if (INPUT,LENGTH) is a structure which should be passed + * to cram_octet_string. This is basically the same loop as in + * cram_octet_string but without any actual copying. */ +static int +need_octet_string_cramming (const unsigned char *input, size_t length) +{ + const unsigned char *s = input; + size_t n = length; + struct tag_info ti; + + if (!length) + return 0; + + while (n) + { + if (parse_tag (&s, &n, &ti)) + return 0; + if (ti.class == CLASS_UNIVERSAL && ti.tag == TAG_OCTET_STRING + && !ti.ndef && !ti.is_constructed) + { + s += ti.length; + n -= ti.length; + } + else if (ti.class == CLASS_UNIVERSAL && !ti.tag && !ti.is_constructed) + break; /* Ready */ + else + return 0; + } + + return 1; +} + + static int string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw, int req_keylen, unsigned char *keybuf) @@ -1173,13 +1214,15 @@ bag_decrypted_data_p (const void *plaintext, size_t length) const unsigned char *p = plaintext; size_t n = length; - /* { */ - /* # warning debug code is enabled */ - /* FILE *fp = fopen ("tmp-minip12-plain-data.der", "wb"); */ - /* if (!fp || fwrite (p, n, 1, fp) != 1) */ - /* exit (2); */ - /* fclose (fp); */ - /* } */ +#ifdef ENABLE_DER_STRUCT_DUMPING + { + # warning debug code is enabled + FILE *fp = fopen ("tmp-minip12-plain-data.der", "wb"); + if (!fp || fwrite (p, n, 1, fp) != 1) + exit (2); + fclose (fp); + } +#endif /*ENABLE_DER_STRUCT_DUMPING*/ if (parse_tag (&p, &n, &ti)) return 0; @@ -1696,13 +1739,15 @@ bag_data_p (const void *plaintext, size_t length) const unsigned char *p = plaintext; size_t n = length; -/* { */ -/* # warning debug code is enabled */ -/* FILE *fp = fopen ("tmp-minip12-plain-key.der", "wb"); */ -/* if (!fp || fwrite (p, n, 1, fp) != 1) */ -/* exit (2); */ -/* fclose (fp); */ -/* } */ +#ifdef ENABLE_DER_STRUCT_DUMPING + { +# warning debug code is enabled + FILE *fp = fopen ("tmp-minip12-plain-key.der", "wb"); + if (!fp || fwrite (p, n, 1, fp) != 1) + exit (2); + fclose (fp); + } +#endif /*ENABLE_DER_STRUCT_DUMPING*/ if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) return 0; diff --git a/tests/cms/Makefile.am b/tests/cms/Makefile.am index 7efdf37b1..d5d753902 100644 --- a/tests/cms/Makefile.am +++ b/tests/cms/Makefile.am @@ -99,6 +99,7 @@ EXTRA_DIST = $(XTESTS) $(KEYS) $(CERTS) $(TEST_FILES) \ samplekeys/opensc-test.p12 \ samplekeys/t5793-openssl.pfx \ samplekeys/t5793-test.pfx \ + samplekeys/edward.tester@demo.gnupg.com.p12 \ samplemsgs/pwri-sample.cbc.p7m \ samplemsgs/pwri-sample.cbc-2.p7m \ samplemsgs/pwri-sample.gcm.p7m \ diff --git a/tests/cms/samplekeys/Description-p12 b/tests/cms/samplekeys/Description-p12 index f882de9ea..6fbbd82cf 100644 --- a/tests/cms/samplekeys/Description-p12 +++ b/tests/cms/samplekeys/Description-p12 @@ -1,4 +1,6 @@ # Description-p12 - Machine readable description of our P12 test vectors +# The Cert line gives the SHA1 fingerprint of the certificate +# The Key line gives a hash of the key parameters as returned by minip12.c Name: ov-user.p12 Desc: Private test key from www.openvalidation.org @@ -30,3 +32,11 @@ Desc: QuaVadis format of t5793-openssl Pass: test Cert: 80348a438e4b803b99e708da0b7fdd0659dedd15 Key: c271e44ab4fb19ca1aae71102ea4d7292ccc981d + +Name: edward.tester@demo.gnupg.com.p12 +Desc: GnuPG exported Brainpool certificate +Pass: abc,123456 +Cert: ff810b9281a43c394aa138e9c7fd4c0193216fa6 +Key: 94c6d0b067370a8f2a09ae43cfe8d700bbd61e75 + +# eof # diff --git a/tests/cms/samplekeys/edward.tester@demo.gnupg.com.p12 b/tests/cms/samplekeys/edward.tester@demo.gnupg.com.p12 new file mode 100644 index 0000000000000000000000000000000000000000..a6f983780f6ca06c9be9cef235d46fa945430bfd GIT binary patch literal 1561 zcmY+Ec{G%39LL|6*VrOqG8Yv}$|&#ThRHfeldWm&-Lfy)W;8~cO3Vz}kfKZ3#uCO7 zQ{#>pTlN~n4TVN&Q#WM`t?szz-rK!@{Lc4zKHqbG=RD6JADDqaih<%VLt+det($~T zT9N}LK^8+o05K%GMYtViK;Azp1d9O?M94u51Vpj-M+3s@2${b(tN{_QJS2svr)|=m zXowOMlLF!y5bC#sLZVkTReZX8&qUSxi_My6vA!!roY*}T@#+H3*@VoaW6FKzE;|Mb zmo(&6X+6vM0r;)S$fvjj^wb(2LCTYBKSJt@+#Xy;ZoEI=o6NO(MMzPCVx@D}FJ@rM z5>Q=68)e`?qF*DU17o`vpeP&`eE9HqDh1FIO(ArY-O{uO-_Stt5 zeM86wllQr?PDY8zmhb-1u?VJ83*8h=cQX`!^^Kj>WqW;I;JlT-_7n5-sdsaFk~E=V zUcpO?<(4luR5$uTIO&x3oI%B?tgrp0j^FD)=8bQO{L(thQ`d??3blGC`;n^JTPHd~ zj13RZI@*~>jw__y)poHGs(0P-9avYJk63>}{KUj#LiC6~ABm?z^^r6!Gn7JP&7&MH zdF>RuWy*@$@BTJkjwbS#XMwxthbct1C<_Z<1U5NHn zGs&n{R4v95E{CL@h%4pw+YBQeSh_A=?Al(*^aq-)d~aWIS{_ z^qRpX*6+Wp{v2%+J=dJHRNQp zPEzm5ZP=-saMtsiC3$)9{ixJzLw#dJj{5WxBww8w!sxD?iQX}8`nDo9dpYO;N=?b2 zxG~!PgA0B_*U6nm3!S8#PQ&|W zhlK10y=}B5;lSJiey5Mjym~G{HV&FUD2~qwD-r;RgOLkSc=38- zcl06`AD8TB8|R_WuQG@jXJ#KysJ(QLb!#%qM#pVo<;=CE%1Z{6snZ~zTxD9`U5aQ6-u$8242812P=A@KBo7rh z%gzTXmI=_Uud#quW1~xiq_@Lu$7-ENv*mavUd%O!jV6Mg)F9(7X6iJiThj*K^wfXa zgh|zFj;qUOa_DoU`TWTq!OQdEtSZ8EOKP%oZEm9Glcc5(6dymewU!Nx2IsvhO<_CQ zv6$1a>%UKwR>t5r+5-Ck5)cg#M5zG;0w;h-fDBLos^}abBL1RWy@dclqVWfO|7tV< zEMNfa0x*D~i2DMD@a7+Dk(l+6@(Nw{3cc7AYgb_Wrt6ynn661KfibWqERB#r%ZrPt oN&t{@c(F$V$7b0aj9<|~l_+pDVo;5c)T>djsne-Jb@dPb1p3sgLjV8( literal 0 HcmV?d00001 From b4449ffabc10faa5f532be22738f2ef61828c33b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 5 Oct 2023 11:07:16 +0200 Subject: [PATCH 210/869] gpg-card: Give a hint on how to get help for the "yubikey" command. * tools/card-yubikey.c (yubikey_commands): Print a hint. --- tools/card-yubikey.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/card-yubikey.c b/tools/card-yubikey.c index ece7edc48..63d49c762 100644 --- a/tools/card-yubikey.c +++ b/tools/card-yubikey.c @@ -332,6 +332,8 @@ yubikey_commands (card_info_t info, estream_t fp, int argc, const char *argv[]) cmd = ykDISABLE; else { + log_info ("Please use \"%s\" to list the available sub-commands\n", + "help yubikey"); err = gpg_error (GPG_ERR_UNKNOWN_COMMAND); goto leave; } From 19caa5c267a53d248efea5a09b0bd10962fd8003 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 26 Sep 2023 13:42:37 +0900 Subject: [PATCH 211/869] agent: Initialize FP for the case of error return. * agent/findkey.c (agent_write_private_key): Initialize FP. -- Cherry-picked from master commit of: a8618fdccdab228a8bbe3efeb87223a68fa57219 Signed-off-by: NIIBE Yutaka --- agent/findkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/findkey.c b/agent/findkey.c index eb2b7a17a..a5f022574 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -118,7 +118,7 @@ agent_write_private_key (const unsigned char *grip, gpg_error_t err; char *fname = NULL; char *tmpfname = NULL; - estream_t fp; + estream_t fp = NULL; int newkey; nvc_t pk = NULL; gcry_sexp_t key = NULL; From 9909f622f69e2b5775099931406dce2d35011281 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 28 Sep 2023 11:59:14 +0900 Subject: [PATCH 212/869] agent: fix tpm2d keytotpm handling * agent/divert-tpm2.c (agent_write_tpm2_shadow_key): Call agent_delete_key before agent_write_private_key. Recover from an error. -- Cherry-picked from master commit of: eda3997b439e415f1bebaa3be20c8bdb43d3a1d0 Fixes-commit: a1015bf2fc07dabb1200eab5fa41f13e7bf98202 Signed-off-by: James Bottomley --- agent/divert-tpm2.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index b2f884f93..e7c6a8aae 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -26,9 +26,10 @@ divert_tpm2_pksign (ctrl_t ctrl, static gpg_error_t agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, - unsigned char *shadow_info) + unsigned char *shadow_info, + gcry_sexp_t s_key) { - gpg_error_t err; + gpg_error_t err, err1; unsigned char *shdkey; unsigned char *pkbuf; size_t len; @@ -44,7 +45,14 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, xfree (pkbuf); if (err) { - log_error ("shadowing the key failed: %s\n", gpg_strerror (err)); + log_error ("shadowing the tpm key failed: %s\n", gpg_strerror (err)); + return err; + } + + err = agent_delete_key (ctrl, NULL, grip, 1, 0); + if (err) + { + log_error ("failed to delete unshadowed key: %s\n", gpg_strerror (err)); return err; } @@ -53,7 +61,22 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, NULL, NULL, NULL, 0); xfree (shdkey); if (err) - log_error ("error writing key: %s\n", gpg_strerror (err)); + { + log_error ("error writing tpm key: %s\n", gpg_strerror (err)); + + len = gcry_sexp_sprint(s_key, GCRYSEXP_FMT_CANON, NULL, 0); + pkbuf = xtrymalloc(len); + if (!pkbuf) + return GPG_ERR_ENOMEM; + + gcry_sexp_sprint(s_key, GCRYSEXP_FMT_CANON, pkbuf, len); + err1 = agent_write_private_key (grip, pkbuf, len, 1 /*force*/, + NULL, NULL, NULL, 0); + xfree(pkbuf); + if (err1) + log_error ("error trying to restore private key: %s\n", + gpg_strerror (err1)); + } return err; } @@ -68,7 +91,7 @@ divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip, ret = agent_tpm2d_writekey(ctrl, &shadow_info, s_skey); if (!ret) { - ret = agent_write_tpm2_shadow_key (ctrl, grip, shadow_info); + ret = agent_write_tpm2_shadow_key (ctrl, grip, shadow_info, s_skey); xfree (shadow_info); } return ret; From 8d0819346db8943b519ea7685569382c56776d15 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 28 Sep 2023 13:26:52 +0900 Subject: [PATCH 213/869] tpm2d: Check SWTPM environment variable for swtpm support. * tpm2d/intel-tss.h (TSS_Create): Check SWTPM. -- Cherry-picked from master commit of: 1da40db03eba4aa056f7cdf8ef90292272a4147d Signed-off-by: James Bottomley --- tpm2d/intel-tss.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tpm2d/intel-tss.h b/tpm2d/intel-tss.h index 615f81e2f..53da5cee2 100644 --- a/tpm2d/intel-tss.h +++ b/tpm2d/intel-tss.h @@ -285,9 +285,15 @@ TSS_Create(TSS_CONTEXT **tssContext) */ if (intType) { - if (strcmp("socsim", intType) == 0) { - tctildr = "mssim"; - } + if (strcmp("socsim", intType) == 0) + { + char *swtpm = getenv("SWTPM"); + + if (!swtpm || strlen(swtpm) == 0) + tctildr = "mssim"; + else + tctildr = "swtpm"; + } else if (strcmp("dev", intType) == 0) { tctildr = "device"; From d17efdcd6f755f13c9ff9b7a3127c13496ab7055 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 3 Oct 2023 11:53:00 +0900 Subject: [PATCH 214/869] tests:tpm2dtests: Fix tests with TPM2D. * tests/tpm2dtests/Makefile.am (TESTS_ENVIRONMENT): Fix. * tests/tpm2dtests/all-tests.scm: Follow the change of gpgscm. * tests/tpm2dtests/run-tests.scm: Likewise. -- Cherry-picked from master commit of: 321f9c0a3f2873cb3007e2bc2a542bbd0b2cc974 GnuPG-bug-id: 6052 Signed-off-by: NIIBE Yutaka --- tests/tpm2dtests/Makefile.am | 4 ++-- tests/tpm2dtests/all-tests.scm | 21 ++++++++++++--------- tests/tpm2dtests/run-tests.scm | 2 ++ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/tests/tpm2dtests/Makefile.am b/tests/tpm2dtests/Makefile.am index 72ad11d9b..6048d201c 100644 --- a/tests/tpm2dtests/Makefile.am +++ b/tests/tpm2dtests/Makefile.am @@ -34,10 +34,10 @@ TESTS_ENVIRONMENT = LC_ALL=C \ PATH="../gpgscm:$(PATH)" \ abs_top_srcdir="$(abs_top_srcdir)" \ objdir="$(abs_top_builddir)" \ - TPMSERVER="$(TPMSERVER)" \ + TPMSERVER="$(TPMSERVER)" TSSSTARTUP="$(TSSSTARTUP)" \ SWTPM="$(SWTPM)" \ SWTPM_IOCTL="$(SWTPM_IOCTL)" \ - GNUPG_BUILD_ROOT="$(abs_top_builddir)/tests" \ + GNUPG_BUILD_ROOT="$(abs_top_builddir)" \ GNUPG_IN_TEST_SUITE=fact \ GPGSCM_PATH="$(abs_top_srcdir)/tests/gpgscm" diff --git a/tests/tpm2dtests/all-tests.scm b/tests/tpm2dtests/all-tests.scm index bf7a981ca..8934f01f2 100644 --- a/tests/tpm2dtests/all-tests.scm +++ b/tests/tpm2dtests/all-tests.scm @@ -30,8 +30,9 @@ (make-environment-cache (test::scm #f - (path-join "tests" "openpgp" "setup.scm") - (in-srcdir "tests" "openpgp" "setup.scm")))) + #f + (path-join "tests" "tpm2dtests" "setup.scm") + (in-srcdir "tests" "tpm2dtests" "setup.scm")))) (define (qualify path variant) (string-append "<" variant ">" path)) @@ -40,8 +41,9 @@ (make-environment-cache (test::scm #f - (qualify (path-join "tests" "openpgp" "setup.scm") variant) - (in-srcdir "tests" "openpgp" "setup.scm") + variant + (path-join "tests" "tpm2dtests" "setup.scm") + (in-srcdir "tests" "tpm2dtests" "setup.scm") (string-append "--" variant)))) (define setup-use-keyring (setup* "use-keyring")) @@ -55,7 +57,8 @@ (define tests (map (lambda (name) (test::scm setup - (qualify (path-join "tests" "tpm2dtests" name) "standard") + "standards" + (path-join "tests" "tpm2dtests" name) (in-srcdir "tests" "tpm2dtests" name))) all-tests)) (when *run-all-tests* @@ -65,15 +68,15 @@ ;; The second pass uses the keyboxd (map (lambda (name) (test::scm setup-use-keyboxd - (qualify (path-join "tests" "tpm2dtests" name) - "keyboxd") + "keyboxd" + (path-join "tests" "tpm2dtests" name) (in-srcdir "tests" "tpm2dtests" name) "--use-keyboxd")) all-tests) ;; The third pass uses the legact pubring.gpg (map (lambda (name) (test::scm setup-use-keyring - (qualify (path-join "tests" "tpm2dtests" name) - "keyring") + "keyring" + (path-join "tests" "tpm2dtests" name) (in-srcdir "tests" "tpm2dtests" name) "--use-keyring")) all-tests) ))) diff --git a/tests/tpm2dtests/run-tests.scm b/tests/tpm2dtests/run-tests.scm index fdf1859a8..638d3a8a1 100644 --- a/tests/tpm2dtests/run-tests.scm +++ b/tests/tpm2dtests/run-tests.scm @@ -29,6 +29,7 @@ (define setup (make-environment-cache (test::scm #f + #f (path-join "tests" "tpm2dtests" "setup.scm") (in-srcdir "tests" "tpm2dtests" "setup.scm")))) @@ -38,6 +39,7 @@ (load-tests "tests" "tpm2dtests") (map (lambda (name) (test::scm setup + #f (path-join "tests" "tpm2dtests" name) (in-srcdir "tests" "tpm2dtests" name) "--use-keyring")) tests))) From e783866f414097e38fb1cf0061005989d11c468b Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 3 Oct 2023 16:51:46 +0900 Subject: [PATCH 215/869] tools: Add TPM2DAEMON_SOCK_NAME for --remove-socketdir. * tools/gpgconf.c (main): Care about tpm2d. Emit correct ERR. -- Cherry-picked from master commit of: 25c84ffd1078e6619761aa731a82dbaf4175c02e Signed-off-by: NIIBE Yutaka --- tools/gpgconf.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 6dcdc9f3c..f34248c40 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -963,7 +963,8 @@ main (int argc, char **argv) GPG_AGENT_SSH_SOCK_NAME, SCDAEMON_SOCK_NAME, KEYBOXD_SOCK_NAME, - DIRMNGR_SOCK_NAME + DIRMNGR_SOCK_NAME, + TPM2DAEMON_SOCK_NAME }; int i; char *p; @@ -976,8 +977,11 @@ main (int argc, char **argv) xfree (p); } if (gnupg_rmdir (socketdir)) - gc_error (1, 0, "error removing '%s': %s", - socketdir, gpg_strerror (err)); + { + err = gpg_error_from_syserror (); + gc_error (1, 0, "error removing '%s': %s", + socketdir, gpg_strerror (err)); + } } else if (gpg_err_code (err) == GPG_ERR_ENOENT) gc_error (0, 0, "warning: removing '%s' failed: %s", From 0494ec8f4d6399336f3202a23144f4afe734aede Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 3 Oct 2023 16:55:02 +0900 Subject: [PATCH 216/869] build: Simplify detecting a TPM emulator. * configure.ac (TPMSERVER): Don't supply hard-coded path. (SWTPM, SWTPM_IOCTL, TSSSTARTUP): Likewise. -- Cherry-picked from master commit of: f2ca727978da5b1ed84f97bf37d604e8a4e60091 Having hard-coded path has bad side effect; It may not be detected even if it's available with PATH. Signed-off-by: NIIBE Yutaka --- configure.ac | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 6f544bf98..6536810f1 100644 --- a/configure.ac +++ b/configure.ac @@ -1613,10 +1613,10 @@ if test "$build_tpm2d" = "yes"; then if test "$have_libtss" != no; then AC_DEFINE(HAVE_LIBTSS, 1, [Defined if we have TPM2 support library]) # look for a TPM emulator for testing - AC_PATH_PROG(TPMSERVER, tpm_server,,/bin:/usr/bin:/usr/lib/ibmtss:/usr/libexec/ibmtss) - AC_PATH_PROG(SWTPM, swtpm,,/bin:/usr/bin:/usr/lib/ibmtss:/usr/libexec/ibmtss) - AC_PATH_PROG(SWTPM_IOCTL, swtpm_ioctl,,/bin:/usr/bin:/usr/lib/ibmtss:/usr/libexec/ibmtss) - AC_PATH_PROG(TSSSTARTUP, tssstartup,,/bin:/usr/bin:/usr/lib/ibmtss:/usr/libexec/ibmtss) + AC_PATH_PROG(TPMSERVER, tpm_server) + AC_PATH_PROG(SWTPM, swtpm) + AC_PATH_PROG(SWTPM_IOCTL, swtpm_ioctl) + AC_PATH_PROG(TSSSTARTUP, tssstartup) fi fi if test "$have_libtss" = no; then From 0e200f2187e005d8c52d8efb5ef89e4709eabcc1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 4 Oct 2023 18:30:33 +0900 Subject: [PATCH 217/869] tests:tpm2dtests: Fix tests with SWTPM. * configure.ac (TEST_LIBTSS): Fix the condition with SWTPM. * tests/tpm2dtests/start_sw_tpm.sh: Use --daemon and --pid to run SWTPM. -- Cherry-picked from master commit of: 98dd6f7af6aa3dcce19f20c22e3f825676e6b184 GnuPG-bug-id: 6052 Signed-off-by: NIIBE Yutaka --- configure.ac | 2 +- tests/tpm2dtests/start_sw_tpm.sh | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 6536810f1..72c99b1be 100644 --- a/configure.ac +++ b/configure.ac @@ -1625,7 +1625,7 @@ fi AC_SUBST(LIBTSS_LIBS) AC_SUBST(LIBTSS_CFLAGS) AM_CONDITIONAL(HAVE_LIBTSS, test "$have_libtss" != no) -AM_CONDITIONAL(TEST_LIBTSS, test -n "$TPMSERVER" || test -n "$SWTPM" && test -n "$TSSSTARTUP") +AM_CONDITIONAL(TEST_LIBTSS, test -n "$TPMSERVER" -o -n "$SWTPM" -a -n "$TSSSTARTUP" -a -n "$SWTPM_IOCTL") AC_SUBST(HAVE_LIBTSS) # diff --git a/tests/tpm2dtests/start_sw_tpm.sh b/tests/tpm2dtests/start_sw_tpm.sh index 36e1a806e..fc86801e2 100755 --- a/tests/tpm2dtests/start_sw_tpm.sh +++ b/tests/tpm2dtests/start_sw_tpm.sh @@ -3,12 +3,15 @@ # remove any prior TPM contents rm -f NVChip h*.bin *.permall if [ -x "${SWTPM}" ]; then - ${SWTPM} socket --tpm2 --server type=tcp,port=2321 \ - --ctrl type=tcp,port=2322 --tpmstate dir=`pwd` & + ${SWTPM} socket --tpm2 --daemon \ + --pid file=swtpm.pid \ + --server type=tcp,port=2321 \ + --ctrl type=tcp,port=2322 --tpmstate dir=`pwd` + pid=$(cat swtpm.pid) else ${TPMSERVER} > /dev/null 2>&1 & + pid=$! fi -pid=$! ## # This powers on the tpm and starts it # then we derive the RSA version of the storage seed and From 9353dc811a04cf47f2445bb1e1f0401ea5f3d044 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 5 Oct 2023 10:21:35 +0900 Subject: [PATCH 218/869] tests:tpm2dtests: Modify tests with SWTPM and relax the condition. * configure.ac (SWTPM_IOCTL): Remove. (TEST_LIBTSS): Fix the condition. * tests/tpm2dtests/Makefile.am (TESTS_ENVIRONMENT): Remove SWTPM_IOCTL. * tests/tpm2dtests/start_sw_tpm.sh: Add --flags to invoke SWTPM, not requiring SWTPM_IOCTL and TSSSTARTUP any more. -- Cherry-picked from master commit of: 227b3b14f4be2f33ed721818c2186e7fca4cebdf GnuPG-bug-id: 6052 Signed-off-by: NIIBE Yutaka --- configure.ac | 5 ++- tests/tpm2dtests/Makefile.am | 1 - tests/tpm2dtests/start_sw_tpm.sh | 55 ++++++++++++++++---------------- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/configure.ac b/configure.ac index 72c99b1be..fc0590c14 100644 --- a/configure.ac +++ b/configure.ac @@ -1614,9 +1614,8 @@ if test "$build_tpm2d" = "yes"; then AC_DEFINE(HAVE_LIBTSS, 1, [Defined if we have TPM2 support library]) # look for a TPM emulator for testing AC_PATH_PROG(TPMSERVER, tpm_server) - AC_PATH_PROG(SWTPM, swtpm) - AC_PATH_PROG(SWTPM_IOCTL, swtpm_ioctl) AC_PATH_PROG(TSSSTARTUP, tssstartup) + AC_PATH_PROG(SWTPM, swtpm) fi fi if test "$have_libtss" = no; then @@ -1625,7 +1624,7 @@ fi AC_SUBST(LIBTSS_LIBS) AC_SUBST(LIBTSS_CFLAGS) AM_CONDITIONAL(HAVE_LIBTSS, test "$have_libtss" != no) -AM_CONDITIONAL(TEST_LIBTSS, test -n "$TPMSERVER" -o -n "$SWTPM" -a -n "$TSSSTARTUP" -a -n "$SWTPM_IOCTL") +AM_CONDITIONAL(TEST_LIBTSS, test -n "$SWTPM" -o -n "$TPMSERVER" -a -n "$TSSSTARTUP") AC_SUBST(HAVE_LIBTSS) # diff --git a/tests/tpm2dtests/Makefile.am b/tests/tpm2dtests/Makefile.am index 6048d201c..ceaf56420 100644 --- a/tests/tpm2dtests/Makefile.am +++ b/tests/tpm2dtests/Makefile.am @@ -36,7 +36,6 @@ TESTS_ENVIRONMENT = LC_ALL=C \ objdir="$(abs_top_builddir)" \ TPMSERVER="$(TPMSERVER)" TSSSTARTUP="$(TSSSTARTUP)" \ SWTPM="$(SWTPM)" \ - SWTPM_IOCTL="$(SWTPM_IOCTL)" \ GNUPG_BUILD_ROOT="$(abs_top_builddir)" \ GNUPG_IN_TEST_SUITE=fact \ GPGSCM_PATH="$(abs_top_srcdir)/tests/gpgscm" diff --git a/tests/tpm2dtests/start_sw_tpm.sh b/tests/tpm2dtests/start_sw_tpm.sh index fc86801e2..a44833e28 100755 --- a/tests/tpm2dtests/start_sw_tpm.sh +++ b/tests/tpm2dtests/start_sw_tpm.sh @@ -3,36 +3,35 @@ # remove any prior TPM contents rm -f NVChip h*.bin *.permall if [ -x "${SWTPM}" ]; then - ${SWTPM} socket --tpm2 --daemon \ - --pid file=swtpm.pid \ - --server type=tcp,port=2321 \ - --ctrl type=tcp,port=2322 --tpmstate dir=`pwd` - pid=$(cat swtpm.pid) + ${SWTPM} socket --tpm2 --daemon \ + --pid file=swtpm.pid \ + --server type=tcp,port=2321 \ + --ctrl type=tcp,port=2322 \ + --flags not-need-init,startup-clear \ + --tpmstate dir=`pwd` + cat swtpm.pid else ${TPMSERVER} > /dev/null 2>&1 & pid=$! -fi -## -# This powers on the tpm and starts it -# then we derive the RSA version of the storage seed and -# store it permanently at handle 81000001 and flush the transient -## -a=0; while [ $a -lt 10 ]; do - if [ -x "${SWTPM_IOCTL}" ]; then - ${SWTPM_IOCTL} --tcp 127.0.0.1:2322 -i > /dev/null 2>&1 - else - tsspowerup > /dev/null 2>&1 + ## + # This powers on the tpm and starts it + # then we derive the RSA version of the storage seed and + # store it permanently at handle 81000001 and flush the transient + ## + a=0 + while [ $a -lt 10 ]; do + tsspowerup > /dev/null 2>&1 + if [ $? -eq 0 ]; then + break; + fi + sleep 1 + a=$[$a+1] + done + if [ $a -eq 10 ]; then + echo "Waited 10s for tpm_server to come up; exiting" + exit 1 fi - if [ $? -eq 0 ]; then - break; - fi - sleep 1 - a=$[$a+1] -done -if [ $a -eq 10 ]; then - echo "Waited 10s for tpm_server to come up; exiting" - exit 1 -fi -tssstartup || exit 1 -echo -n $pid + ${TSSSTARTUP} || exit 1 + echo -n $pid +fi From 24b3a5a5794db4bb69b38a1df099d5e59cccf2b3 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 6 Oct 2023 10:57:12 +0200 Subject: [PATCH 219/869] sm: Support more HMAC algos in the pkcs#12 parser. * sm/minip12.c (oid_hmacWithSHA1): New. Also for the SHA-2 algos. (digest_algo_from_oid): New. (set_key_iv_pbes2): Add arg digest_algo. (crypt_block): Ditto. (decrypt_block): Ditto. (parse_bag_encrypted_data): Parse the optional prf part and get the hmac algorithm. (parse_shrouded_key_bag): Ditto. (p12_build): Pass SHA1 for digest_algo. * sm/t-minip12.c (run_one_test): Print failed values in verbose mode. * tests/cms/samplekeys/nistp256-openssl-self-signed.p12: New. * tests/cms/samplekeys/Description-p12: Add this one. * tests/cms/Makefile.am (EXTRA_DIST): Ditto. -- This supports the modern algorithms, i.e. using SHA256 for the KDF which is the default in openssl unless the -legacy option is used. GnuPG-bug-id: 6536 --- sm/minip12.c | 131 ++++++++++++++++-- sm/t-minip12.c | 12 +- tests/cms/Makefile.am | 1 + tests/cms/samplekeys/Description-p12 | 6 + .../nistp256-openssl-self-signed.p12 | Bin 0 -> 1232 bytes 5 files changed, 135 insertions(+), 15 deletions(-) create mode 100644 tests/cms/samplekeys/nistp256-openssl-self-signed.p12 diff --git a/sm/minip12.c b/sm/minip12.c index ed80534b6..e63d9a95d 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -83,6 +83,17 @@ static unsigned char const oid_aes128_CBC[9] = { static unsigned char const oid_aes256_CBC[9] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2A }; +static unsigned char const oid_hmacWithSHA1[8] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x07 }; +static unsigned char const oid_hmacWithSHA224[8] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x08 }; +static unsigned char const oid_hmacWithSHA256[8] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x09 }; +static unsigned char const oid_hmacWithSHA384[8] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0A }; +static unsigned char const oid_hmacWithSHA512[8] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x0B }; + static unsigned char const oid_rsaEncryption[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }; static unsigned char const oid_pcPublicKey[7] = { @@ -241,6 +252,32 @@ dump_tag_info (const char *text, struct tag_info *ti) } +static int +digest_algo_from_oid (unsigned char const *oid, size_t oidlen) +{ + int algo; + + if (oidlen == DIM(oid_hmacWithSHA1) && + !memcmp (oid, oid_hmacWithSHA1, oidlen)) + algo = GCRY_MD_SHA1; + else if (oidlen == DIM(oid_hmacWithSHA224) && + !memcmp (oid, oid_hmacWithSHA224, oidlen)) + algo = GCRY_MD_SHA224; + else if (oidlen == DIM(oid_hmacWithSHA256) && + !memcmp (oid, oid_hmacWithSHA256, oidlen)) + algo = GCRY_MD_SHA256; + else if (oidlen == DIM(oid_hmacWithSHA384) && + !memcmp (oid, oid_hmacWithSHA384, oidlen)) + algo = GCRY_MD_SHA384; + else if (oidlen == DIM(oid_hmacWithSHA512) && + !memcmp (oid, oid_hmacWithSHA512, oidlen)) + algo = GCRY_MD_SHA512; + else + algo = 0; + return algo; +} + + /* Wrapper around tlv_builder_add_ptr to add an OID. When we * eventually put the whole tlv_builder stuff into Libksba, we can add * such a function there. Right now we don't do this to avoid a @@ -1029,13 +1066,14 @@ set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter, static int set_key_iv_pbes2 (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter, - const void *iv, size_t ivlen, const char *pw, int algo) + const void *iv, size_t ivlen, const char *pw, + int cipher_algo, int digest_algo) { unsigned char *keybuf; size_t keylen; int rc; - keylen = gcry_cipher_get_algo_keylen (algo); + keylen = gcry_cipher_get_algo_keylen (cipher_algo); if (!keylen) return -1; keybuf = gcry_malloc_secure (keylen); @@ -1043,7 +1081,7 @@ set_key_iv_pbes2 (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter, return -1; rc = gcry_kdf_derive (pw, strlen (pw), - GCRY_KDF_PBKDF2, GCRY_MD_SHA1, + GCRY_KDF_PBKDF2, digest_algo, salt, saltlen, iter, keylen, keybuf); if (rc) { @@ -1074,7 +1112,7 @@ set_key_iv_pbes2 (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter, static void crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen, int iter, const void *iv, size_t ivlen, - const char *pw, int cipher_algo, int encrypt) + const char *pw, int cipher_algo, int digest_algo, int encrypt) { gcry_cipher_hd_t chd; int rc; @@ -1088,7 +1126,8 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen, } if ((cipher_algo == GCRY_CIPHER_AES128 || cipher_algo == GCRY_CIPHER_AES256) - ? set_key_iv_pbes2 (chd, salt, saltlen, iter, iv, ivlen, pw, cipher_algo) + ? set_key_iv_pbes2 (chd, salt, saltlen, iter, iv, ivlen, pw, + cipher_algo, digest_algo) : set_key_iv (chd, salt, saltlen, iter, pw, cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24)) { @@ -1125,7 +1164,7 @@ static void decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, char *salt, size_t saltlen, int iter, const void *iv, size_t ivlen, - const char *pw, int cipher_algo, + const char *pw, int cipher_algo, int digest_algo, int (*check_fnc) (const void *, size_t)) { static const char * const charsets[] = { @@ -1197,7 +1236,7 @@ decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, } memcpy (plaintext, ciphertext, length); crypt_block (plaintext, length, salt, saltlen, iter, iv, ivlen, - convertedpw? convertedpw:pw, cipher_algo, 0); + convertedpw? convertedpw:pw, cipher_algo, digest_algo, 0); if (check_fnc (plaintext, length)) break; /* Decryption succeeded. */ } @@ -1257,6 +1296,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) int renewed_tlv = 0; int loopcount; unsigned int startlevel; + int digest_algo = GCRY_MD_SHA1; where = "bag.encryptedData"; if (opt_verbose) @@ -1326,6 +1366,8 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) /*FIXME: This code is duplicated in parse_shrouded_key_bag. */ if (is_pbes2) { + size_t parmlen; /* Remaining length of the parameter sequence. */ + where = "pkcs5PBES2-params"; if (tlv_next (tlv)) goto bailout; @@ -1352,11 +1394,13 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; if (tlv_expect_sequence (tlv)) goto bailout; + parmlen = tlv->ti.length; if (tlv_next (tlv)) goto bailout; if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; + parmlen -= tlv->ti.length + tlv->ti.nhdr; if (datalen < 8 || datalen > sizeof salt) { log_info ("bad length of salt (%zu)\n", datalen); @@ -1370,6 +1414,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; if ((err = tlv_expect_integer (tlv, &intval))) goto bailout; + parmlen -= tlv->ti.length + tlv->ti.nhdr; if (!intval) /* Not a valid iteration count. */ { err = gpg_error (GPG_ERR_INV_VALUE); @@ -1377,8 +1422,34 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) } iter = intval; - /* Note: We don't support the optional parameters but assume - that the algorithmIdentifier follows. */ + if (parmlen > 2) /* There is the optional prf. */ + { + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_sequence (tlv)) + goto bailout; + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + digest_algo = digest_algo_from_oid (oid, oidlen); + if (!digest_algo) + { + gpgrt_log_printhex (oid, oidlen, "kdf digest algo:"); + err = gpg_error (GPG_ERR_DIGEST_ALGO); + goto bailout; + } + if (opt_verbose > 1) + log_debug ("kdf digest algo = %d\n", digest_algo); + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_null (tlv)) + tlv_set_pending (tlv); /* NULL tag missing - ignore this. */ + } + else + digest_algo = GCRY_MD_SHA1; + if (tlv_next (tlv)) goto bailout; if (tlv_expect_sequence (tlv)) @@ -1468,6 +1539,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) iv, is_pbes2?16:0, ctx->password, is_pbes2 ? (is_aes256?GCRY_CIPHER_AES256:GCRY_CIPHER_AES128) : is_3des ? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40, + digest_algo, bag_decrypted_data_p); /* We do not need the TLV anymore and allocated a new one. */ @@ -1778,6 +1850,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) unsigned char *plain = NULL; int is_pbes2 = 0; int is_aes256 = 0; + int digest_algo = GCRY_MD_SHA1; where = "shrouded_key_bag"; if (opt_verbose) @@ -1819,6 +1892,8 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) if (is_pbes2) { + size_t parmlen; /* Remaining length of the parameter sequence. */ + where = "shrouded_key_bag.pkcs5PBES2-params"; if (tlv_next (tlv)) goto bailout; @@ -1842,11 +1917,13 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; if (tlv_expect_sequence (tlv)) goto bailout; + parmlen = tlv->ti.length; if (tlv_next (tlv)) goto bailout; if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; + parmlen -= tlv->ti.length + tlv->ti.nhdr; if (datalen < 8 || datalen > sizeof salt) { log_info ("bad length of salt (%zu) for AES\n", datalen); @@ -1860,6 +1937,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; if ((err = tlv_expect_integer (tlv, &intval))) goto bailout; + parmlen -= tlv->ti.length + tlv->ti.nhdr; if (!intval) /* Not a valid iteration count. */ { err = gpg_error (GPG_ERR_INV_VALUE); @@ -1867,8 +1945,34 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) } iter = intval; - /* Note: We don't support the optional parameters but assume - that the algorithmIdentifier follows. */ + if (parmlen > 2) /* There is the optional prf. */ + { + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_sequence (tlv)) + goto bailout; + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_object_id (tlv, &oid, &oidlen)) + goto bailout; + digest_algo = digest_algo_from_oid (oid, oidlen); + if (!digest_algo) + { + gpgrt_log_printhex (oid, oidlen, "kdf digest algo:"); + err = gpg_error (GPG_ERR_DIGEST_ALGO); + goto bailout; + } + if (opt_verbose > 1) + log_debug ("kdf digest algo = %d\n", digest_algo); + + if (tlv_next (tlv)) + goto bailout; + if (tlv_expect_null (tlv)) + tlv_set_pending (tlv); /* NULL tag missing - ignore this. */ + } + else + digest_algo = GCRY_MD_SHA1; + if (tlv_next (tlv)) goto bailout; if (tlv_expect_sequence (tlv)) @@ -1954,6 +2058,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) iv, is_pbes2? 16:0, ctx->password, is_pbes2 ? (is_aes256?GCRY_CIPHER_AES256:GCRY_CIPHER_AES128) : GCRY_CIPHER_3DES, + digest_algo, bag_data_p); @@ -3468,7 +3573,7 @@ p12_build (gcry_mpi_t *kparms, const void *cert, size_t certlen, /* Encrypt it. */ gcry_randomize (salt, 8, GCRY_STRONG_RANDOM); crypt_block (buffer, buflen, salt, 8, 2048, NULL, 0, pw, - GCRY_CIPHER_RFC2268_40, 1); + GCRY_CIPHER_RFC2268_40, GCRY_MD_SHA1, 1); /* Encode the encrypted stuff into a bag. */ seqlist[seqlistidx].buffer = build_cert_bag (buffer, buflen, salt, &n); @@ -3500,7 +3605,7 @@ p12_build (gcry_mpi_t *kparms, const void *cert, size_t certlen, /* Encrypt it. */ gcry_randomize (salt, 8, GCRY_STRONG_RANDOM); crypt_block (buffer, buflen, salt, 8, 2048, NULL, 0, - pw, GCRY_CIPHER_3DES, 1); + pw, GCRY_CIPHER_3DES, GCRY_MD_SHA1, 1); /* Encode the encrypted stuff into a bag. */ if (cert && certlen) diff --git a/sm/t-minip12.c b/sm/t-minip12.c index de6b7e5cc..bf3177ea0 100644 --- a/sm/t-minip12.c +++ b/sm/t-minip12.c @@ -559,13 +559,21 @@ run_one_test (const char *name, const char *desc, const char *pass, else if (!certexpected && certstr) printresult ("FAIL: %s - no certs expected but got one\n", name); else if (certexpected && certstr && strcmp (certexpected, certstr)) - printresult ("FAIL: %s - certs not as expected\n", name); + { + printresult ("FAIL: %s - certs not as expected\n", name); + inf ("cert(exp)=%s", certexpected); + inf ("cert(got)=%s", certstr? certstr:"[null]"); + } else if (keyexpected && !resulthash) printresult ("FAIL: %s - expected key but got none\n", name); else if (!keyexpected && resulthash) printresult ("FAIL: %s - key not expected but got one\n", name); else if (keyexpected && resulthash && strcmp (keyexpected, resulthash)) - printresult ("FAIL: %s - keys not as expected\n", name); + { + printresult ("FAIL: %s - keys not as expected\n", name); + inf ("key(exp)=%s", keyexpected); + inf ("key(got)=%s", resulthash? resulthash:"[null]"); + } else { printresult ("PASS: %s\n", name); diff --git a/tests/cms/Makefile.am b/tests/cms/Makefile.am index d5d753902..b43fb1c91 100644 --- a/tests/cms/Makefile.am +++ b/tests/cms/Makefile.am @@ -100,6 +100,7 @@ EXTRA_DIST = $(XTESTS) $(KEYS) $(CERTS) $(TEST_FILES) \ samplekeys/t5793-openssl.pfx \ samplekeys/t5793-test.pfx \ samplekeys/edward.tester@demo.gnupg.com.p12 \ + samplekeys/nistp256-openssl-self-signed.p12 \ samplemsgs/pwri-sample.cbc.p7m \ samplemsgs/pwri-sample.cbc-2.p7m \ samplemsgs/pwri-sample.gcm.p7m \ diff --git a/tests/cms/samplekeys/Description-p12 b/tests/cms/samplekeys/Description-p12 index 6fbbd82cf..a73998fac 100644 --- a/tests/cms/samplekeys/Description-p12 +++ b/tests/cms/samplekeys/Description-p12 @@ -39,4 +39,10 @@ Pass: abc,123456 Cert: ff810b9281a43c394aa138e9c7fd4c0193216fa6 Key: 94c6d0b067370a8f2a09ae43cfe8d700bbd61e75 +Name: nistp256-openssl-self-signed.p12 +Desc: OpenSSL generated self-signed nistp256 key+cert +Pass: abc +Cert: 5cea0c5bf09ccd92535267c662fc098f6c81c27e +Key: 3cb2fba95d1976df69eb7aa8c65ac5354e15af32 + # eof # diff --git a/tests/cms/samplekeys/nistp256-openssl-self-signed.p12 b/tests/cms/samplekeys/nistp256-openssl-self-signed.p12 new file mode 100644 index 0000000000000000000000000000000000000000..9eeebdae335a133abb7e66166d2691d8999196a2 GIT binary patch literal 1232 zcmXqLVmZUa$ZXKW(!|E8)#lOmotKfFaX}MHF-sFmK2SK@pov)tA;q?!iCGvZ#LvXY z0Hin&GK>b{a1JZ4ftP_Mg3Dtd!@^-9y3zLRjF>_uCJqJz9ySh$ZA_f33Inm3|n4o`T_UqNf1#0qZXKuW{x%%a{Ly!6Xsfp>R#c^6Wrkz~w=Mln|8FOOc z!MHPXA6EQ%zOja7(b5p9&&M~;)_FNu=uKwLnUuS$PaiuuyC8L~k;WAkz7HRcdd^wr zZ==6^%6U`&b!i_PMZ5wmxq{{VaMI007dx~!=2@m|w?Q3RudG?8&)$jEsGLO$@i#k?c@aoL` zM{_1_eHA>h&u~v$)SkI#EUOl-wm8jp+EnE00fVlYw?(+hZpZojKX=Rh{d$306K5yS z6)*U*VCfT?)#tkt#w>bG;>JBmEN%CqQU{Dp1%_Pu5}bL%MI-S;Ucbd&i%%$HDk zKUsa&_N>O2C+zOtiM&!RGylZ{-Tn(t&w3;Yo2EWbpC-2Yb4HbD+w_20hkEkgG>IMR zZT~H$@hI_h_q5G7zH?OB16WP*@9y)!4Y9d5edOk!eBWdxOR|gtE(= z@0mY$bZ(tQFuQ~VyZG%D{JwMc!J-G;Vk=l!8YkS8Ja|s4`A7_FW8twQJ0%3`Hg;Z9 zdHrh6J%&kqc@Kp=R+lkIDXkXKt}0m@)YSFOv*zowyMM(R1b(kyeab%chOy~GQ-y1( zd!t?l#RNy*XFsBOwmItQI-MfLbszTqR`_TX>QG}R@#na~k?9ZRyM=$trw8n1TX|&a zZox Date: Fri, 6 Oct 2023 12:04:00 +0200 Subject: [PATCH 220/869] scd:openpgp: Return better error codes for the Reset Code. * scd/app-openpgp.c (do_change_pin): Use GPG_ERR_BAD_RESET_CODE where appropriate. * common/util.h: Add error codes missing in gpgrt 1.46. * agent/call-pinentry.c (unlock_pinentry): Handle GPG_ERR_BAD_RESET_CODE. (agent_askpin): Ditlo. Also simply condition. (agent_get_passphrase): Ditto. * g10/call-agent.c (status_sc_op_failure): Handle GPG_ERR_BAD_RESET_CODE. * g10/card-util.c (write_sc_op_status): Ditto. * tools/card-call-scd.c (status_sc_op_failure): Ditto. --- agent/call-pinentry.c | 15 +++++++++------ common/util.h | 5 +++++ g10/call-agent.c | 1 + g10/card-util.c | 1 + scd/app-openpgp.c | 6 +++--- tools/card-call-scd.c | 1 + 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 656d5f623..d236e1107 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -174,6 +174,7 @@ unlock_pinentry (ctrl_t ctrl, gpg_error_t rc) case GPG_ERR_NO_PASSPHRASE: case GPG_ERR_BAD_PASSPHRASE: case GPG_ERR_BAD_PIN: + case GPG_ERR_BAD_RESET_CODE: break; case GPG_ERR_CORRUPTED_PROTECTION: @@ -1621,12 +1622,13 @@ agent_askpin (ctrl_t ctrl, && (pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE)) return unlock_pinentry (ctrl, rc); - if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE) + if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE + || gpg_err_code (rc) == GPG_ERR_BAD_PIN + || gpg_err_code (rc) == GPG_ERR_BAD_RESET_CODE) { if (pininfo->cb_errtext) errtext = pininfo->cb_errtext; - else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE - || gpg_err_code (rc) == GPG_ERR_BAD_PIN) + else errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase")); } else if (rc) @@ -1894,12 +1896,13 @@ agent_get_passphrase (ctrl_t ctrl, if (rc && (pininfo->status & PINENTRY_STATUS_PASSWORD_FROM_CACHE)) return unlock_pinentry (ctrl, rc); - if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE) + if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE + || gpg_err_code (rc) == GPG_ERR_BAD_PIN + || gpg_err_code (rc) == GPG_ERR_BAD_RESET_CODE) { if (pininfo->cb_errtext) errtext = pininfo->cb_errtext; - else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE - || gpg_err_code (rc) == GPG_ERR_BAD_PIN) + else errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase")); } else if (rc) diff --git a/common/util.h b/common/util.h index 83882caf2..875969187 100644 --- a/common/util.h +++ b/common/util.h @@ -39,6 +39,11 @@ * libgpg-error version. Define them here. * Example: (#if GPG_ERROR_VERSION_NUMBER < 0x011500 // 1.21) */ +#if GPG_ERROR_VERSION_NUMBER < 0x012f00 /* 1.47 */ +# define GPG_ERR_BAD_PUK 320 +# define GPG_ERR_NO_RESET_CODE 321 +# define GPG_ERR_BAD_RESET_CODE 322 +#endif #ifndef EXTERN_UNLESS_MAIN_MODULE # if !defined (INCLUDED_BY_MAIN_MODULE) diff --git a/g10/call-agent.c b/g10/call-agent.c index b0bccc0a5..eb9f8e29b 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -130,6 +130,7 @@ status_sc_op_failure (int rc) write_status_text (STATUS_SC_OP_FAILURE, "1"); break; case GPG_ERR_BAD_PIN: + case GPG_ERR_BAD_RESET_CODE: write_status_text (STATUS_SC_OP_FAILURE, "2"); break; default: diff --git a/g10/card-util.c b/g10/card-util.c index d680c4d0a..b83472285 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -62,6 +62,7 @@ write_sc_op_status (gpg_error_t err) write_status_text (STATUS_SC_OP_FAILURE, "1"); break; case GPG_ERR_BAD_PIN: + case GPG_ERR_BAD_RESET_CODE: write_status_text (STATUS_SC_OP_FAILURE, "2"); break; default: diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 66ec9f4a9..fd9ce554c 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -3453,7 +3453,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, if (!remaining) { log_error (_("Reset Code not or not anymore available\n")); - rc = gpg_error (GPG_ERR_BAD_PIN); + rc = gpg_error (GPG_ERR_NO_RESET_CODE); goto leave; } @@ -3470,7 +3470,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, { log_info (_("Reset Code is too short; minimum length is %d\n"), minlen); - rc = gpg_error (GPG_ERR_BAD_PIN); + rc = gpg_error (GPG_ERR_BAD_RESET_CODE); goto leave; } } @@ -3538,7 +3538,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, if (bufferlen != 0 && bufferlen < 8) { log_error (_("Reset Code is too short; minimum length is %d\n"), 8); - rc = gpg_error (GPG_ERR_BAD_PIN); + rc = gpg_error (GPG_ERR_BAD_RESET_CODE); } else { diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 27d8ad961..98d3ddeb7 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -235,6 +235,7 @@ status_sc_op_failure (gpg_error_t err) gnupg_status_printf (STATUS_SC_OP_FAILURE, "1"); break; case GPG_ERR_BAD_PIN: + case GPG_ERR_BAD_RESET_CODE: gnupg_status_printf (STATUS_SC_OP_FAILURE, "2"); break; default: From 5601f5db9862e23140bccc0e603e42164fe02296 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 10 Oct 2023 11:36:26 +0200 Subject: [PATCH 221/869] gpgsm: Improvements for NDEF in the pkcs#12 parser * sm/minip12.c (_tlv_push): Handle NDEF more correctly. (tlv_expect_octet_string): Do not bail out on NDEF. (dump_tag_info): Print some more infos. -- We do not have a complete test case for this. We need to further analyze T6752 to see what Mozilla is doing here. In any case with this patch we get a bit further and don't bail out at the ndef. GnuPG-bug-id: 6536, 6752 --- sm/minip12.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/sm/minip12.c b/sm/minip12.c index e63d9a95d..3705f3770 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -241,14 +241,21 @@ p12_set_verbosity (int verbose, int debug) static void -dump_tag_info (const char *text, struct tag_info *ti) +dump_tag_info (const char *text, struct tlv_ctx_s *tlv) { - if (opt_verbose > 1) - log_debug ("p12_parse(%s): ti.class=%d tag=%lu len=%zu nhdr=%zu %s%s\n", - text, - ti->class, ti->tag, ti->length, ti->nhdr, - ti->is_constructed?" cons":"", - ti->ndef?" ndef":""); + struct tag_info *ti; + + if (opt_verbose < 2) + return; + + ti = &tlv->ti; + log_debug ("p12_parse(%s): ti.class=%-2d tag=%-2lu len=%-4zu nhdr=%zu %s %s" + " (%u:%zu.%zu)\n", + text, + ti->class, ti->tag, ti->length, ti->nhdr, + ti->is_constructed?"cons":" ", + ti->ndef?"ndef":" ", + tlv->stacklen, tlv->bufsize, tlv->offset); } @@ -473,7 +480,13 @@ _tlv_push (struct tlv_ctx_s *tlv) tlv->stack[tlv->stacklen].in_ndef = tlv->in_ndef; tlv->stacklen++; tlv->buffer += tlv->offset; - tlv->bufsize = tlv->ti.length; + if (tlv->ti.ndef) + { + log_assert (tlv->bufsize >= tlv->offset); + tlv->bufsize -= tlv->offset; + } + else + tlv->bufsize = tlv->ti.length; tlv->offset = 0; tlv->in_ndef = tlv->ti.ndef; return 0; @@ -551,7 +564,7 @@ tlv_next (struct tlv_ctx_s *tlv) /* Set offset to the value of the TLV. */ tlv->offset += tlv->bufsize - tlv->offset - n; - dump_tag_info ("tlv_next", &tlv->ti); + dump_tag_info ("tlv_next", tlv); return 0; } @@ -706,7 +719,7 @@ tlv_expect_octet_string (struct tlv_ctx_s *tlv, int encapsulates, && (!tlv->ti.is_constructed || encapsulates))) return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); p = tlv->buffer + tlv->offset; - if (!(n=tlv->ti.length)) + if (!(n=tlv->ti.length) && !tlv->ti.ndef) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); if (encapsulates && tlv->ti.is_constructed From a17363e992943244987dbab754b112c77d938b5d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 14 Oct 2023 17:06:51 +0200 Subject: [PATCH 222/869] common: New function scan_secondsstr. * common/gettime.c (scan_secondsstr): New. * common/t-gettime.c (test_scan_secondsstr): (main): Call it. --- common/gettime.c | 23 ++++++++++++++++++++ common/gettime.h | 1 + common/stringhelp.c | 2 +- common/t-gettime.c | 52 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 2 deletions(-) diff --git a/common/gettime.c b/common/gettime.c index 2a9b71779..c3b0c6c6c 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -37,6 +37,7 @@ #ifdef HAVE_LANGINFO_H #include #endif +#include /* We use uint64_t. */ #include "util.h" #include "i18n.h" @@ -172,6 +173,28 @@ make_timestamp (void) } +/* Specialized version of atoi which returns an u32 instead of an int + * and caps the result at 2^32-2. Leading white space is skipped, + * scanning stops at at the first non-convertable byte. Note that we + * do not cap at 2^32-1 because that value is often used as error + * return. */ +u32 +scan_secondsstr (const char *string) +{ + uint64_t value = 0; + + while (*string == ' ' || *string == '\t') + string++; + for (; *string >= '0' && *string <= '9'; string++) + { + value *= 10; + value += atoi_1 (string); + if (value >= (u32)(-1)) + return (u32)(-1) - 1; + } + return (u32)value; +} + /**************** * Scan a date string and return a timestamp. diff --git a/common/gettime.h b/common/gettime.h index 4f7199f92..18f65ab1a 100644 --- a/common/gettime.h +++ b/common/gettime.h @@ -51,6 +51,7 @@ int gnupg_faked_time_p (void); u32 make_timestamp (void); char *elapsed_time_string (time_t since, time_t now); +u32 scan_secondsstr (const char *string); u32 scan_isodatestr (const char *string); int isotime_p (const char *string); int isotime_human_p (const char *string, int date_only); diff --git a/common/stringhelp.c b/common/stringhelp.c index 5407653de..9a2265258 100644 --- a/common/stringhelp.c +++ b/common/stringhelp.c @@ -725,7 +725,7 @@ compare_filenames (const char *a, const char *b) /* Convert a base-10 number in STRING into a 64 bit unsigned int * value. Leading white spaces are skipped but no error checking is - * done. Thus it is similar to atoi(). */ + * done. Thus it is similar to atoi(). See also scan_secondsstr. */ uint64_t string_to_u64 (const char *string) { diff --git a/common/t-gettime.c b/common/t-gettime.c index 13cb1a2f7..76c305204 100644 --- a/common/t-gettime.c +++ b/common/t-gettime.c @@ -43,6 +43,56 @@ static int errcount; #define INVALID ((time_t)(-1)) +static void +test_scan_secondsstr (void) +{ + struct { const char *string; u32 expected; } array [] = { + { "", 0 }, + { "0", 0 }, + { " 0", 0 }, + { " 0x", 0 }, + { " 1", 1 }, + { "-1", 0 }, + { " -1", 0 }, + { "2", 2 }, + { "11", 11 }, + { "011", 11 }, + { "3600 ", 3600 }, + { "65535", 65535 }, + { "65536", 65536 }, + { "65537", 65537 }, + { "4294967289", 4294967289 }, + { "4294967290", 4294967290 }, + { "4294967293", 4294967293 }, + { "4294967295", 4294967294 }, + { "4294967296", 4294967294 }, + { "4294967297", 4294967294 }, + { "4294967298", 4294967294 }, + { "4294967299", 4294967294 }, + { "4294967300", 4294967294 }, + { "5294967300", 4294967294 }, + { "9999999999", 4294967294 }, + { "99999999999",4294967294 }, + { NULL, 0 } + }; + int idx; + u32 val; + + for (idx=0; array[idx].string; idx++) + { + val = scan_secondsstr (array[idx].string); + if (val != array[idx].expected ) + { + fail (idx); + if (verbose) + fprintf (stderr, "string '%s' exp: %ld got: %ld\n", + array[idx].string, (unsigned long)array[idx].expected, + (unsigned long)val); + } + } +} + + static void test_isotime2epoch (void) { @@ -103,7 +153,6 @@ test_isotime2epoch (void) } - static void test_string2isotime (void) { @@ -269,6 +318,7 @@ main (int argc, char **argv) if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; + test_scan_secondsstr (); test_isotime2epoch (); test_string2isotime (); test_isodate_human_to_tm (); From 606933dfb48ddd3113bc60eb8b18126112b3b8a4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 14 Oct 2023 17:23:42 +0200 Subject: [PATCH 223/869] gpg: Allow to specify seconds since Epoch beyond 2038. * g10/keygen.c (parse_expire_string_with_ct): Use new function scan_secondsstr. (parse_creation_string): Ditto. -- Noet that we cap the seconds at the year 2106. GnuPG-bug-id: 6736 --- g10/keygen.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index c252b0de4..06fc39aa1 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2759,14 +2759,21 @@ parse_expire_string_with_ct (const char *string, u32 creation_time) || !strcmp (string, "never") || !strcmp (string, "-")) seconds = 0; else if (!strncmp (string, "seconds=", 8)) - seconds = atoi (string+8); + seconds = scan_secondsstr (string+8); else if ((abs_date = scan_isodatestr(string)) && (abs_date+86400/2) > curtime) seconds = (abs_date+86400/2) - curtime; else if ((tt = isotime2epoch (string)) != (time_t)(-1)) seconds = (u32)tt - curtime; else if ((mult = check_valid_days (string))) - seconds = atoi (string) * 86400L * mult; + { + uint64_t tmp64; + tmp64 = scan_secondsstr (string) * 86400L * mult; + if (tmp64 >= (u32)(-1)) + seconds = (u32)(-1) - 1; /* cap value. */ + else + seconds = (u32)tmp64; + } else seconds = (u32)(-1); @@ -2790,7 +2797,7 @@ parse_creation_string (const char *string) if (!*string) seconds = 0; else if ( !strncmp (string, "seconds=", 8) ) - seconds = atoi (string+8); + seconds = scan_secondsstr (string+8); else if ( !(seconds = scan_isodatestr (string))) { time_t tmp = isotime2epoch (string); From 956b1e1c26aa1c7b253096af50be3400ace43e4c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 16 Oct 2023 16:31:08 +0200 Subject: [PATCH 224/869] build: Extend autobuild diagnostics by the username * m4/autobuild.m4 (AB_INIT): Add username. -- The old autobuild diagnostics show up in build logs. What they are missing is an information on the user who triggered a build. EMAIL is a common thing to denote the actual user using a service account. --- m4/autobuild.m4 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/m4/autobuild.m4 b/m4/autobuild.m4 index ceed46494..20086ae9f 100644 --- a/m4/autobuild.m4 +++ b/m4/autobuild.m4 @@ -23,6 +23,9 @@ AC_DEFUN([AB_INIT], if test "$hostname"; then AC_MSG_NOTICE([autobuild hostname... $hostname]) fi + if test "$EMAIL"; then + AC_MSG_NOTICE([autobuild username... $EMAIL]) + fi ifelse([$1],[],,[AC_MSG_NOTICE([autobuild mode... $1])]) date=`date +%Y%m%d-%H%M%S` if test "$?" != 0; then From 873b2b0da1086f9c493527a46815f68f5dac1bcd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 18 Oct 2023 15:43:22 +0200 Subject: [PATCH 225/869] doc: Minor typo fixes. -- --- sm/keylist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sm/keylist.c b/sm/keylist.c index fabd82224..d6eccfc45 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -54,7 +54,7 @@ struct list_external_parm_s #define OID_FLAG_SKIP 1 /* The extension is a simple UTF8String and should be printed. */ #define OID_FLAG_UTF8 2 -/* The extension can be trnted as a hex string. */ +/* The extension can be printed as a hex string. */ #define OID_FLAG_HEX 4 /* Define if this specififies a key purpose. */ #define OID_FLAG_KP 8 @@ -208,6 +208,8 @@ static struct { "1.3.6.1.4.1.311.21.6", "ms-keyRecovery", OID_FLAG_KP }, { "1.3.6.1.4.1.311.21.19", "ms-dsEmailReplication", OID_FLAG_KP }, + /* BSI policies. */ + /* Other vendor extensions. */ { "1.3.6.1.4.1.30205.13.1.1", "trusted-disk", OID_FLAG_KP }, { "1.2.840.113583.1.1.5", "pdfAuthenticDocumentsTrust", OID_FLAG_KP }, From 7661d2fbc6eb533016df63a86ec3e35bf00cfb1f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 24 Oct 2023 09:22:13 +0200 Subject: [PATCH 226/869] sm: Another partly rewrite of minip12.c * sm/minip12.c (struct tlv_ctx_s): Add origbuffer and origbufsize. Remove pop_count. Rename offset to length. (dump_tag_info, _dump_tag_info): Rewrite. (dump_tlv_ctx, _dump_tlv_ctx): Rewrite. (tlv_new): Init origbuffer. (_tlv_peek): Add arg ti. (tlv_peek): New. (tlv_peek_null): New. (_tlv_push): Rewrite. (_tlv_pop): Rewrite. (tlv_next): New macro. Move old code to ... (_tlv_next): this. Add arg lno. Pop remaining end tags. (tlv_popped): Remove. (tlv_expect_object): Handle ndef. (tlv_expect_octet_string): Ditto. (parse_bag_encrypted_data): Use nesting level to control the inner loop. (parse_shrouded_key_bag): Likewise. (parse_bag_data): Handle surplus octet strings. (p12_parse): Ditto. * sm/minip12.c (decrypt_block): Strip the padding. (tlv_expect_top_sequence): Remove. Replace callers by tlv_expect_sequence. * tests/cms/samplekeys/t6752-ov-user-ff.p12: New sample key. * tests/cms/samplekeys/Description-p12: Add its description -- This patch improves the BER parser by simplifying it. Now tlv_next pops off and thus closes all containers regardless on whether they are length bounded or ndef. tlv_set_pending is now always used to undo the effect of a tlv_next in a loop condition which was terminated by a nesting level change. Instead of using the length as seen in the decrypted container we now remove the padding and let the BER parser do its work. This might have a negative effect on pkcs#12 objects which are not correctly padded but we don't have any example of such broken objects. GnuPG-bug-id: 6752 --- sm/minip12.c | 501 ++++++++++++++-------- tests/cms/samplekeys/Description-p12 | 6 + tests/cms/samplekeys/t6752-ov-user-ff.p12 | Bin 0 -> 2323 bytes 3 files changed, 325 insertions(+), 182 deletions(-) create mode 100644 tests/cms/samplekeys/t6752-ov-user-ff.p12 diff --git a/sm/minip12.c b/sm/minip12.c index 3705f3770..98eb4e3b5 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -174,11 +174,14 @@ struct bufferlist_s /* An object to control the ASN.1 parsing. */ struct tlv_ctx_s { + /* The orginal buffer with the entire pkcs#12 object and its length. */ + const unsigned char *origbuffer; + size_t origbufsize; + /* The current buffer we are working on and its length. */ const unsigned char *buffer; size_t bufsize; - size_t offset; /* The current offset into this buffer. */ int in_ndef; /* Flag indicating that we are in a NDEF. */ int pending; /* The last tlv_next has not yet been processed. */ @@ -186,15 +189,14 @@ struct tlv_ctx_s gpg_error_t lasterr; /* Last error from tlv function. */ const char *lastfunc;/* Name of last called function. */ - struct bufferlist_s *bufferlist; /* To keep track of amlloced buffers. */ + struct bufferlist_s *bufferlist; /* To keep track of malloced buffers. */ - unsigned int pop_count;/* Number of pops by tlv_next. */ unsigned int stacklen; /* Used size of the stack. */ struct { const unsigned char *buffer; /* Saved value of BUFFER. */ size_t bufsize; /* Saved value of BUFSIZE. */ - size_t offset; /* Saved value of OFFSET. */ - int in_ndef; /* Saved IN_NDEF flag. */ + size_t length; /* Length of the container (ti.length). */ + int in_ndef; /* Saved IN_NDEF flag (ti.ndef). */ } stack[TLV_MAX_DEPTH]; }; @@ -240,8 +242,9 @@ p12_set_verbosity (int verbose, int debug) } +#define dump_tag_info(a,b) _dump_tag_info ((a),__LINE__,(b)) static void -dump_tag_info (const char *text, struct tlv_ctx_s *tlv) +_dump_tag_info (const char *text, int lno, struct tlv_ctx_s *tlv) { struct tag_info *ti; @@ -249,13 +252,31 @@ dump_tag_info (const char *text, struct tlv_ctx_s *tlv) return; ti = &tlv->ti; - log_debug ("p12_parse(%s): ti.class=%-2d tag=%-2lu len=%-4zu nhdr=%zu %s %s" - " (%u:%zu.%zu)\n", - text, + + log_debug ("p12_parse:%s:%d: @%04zu class=%d tag=%lu len=%zu nhdr=%zu %s%s\n", + text, lno, + (size_t)(tlv->buffer - tlv->origbuffer) - ti->nhdr, ti->class, ti->tag, ti->length, ti->nhdr, - ti->is_constructed?"cons":" ", - ti->ndef?"ndef":" ", - tlv->stacklen, tlv->bufsize, tlv->offset); + ti->is_constructed?" cons":"", + ti->ndef?" ndef":""); +} + + +#define dump_tlv_ctx(a,b,c) _dump_tlv_ctx ((a),(b),__LINE__,(c)) +static void +_dump_tlv_ctx (const char *text, const char *text2, + int lno, struct tlv_ctx_s *tlv) +{ + if (opt_verbose < 2) + return; + + log_debug ("p12_parse:%s%s%s:%d: @%04zu lvl=%u %s\n", + text, + text2? "/":"", text2? text2:"", + lno, + (size_t)(tlv->buffer - tlv->origbuffer), + tlv->stacklen, + tlv->in_ndef? " in-ndef":""); } @@ -413,6 +434,8 @@ tlv_new (const unsigned char *buffer, size_t bufsize) tlv = xtrycalloc (1, sizeof *tlv); if (tlv) { + tlv->origbuffer = buffer; + tlv->origbufsize = bufsize; tlv->buffer = buffer; tlv->bufsize = bufsize; } @@ -454,17 +477,45 @@ tlv_release (struct tlv_ctx_s *tlv) } -/* Helper for tlv_next and tlv_peek. */ +/* Helper for the tlv_peek functions. */ static gpg_error_t -_tlv_peek (struct tlv_ctx_s *tlv, size_t *r_n) +_tlv_peek (struct tlv_ctx_s *tlv, struct tag_info *ti) { const unsigned char *p; + size_t n; - if (tlv->offset > tlv->bufsize) + /* Note that we want to peek ahead of any current container but of + * course not beyond our entire buffer. */ + p = tlv->buffer; + if ((p - tlv->origbuffer) > tlv->origbufsize) return gpg_error (GPG_ERR_BUG); - p = tlv->buffer + tlv->offset; - *r_n = tlv->bufsize - tlv->offset; - return parse_tag (&p, r_n, &tlv->ti); + n = tlv->origbufsize - (p - tlv->origbuffer); + return parse_tag (&p, &n, ti); +} + + +/* Look for the next tag and return true if it matches CLASS and TAG. + * Otherwise return false. No state is changed. */ +static int +tlv_peek (struct tlv_ctx_s *tlv, int class, int tag) +{ + struct tag_info ti; + + return (!_tlv_peek (tlv, &ti) + && ti.class == class && ti.tag == tag); +} + + +/* Look for the next tag and return true if it is the Null tag. + * Otherwise return false. No state is changed. */ +static int +tlv_peek_null (struct tlv_ctx_s *tlv) +{ + struct tag_info ti; + + return (!_tlv_peek (tlv, &ti) + && ti.class == CLASS_UNIVERSAL && ti.tag == TAG_NULL + && !ti.is_constructed && !ti.length); } @@ -472,23 +523,30 @@ _tlv_peek (struct tlv_ctx_s *tlv, size_t *r_n) static gpg_error_t _tlv_push (struct tlv_ctx_s *tlv) { + /* Right now our pointer is at the value of the current container. + * We push that info onto the stack. */ if (tlv->stacklen >= TLV_MAX_DEPTH) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_MANY)); tlv->stack[tlv->stacklen].buffer = tlv->buffer; tlv->stack[tlv->stacklen].bufsize = tlv->bufsize; - tlv->stack[tlv->stacklen].offset = tlv->offset; tlv->stack[tlv->stacklen].in_ndef = tlv->in_ndef; + tlv->stack[tlv->stacklen].length = tlv->ti.length; tlv->stacklen++; - tlv->buffer += tlv->offset; - if (tlv->ti.ndef) + + tlv->in_ndef = tlv->ti.ndef; + + /* We set the size of the buffer to the TLV length if it is known or + * else to the size of the remaining entire buffer. */ + if (tlv->in_ndef) { - log_assert (tlv->bufsize >= tlv->offset); - tlv->bufsize -= tlv->offset; + if ((tlv->buffer - tlv->origbuffer) > tlv->origbufsize) + return (tlv->lasterr = gpg_error (GPG_ERR_BUG)); + tlv->bufsize = tlv->origbufsize - (tlv->buffer - tlv->origbuffer); } else tlv->bufsize = tlv->ti.length; - tlv->offset = 0; - tlv->in_ndef = tlv->ti.ndef; + + dump_tlv_ctx (__func__, NULL, tlv); return 0; } @@ -497,74 +555,102 @@ _tlv_push (struct tlv_ctx_s *tlv) static gpg_error_t _tlv_pop (struct tlv_ctx_s *tlv) { - size_t saveoff; + size_t lastlen; + /* We reached the end of a container, either due to the size limit + * or due to an end tag. Now we pop the last container so that we + * are positioned at the value of the last container. */ if (!tlv->stacklen) return gpg_error (GPG_ERR_EOF); - saveoff = tlv->offset; - tlv->stacklen--; - tlv->buffer = tlv->stack[tlv->stacklen].buffer; - tlv->bufsize = tlv->stack[tlv->stacklen].bufsize; - tlv->offset = tlv->stack[tlv->stacklen].offset; tlv->in_ndef = tlv->stack[tlv->stacklen].in_ndef; + if (tlv->in_ndef) + { + /* We keep buffer but adjust bufsize to the end of the origbuffer. */ + if ((tlv->buffer - tlv->origbuffer) > tlv->origbufsize) + return (tlv->lasterr = gpg_error (GPG_ERR_BUG)); + tlv->bufsize = tlv->origbufsize - (tlv->buffer - tlv->origbuffer); + } + else + { + lastlen = tlv->stack[tlv->stacklen].length; + tlv->buffer = tlv->stack[tlv->stacklen].buffer; + tlv->bufsize = tlv->stack[tlv->stacklen].bufsize; + if (lastlen > tlv->bufsize) + { + log_debug ("%s: container length larger than buffer (%zu/%zu)\n", + __func__, lastlen, tlv->bufsize); + return gpg_error (GPG_ERR_INV_BER); + } + tlv->buffer += lastlen; + tlv->bufsize -= lastlen; + } - /* Move offset of the container to the end of the container. */ - tlv->offset += saveoff; - if (tlv->offset > tlv->bufsize) - return gpg_error (GPG_ERR_INV_BER); - - tlv->pop_count++; + dump_tlv_ctx (__func__, NULL, tlv); return 0; } -/* Parse the next tag and value. Also detect the end of a container; - * tlv_popped() can be used to detect this. */ +/* Parse the next tag and value. Also detect the end of a + * container. */ +#define tlv_next(a) _tlv_next ((a), __LINE__) static gpg_error_t -tlv_next (struct tlv_ctx_s *tlv) +_tlv_next (struct tlv_ctx_s *tlv, int lno) { gpg_error_t err; - size_t n; - tlv->pop_count = 0; tlv->lasterr = 0; tlv->lastfunc = __func__; + if (tlv->pending) { tlv->pending = 0; + if (opt_verbose > 1) + log_debug ("%s: tlv_next skipped\n", __func__); return 0; } - if (!tlv->in_ndef && tlv->offset == tlv->bufsize) + if (opt_verbose > 1) + log_debug ("%s: tlv_next called\n", __func__); + /* If we are at the end of an ndef container pop the stack. */ + if (!tlv->in_ndef && !tlv->bufsize) { - /* We are at the end of a container. Pop the stack. */ do err = _tlv_pop (tlv); - while (!err && !tlv->in_ndef && tlv->offset == tlv->bufsize); + while (!err && !tlv->in_ndef && !tlv->bufsize); if (err) return (tlv->lasterr = err); + if (opt_verbose > 1) + log_debug ("%s: container(s) closed due to size\n", __func__); } - err = _tlv_peek (tlv, &n); + again: + /* Get the next tag. */ + err = parse_tag (&tlv->buffer, &tlv->bufsize, &tlv->ti); if (err) - return err; + { + if (opt_verbose > 1) + log_debug ("%s: reading tag returned err=%d\n", __func__, err); + return err; + } + + /* If there is an end tag in an ndef container pop the stack. Also + * pop other containers which are fully consumed. */ if (tlv->in_ndef && (tlv->ti.class == CLASS_UNIVERSAL && !tlv->ti.tag && !tlv->ti.is_constructed)) { - /* End tag while in ndef container. Skip the tag, and pop. */ - tlv->offset += n - (tlv->bufsize - tlv->offset); - err = _tlv_pop (tlv); - /* FIXME: We need to peek whether there is another end tag and - * pop again. We can't modify the TLV object, though. */ + do + err = _tlv_pop (tlv); + while (!err && !tlv->in_ndef && !tlv->bufsize); if (err) return (tlv->lasterr = err); + if (opt_verbose > 1) + log_debug ("%s: container(s) closed due to end tag\n", __func__); + goto again; } - /* Set offset to the value of the TLV. */ - tlv->offset += tlv->bufsize - tlv->offset - n; - dump_tag_info ("tlv_next", tlv); + _dump_tag_info (__func__, lno, tlv); return 0; } @@ -577,15 +663,6 @@ tlv_level (struct tlv_ctx_s *tlv) } -/* If called right after tlv_next the number of container levels - * popped are returned. */ -static unsigned int -tlv_popped (struct tlv_ctx_s *tlv) -{ - return tlv->pop_count; -} - - /* Set a flag to indicate that the last tlv_next has not yet been * consumed. */ static void @@ -595,12 +672,15 @@ tlv_set_pending (struct tlv_ctx_s *tlv) } -/* Skip over the value of the current tag. */ +/* Skip over the value of the current tag. Does not yet work for ndef + * containers. */ static void tlv_skip (struct tlv_ctx_s *tlv) { tlv->lastfunc = __func__; - tlv->offset += tlv->ti.length; + log_assert (tlv->bufsize >= tlv->ti.length); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; } @@ -616,19 +696,6 @@ tlv_expect_sequence (struct tlv_ctx_s *tlv) return _tlv_push (tlv); } -/* Variant of tlv_expect_sequence to be used for the outer sequence - * of an object which might have padding after the ASN.1 data. */ -static gpg_error_t -tlv_expect_top_sequence (struct tlv_ctx_s *tlv) -{ - tlv->lastfunc = __func__; - if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_SEQUENCE - && tlv->ti.is_constructed)) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - tlv->bufsize = tlv->ti.nhdr + tlv->ti.length; - return _tlv_push (tlv); -} - /* Expect that the current tag is a context tag and setup the context * for processing. The tag of the context is returned at R_TAG. */ @@ -666,20 +733,28 @@ tlv_expect_object (struct tlv_ctx_s *tlv, int class, int tag, { gpg_error_t err; const unsigned char *p; + size_t n; + int needpush = 0; tlv->lastfunc = __func__; if (!(tlv->ti.class == class && tlv->ti.tag == tag)) return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer + tlv->offset; - if (!tlv->ti.length) + p = tlv->buffer; + n = tlv->ti.length; + if (!n && tlv->ti.ndef) + { + n = tlv->bufsize; + needpush = 1; + } + else if (!tlv->ti.length) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); if (class == CLASS_CONTEXT && tag == 0 && tlv->ti.is_constructed - && need_octet_string_cramming (p, tlv->ti.length)) + && need_octet_string_cramming (p, n)) { char *newbuffer; - newbuffer = cram_octet_string (p, tlv->ti.length, r_datalen); + newbuffer = cram_octet_string (p, n, r_datalen); if (!newbuffer) return (tlv->lasterr = gpg_error (GPG_ERR_BAD_BER)); err = tlv_register_buffer (tlv, newbuffer); @@ -693,10 +768,15 @@ tlv_expect_object (struct tlv_ctx_s *tlv, int class, int tag, else { *r_data = p; - *r_datalen = tlv->ti.length; + *r_datalen = n; } + if (needpush) + return _tlv_push (tlv); - tlv->offset += tlv->ti.length; + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; return 0; } @@ -718,7 +798,7 @@ tlv_expect_octet_string (struct tlv_ctx_s *tlv, int encapsulates, if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_OCTET_STRING && (!tlv->ti.is_constructed || encapsulates))) return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer + tlv->offset; + p = tlv->buffer; if (!(n=tlv->ti.length) && !tlv->ti.ndef) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); @@ -748,19 +828,10 @@ tlv_expect_octet_string (struct tlv_ctx_s *tlv, int encapsulates, if (encapsulates) return _tlv_push (tlv); - tlv->offset += tlv->ti.length; - return 0; -} - - -/* Expect a NULL tag. */ -static gpg_error_t -tlv_expect_null (struct tlv_ctx_s *tlv) -{ - tlv->lastfunc = __func__; - if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_NULL - && !tlv->ti.is_constructed && !tlv->ti.length)) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; return 0; } @@ -778,7 +849,7 @@ tlv_expect_integer (struct tlv_ctx_s *tlv, int *r_value) if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_INTEGER && !tlv->ti.is_constructed)) return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer + tlv->offset; + p = tlv->buffer; if (!(n=tlv->ti.length)) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); @@ -794,7 +865,10 @@ tlv_expect_integer (struct tlv_ctx_s *tlv, int *r_value) return (tlv->lasterr = gpg_error (GPG_ERR_EOVERFLOW)); } *r_value = value; - tlv->offset += tlv->ti.length; + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; return 0; } @@ -816,11 +890,14 @@ tlv_expect_mpinteger (struct tlv_ctx_s *tlv, int ignore_zero, if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_INTEGER && !tlv->ti.is_constructed)) return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer + tlv->offset; + p = tlv->buffer; if (!(n=tlv->ti.length)) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - tlv->offset += tlv->ti.length; + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; if (ignore_zero && n == 1 && !*p) return gpg_error (GPG_ERR_FALSE); @@ -842,13 +919,16 @@ tlv_expect_object_id (struct tlv_ctx_s *tlv, if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_OBJECT_ID && !tlv->ti.is_constructed)) return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer + tlv->offset; + p = tlv->buffer; if (!(n=tlv->ti.length)) return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); *r_oid = p; *r_oidlen = tlv->ti.length; - tlv->offset += tlv->ti.length; + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; return 0; } @@ -1171,9 +1251,9 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen, and CIPHER_ALGO is the algorithm id to use. CHECK_FNC is a function called with the plaintext and used to check whether the decryption succeeded; i.e. that a correct passphrase has been - given. That function shall return true if the decryption has likely - succeeded. */ -static void + given. The function returns the length of the unpadded plaintext + or 0 on error. */ +static size_t decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, char *salt, size_t saltlen, int iter, const void *iv, size_t ivlen, @@ -1202,6 +1282,7 @@ decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, int charsetidx = 0; char *convertedpw = NULL; /* Malloced and converted password or NULL. */ size_t convertedpwsize = 0; /* Allocated length. */ + size_t plainlen = 0; for (charsetidx=0; charsets[charsetidx]; charsetidx++) { @@ -1251,9 +1332,31 @@ decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, crypt_block (plaintext, length, salt, saltlen, iter, iv, ivlen, convertedpw? convertedpw:pw, cipher_algo, digest_algo, 0); if (check_fnc (plaintext, length)) - break; /* Decryption succeeded. */ + { + /* Strip the pkcs#7 padding. */ + if (length) + { + int n, i; + + n = plaintext[length-1]; + if (n >= length || n > 16) + log_info ("decryption failed; invalid padding size\n"); + else + { + for (i=1; i < n; i++) + if (plaintext[length-i-1] != n) + break; + if (i < n) + log_info ("decryption failed; invalid padding octet\n"); + else + plainlen = length - n; + } + } + break; /* Decryption probably succeeded. */ + } } gcry_free (convertedpw); + return plainlen; } @@ -1308,7 +1411,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) int keyelem_count; int renewed_tlv = 0; int loopcount; - unsigned int startlevel; + unsigned int startlevel, startlevel2; int digest_algo = GCRY_MD_SHA1; where = "bag.encryptedData"; @@ -1455,10 +1558,12 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) if (opt_verbose > 1) log_debug ("kdf digest algo = %d\n", digest_algo); - if (tlv_next (tlv)) - goto bailout; - if (tlv_expect_null (tlv)) - tlv_set_pending (tlv); /* NULL tag missing - ignore this. */ + if (tlv_peek_null (tlv)) + { + /* Read the optional Null tag. */ + if (tlv_next (tlv)) + goto bailout; + } } else digest_algo = GCRY_MD_SHA1; @@ -1548,12 +1653,17 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) log_error ("error allocating decryption buffer\n"); goto bailout; } - decrypt_block (data, plain, datalen, salt, saltlen, iter, + datalen = decrypt_block (data, plain, datalen, salt, saltlen, iter, iv, is_pbes2?16:0, ctx->password, is_pbes2 ? (is_aes256?GCRY_CIPHER_AES256:GCRY_CIPHER_AES128) : is_3des ? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40, digest_algo, bag_decrypted_data_p); + if (!datalen) + { + err = gpg_error (GPG_ERR_DECRYPT_FAILED); + goto bailout; + } /* We do not need the TLV anymore and allocated a new one. */ where = "bag.encryptedData.decrypted-text"; @@ -1570,7 +1680,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) ctx->badpass = 1; goto bailout; } - if (tlv_expect_top_sequence (tlv)) + if (tlv_expect_sequence (tlv)) { ctx->badpass = 1; goto bailout; @@ -1692,7 +1802,8 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) where = "reading.keybag.key-parameters"; keyelem_count = 0; - while (!(err = tlv_next (tlv)) && !tlv_popped (tlv)) + startlevel2 = tlv_level (tlv); + while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel2) { if (keyelem_count >= 9) { @@ -1714,7 +1825,9 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) log_debug ("RSA key parameter %d found\n", keyelem_count); keyelem_count++; } - if (err && gpg_err_code (err) != GPG_ERR_EOF) + if (!err) + tlv_set_pending (tlv); + else if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; err = 0; } @@ -1763,24 +1876,21 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) /* Skip the optional SET with the pkcs12 cert attributes. */ where = "bag.attribute_set"; - err = tlv_next (tlv); - if (gpg_err_code (err) == GPG_ERR_EOF) - break; - if (err) - goto bailout; - err = tlv_expect_set (tlv); - if (!err) - { /* This is the optional set of attributes. Skip it. */ + if (tlv_peek (tlv, CLASS_UNIVERSAL, TAG_SET)) + { + if (tlv_next (tlv)) + goto bailout; + err = tlv_expect_set (tlv); + if (err) + goto bailout; tlv_skip (tlv); if (opt_verbose) - log_info ("skipping bag.attribute_set\n"); + log_info ("skipping %s\n", where); } - else if (gpg_err_code (err) == GPG_ERR_INV_OBJ) - tlv_set_pending (tlv); /* The next tlv_next will be skipped. */ - else - goto bailout; } - if (err && gpg_err_code (err) != GPG_ERR_EOF) + if (!err) + tlv_set_pending (tlv); + else if (err && gpg_err_code (err) != GPG_ERR_EOF) { if (!loopcount) /* The first while(tlv_next) failed. */ ctx->badpass = 1; @@ -1804,10 +1914,9 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) bailout: if (!err) err = gpg_error (GPG_ERR_GENERAL); - log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + log_error ("%s(%s): lvl=%u (%s): %s - %s\n", __func__, where, tlv? tlv->stacklen : 0, - tlv? tlv->offset : 0, tlv? tlv->lastfunc : "", tlv ? gpg_strerror (tlv->lasterr) : "init failed", gpg_strerror (err)); @@ -1978,10 +2087,12 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) if (opt_verbose > 1) log_debug ("kdf digest algo = %d\n", digest_algo); - if (tlv_next (tlv)) - goto bailout; - if (tlv_expect_null (tlv)) - tlv_set_pending (tlv); /* NULL tag missing - ignore this. */ + if (tlv_peek_null (tlv)) + { + /* Read the optional Null tag. */ + if (tlv_next (tlv)) + goto bailout; + } } else digest_algo = GCRY_MD_SHA1; @@ -2067,13 +2178,17 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) log_error ("error allocating decryption buffer\n"); goto bailout; } - decrypt_block (data, plain, datalen, salt, saltlen, iter, + datalen = decrypt_block (data, plain, datalen, salt, saltlen, iter, iv, is_pbes2? 16:0, ctx->password, is_pbes2 ? (is_aes256?GCRY_CIPHER_AES256:GCRY_CIPHER_AES128) : GCRY_CIPHER_3DES, digest_algo, bag_data_p); - + if (!datalen) + { + err = gpg_error (GPG_ERR_DECRYPT_FAILED); + goto bailout; + } /* We do not need the TLV anymore and allocated a new one. */ where = "shrouded_key_bag.decrypted-text"; @@ -2093,7 +2208,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) ctx->badpass = 1; goto bailout; } - if (tlv_expect_top_sequence (tlv)) + if (tlv_expect_sequence (tlv)) { ctx->badpass = 1; goto bailout; @@ -2130,10 +2245,13 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) { if (opt_verbose > 1) log_debug ("RSA parameters\n"); - if (tlv_next (tlv)) - goto bailout; - if (tlv_expect_null (tlv)) - tlv_set_pending (tlv); /* NULL tag missing - ignore this. */ + + if (tlv_peek_null (tlv)) + { + /* Read the optional Null tag. */ + if (tlv_next (tlv)) + goto bailout; + } } else if (oidlen == DIM(oid_pcPublicKey) && !memcmp (oid, oid_pcPublicKey, oidlen)) @@ -2218,8 +2336,9 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) { int keyelem_count = 0; int firstparam = 1; + unsigned int startlevel = tlv_level (tlv); - while (!(err = tlv_next (tlv)) && !tlv_popped (tlv)) + while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) { if (keyelem_count >= 9) { @@ -2245,7 +2364,9 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) } firstparam = 0; } - if (err && gpg_err_code (err) != GPG_ERR_EOF) + if (!err) + tlv_set_pending (tlv); + else if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; err = 0; } @@ -2257,22 +2378,18 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) tlv = saved_tlv; where = "shrouded_key_bag.attribute_set"; - err = tlv_next (tlv); - if (gpg_err_code (err) == GPG_ERR_EOF) - goto leave; - if (err) - goto bailout; - err = tlv_expect_set (tlv); - if (!err) - { /* This is the optional set of attributes. Skip it. */ + /* Check for an optional set of attributes. */ + if (tlv_peek (tlv, CLASS_UNIVERSAL, TAG_SET)) + { + if (tlv_next (tlv)) + goto bailout; + err = tlv_expect_set (tlv); + if (err) + goto bailout; tlv_skip (tlv); if (opt_verbose) log_info ("skipping %s\n", where); } - else if (gpg_err_code (err) == GPG_ERR_INV_OBJ) - tlv_set_pending (tlv); /* The next tlv_next will be skipped. */ - else /* Other error. */ - goto bailout; leave: @@ -2288,10 +2405,9 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) bailout: if (!err) err = gpg_error (GPG_ERR_GENERAL); - log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + log_error ("%s(%s): lvl=%d (%s): %s - %s\n", __func__, where, tlv? tlv->stacklen : 0, - tlv? tlv->offset : 0, tlv? tlv->lastfunc : "", tlv ? gpg_strerror (tlv->lasterr) : "init failed", gpg_strerror (err)); @@ -2367,28 +2483,27 @@ parse_cert_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) * SEQUENCE -- we actually ignore this. */ where = "certbag.attribute_set"; - if (tlv_next (tlv)) - goto bailout; - err = tlv_expect_set (tlv); - if (!err) - { /* This is the optional set of attributes. Skip it. */ + /* Check for an optional set of attributes. */ + if (tlv_peek (tlv, CLASS_UNIVERSAL, TAG_SET)) + { + if (tlv_next (tlv)) + goto bailout; + err = tlv_expect_set (tlv); + if (err) + goto bailout; tlv_skip (tlv); if (opt_verbose) - log_info ("skipping certbag.attribute_set\n"); + log_info ("skipping %s\n", where); } - else if (gpg_err_code (err) == GPG_ERR_INV_OBJ) - tlv_set_pending (tlv); /* The next tlv_next will be skipped. */ - else - goto bailout; + leave: return err; bailout: - log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + log_error ("%s(%s): lvl=%u (%s): %s - %s\n", __func__, where, tlv? tlv->stacklen : 0, - tlv? tlv->offset : 0, tlv? tlv->lastfunc : "", tlv ? gpg_strerror (tlv->lasterr) : "init failed", gpg_strerror (err)); @@ -2426,6 +2541,14 @@ parse_bag_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) if (tlv_expect_octet_string (tlv, 1, NULL, NULL)) goto bailout; + if (tlv_peek (tlv, CLASS_UNIVERSAL, TAG_OCTET_STRING)) + { + if (tlv_next (tlv)) + goto bailout; + err = tlv_expect_octet_string (tlv, 1, NULL, NULL); + if (err) + goto bailout; + } /* Expect: * SEQUENCE @@ -2437,6 +2560,7 @@ parse_bag_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; startlevel = tlv_level (tlv); + dump_tlv_ctx ("data.outerseqs", "beginloop", tlv); while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) { /* Expect: @@ -2475,11 +2599,12 @@ parse_bag_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) log_info ("unknown inner data type - skipped\n"); } } - if (err && gpg_err_code (err) != GPG_ERR_EOF) + dump_tlv_ctx ("data.outerseqs", "endloop", tlv); + if (!err) + tlv_set_pending (tlv); + else if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; err = 0; - if (tlv_popped (tlv)) - tlv_set_pending (tlv); leave: return err; @@ -2487,10 +2612,9 @@ parse_bag_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) bailout: if (!err) err = gpg_error (GPG_ERR_GENERAL); - log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + log_error ("%s(%s): lvl=%d (%s): %s - %s\n", __func__, where, tlv? tlv->stacklen : 0, - tlv? tlv->offset : 0, tlv? tlv->lastfunc : "", tlv ? gpg_strerror (tlv->lasterr) : "init failed", gpg_strerror (err)); @@ -2567,6 +2691,14 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, if (tlv_expect_octet_string (tlv, 1, NULL, NULL)) goto bailout; + if (tlv_peek (tlv, CLASS_UNIVERSAL, TAG_OCTET_STRING)) + { + if (tlv_next (tlv)) + goto bailout; + err = tlv_expect_octet_string (tlv, 1, NULL, NULL); + if (err) + goto bailout; + } where = "bags"; if (tlv_next (tlv)) @@ -2575,9 +2707,11 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, goto bailout; startlevel = tlv_level (tlv); + dump_tlv_ctx ("bags", "beginloop", tlv); while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) { where = "bag-sequence"; + dump_tlv_ctx (where, NULL, tlv); if (tlv_expect_sequence (tlv)) goto bailout; @@ -2614,7 +2748,10 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, log_info ("unknown outer bag type - skipped\n"); } } - if (err && gpg_err_code (err) != GPG_ERR_EOF) + dump_tlv_ctx ("bags", "endloop", tlv); + if (!err) + tlv_set_pending (tlv); + else if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; err = 0; @@ -2628,12 +2765,12 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, bailout: *r_badpass = ctx.badpass; - log_error ("%s(%s): offset %u.%zu (%s): %s - %s\n", + log_error ("%s(%s): @%04zu lvl=%u %s: %s - %s\n", __func__, where, + tlv? (size_t)(tlv->buffer - tlv->origbuffer):0, tlv? tlv->stacklen : 0, - tlv? tlv->offset : 0, tlv? tlv->lastfunc : "", - tlv ? gpg_strerror (tlv->lasterr) : "init failed", + tlv? gpg_strerror (tlv->lasterr) : "init failed", gpg_strerror (err)); if (ctx.privatekey) { diff --git a/tests/cms/samplekeys/Description-p12 b/tests/cms/samplekeys/Description-p12 index a73998fac..01276087f 100644 --- a/tests/cms/samplekeys/Description-p12 +++ b/tests/cms/samplekeys/Description-p12 @@ -45,4 +45,10 @@ Pass: abc Cert: 5cea0c5bf09ccd92535267c662fc098f6c81c27e Key: 3cb2fba95d1976df69eb7aa8c65ac5354e15af32 +Name: t6752-ov-user-ff.p12 +Desc: Mozilla generated with a surplus octet string container +Pass: start +Cert: 4753a910e0c8b4caa8663ca0e4273a884eb5397d +Key: 93be89edd11214ab74280d988a665b6beef876c5 + # eof # diff --git a/tests/cms/samplekeys/t6752-ov-user-ff.p12 b/tests/cms/samplekeys/t6752-ov-user-ff.p12 new file mode 100644 index 0000000000000000000000000000000000000000..153ffb00037a62d7ac72ff96c8a67225a34e2d54 GIT binary patch literal 2323 zcmZvcdpy&98^?b(#^y}KFdA~|Foh}ZoT8A391@|08_RK?CC!|bHe@tp~_jg z&HbJS(uDnF=g?P_FKujMkX-0Q2+TU*BVL^@|E0TR!+ee(v08)|?yX%`3>&XgLo!i$ z9WL*gFN&_JP}Wt^XWbYHWnHXasX(K`NM@Yu+HtNIfg@C)^o<$Am78Wti@&Wm6$tX4 z^0{hKaoPQ5vlNhNW-T1C9n51 z9L#bv&c9>`ljTVI9#+LT|52lb!FC05yHH2ROhRv0=vG!cx%p{OJ3By-TKcv5HJRZA zna#&Whcd`Ij4zqKS=owL#d9Z$hQt?HL7o7)_QrDav6Wo@g3_q82?OYyEv2U%pCZ(IeTUK!W zkp67C8cwAYULY@#3XMIHmj{>Bo}LH=4}09Edq0t{fr#1WU6JrWR~FyGIp^4Fll2v1 zhoORO&=(x*yoZ0=q|jM*L(=QQ4q1j^xTLE2ey1u;Jnn8ERj#pRq9(cZyPzRIPt|k` zzQ&Vbfh<2T_{<8ts2Fz?kIdCD3`N=eXX>Fl3{4P5fIV;# zhy)^lXaEO<0D(W=Kp+Ot0KEUsLV%#{N*EBZ-JtfNp_;G&52}0hc3nT>mtO@-OJ&=FWv$q1Q{3*nbIc`^VV%ULj<_A6G zZ9GMQGWQIoz@arYcwv@jz0%Fd_H7YeYBbjggWoE$+FgWZa-sxEuz8EZcILgDRgC2^ zS{G*?i)xO!AtdJXPNkin=1n)(wxnE92JK>|u8C9gK5XjB;LIWN zk@rNP(;sCNX%%l%6tq>A(S*p?EmF0Q5bY2VP^XZpY zC`x_C{I*7)=9P0de;4bshGLK@A{Cb`4&%>*ET&2W7;HqpCTrp|Wpk)LUo+G|+ZC;I zqtswjg!db45tur_D>W%9@VDB>eD$k~H8UgOv8L*4M)z?u0h zd`14r&=rd|`|Ui@?z%PN%$sGEnxP>Dn;gaw|mhz+^kHumt|L+;_PUTYKBzJp^G+5$r@cgNIw zNqbYb^d?96*5DjTlVo?QCt~d|!p!NxQSPxL;sP9{p^gKqD_CQ_o8%~EQUl9j;-2{- zB8wTLaF_O?PiLR)Rk-CHV7_ZMklOpa`c#uTfq;|HY-tlWy}$4A2lGjbh0I%7>%^H3 zO!zOGr}a7aCUBi*M`{x7(i+&(MS~IGq2Bc@*od4F3q_Of_?~#6$KKPpx&NNtZY8y+ zPnK(Pave*FsYkj(r_7)-vG zJYTF2?-Tea!1-XnZAo9va#g>op~I;TJnjo+o}uRc2BQS)j~ zO8utZ@9;pxb7-Nd@SIgnCro$HimQaNfVp-)AgsOTJFxx9P#3a^HZKa$dG}vMlf}*GRarr z^V7DS)c$eOKAf_n?-u)Q2!74reN%EmcJmamLW|@XrQstb%J`PY$I1BP>P7eIuzzd zud5+m6o5o|b~|x!n}HX++sqDs_zSh&{PFk~wKsyenq>tJIobAT&;aKw7>2K^A3$X0 zVh`itnGe|M(1OrAM>H6n#qLgv6C>mVf<4TLvfC?IaZ%QEk^?_OBUeA?IcAgm`+T@b zpSNxT4;3HvsO1luX_ewqg2_8(>{PP9FD|V~eO}0kv)!*KPg>He97^j!F2xRPeZPPw zRnSs2o?4glESFo|9+cm#2)~z^T$%daTdszEZp(_BITeOm?F&{ID>eJAdbCa`KV_U= zt%rv>#Hvdav&f?j76wgvkar|AFmWb=bYqU~uPcbAUN3%tQ!dunnlWy}=%nndh?#m= zwO3o$0d+KEL^|Zm+jovk0UdXLa6>ht8j?7&qA~-sx;@Tu8?JA7-jNYs9KWJ-b*aVN zMBevFIe*E^fe_nisjBbez&Ig*)K`5r;?hj0PD6rCm9bVq(P=2 zelEGbD2l~ftqORqE@|a-XXa+piM@EzL-1$`L0Bvol6T&zl$i0a?fUbLI*i(df Date: Tue, 24 Oct 2023 13:25:10 +0200 Subject: [PATCH 227/869] common: Provide API to parse BER/TLV encodings. * sm/minip12.c: Factor parsing code out to ... * common/tlv-parser.c: new. Extend function names and provide a few extra functions. * common/Makefile.am (common_sources): Add new file. * sm/minip12.c: Adjust to use the new parser API. --- common/Makefile.am | 2 +- common/tlv-parser.c | 788 ++++++++++++++++++++++++++++++++++++++++ common/tlv.h | 67 +++- sm/minip12.c | 860 ++++---------------------------------------- 4 files changed, 922 insertions(+), 795 deletions(-) create mode 100644 common/tlv-parser.c diff --git a/common/Makefile.am b/common/Makefile.am index 7c78708da..91718f99e 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -58,7 +58,7 @@ common_sources = \ openpgpdefs.h \ gc-opt-flags.h \ sexp-parse.h \ - tlv.c tlv.h tlv-builder.c \ + tlv.c tlv.h tlv-builder.c tlv-parser.c \ init.c init.h \ sexputil.c \ sysutils.c sysutils.h \ diff --git a/common/tlv-parser.c b/common/tlv-parser.c new file mode 100644 index 000000000..c9b33d4b6 --- /dev/null +++ b/common/tlv-parser.c @@ -0,0 +1,788 @@ +/* tlv-parser.c - Parse BER encoded objects + * Copyright (C) 2023 g10 Code GmbH + * + * 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 . + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include + +#include +#include +#include +#include + +#include "util.h" +#include "tlv.h" + + +#define TLV_MAX_DEPTH 25 + + +struct bufferlist_s +{ + struct bufferlist_s *next; + char *buffer; +}; + + +/* An object to control the ASN.1 parsing. */ +struct tlv_parser_s +{ + /* The orginal buffer with the entire pkcs#12 object and its length. */ + const unsigned char *origbuffer; + size_t origbufsize; + + /* The current buffer we are working on and its length. */ + const unsigned char *buffer; + size_t bufsize; + + int in_ndef; /* Flag indicating that we are in a NDEF. */ + int pending; /* The last tlv_next has not yet been processed. */ + + struct tag_info ti; /* The current tag. */ + gpg_error_t lasterr; /* Last error from tlv function. */ + const char *lastfunc;/* Name of last called function. */ + int verbosity; /* Arg from tlv_parser_new. */ + + struct bufferlist_s *bufferlist; /* To keep track of malloced buffers. */ + + unsigned int stacklen; /* Used size of the stack. */ + struct { + const unsigned char *buffer; /* Saved value of BUFFER. */ + size_t bufsize; /* Saved value of BUFSIZE. */ + size_t length; /* Length of the container (ti.length). */ + int in_ndef; /* Saved IN_NDEF flag (ti.ndef). */ + } stack[TLV_MAX_DEPTH]; +}; + + +static unsigned char *cram_octet_string (const unsigned char *input, + size_t length, size_t *r_newlength); +static int need_octet_string_cramming (const unsigned char *input, + size_t length); + + + +void +_tlv_parser_dump_tag (const char *text, int lno, tlv_parser_t tlv) +{ + struct tag_info *ti; + + if (!tlv || tlv->verbosity < 2) + return; + + ti = &tlv->ti; + + log_debug ("p12_parse:%s:%d: @%04zu class=%d tag=%lu len=%zu nhdr=%zu %s%s\n", + text, lno, + (size_t)(tlv->buffer - tlv->origbuffer) - ti->nhdr, + ti->class, ti->tag, ti->length, ti->nhdr, + ti->is_constructed?" cons":"", + ti->ndef?" ndef":""); +} + + +void +_tlv_parser_dump_state (const char *text, const char *text2, + int lno, tlv_parser_t tlv) +{ + if (!tlv || tlv->verbosity < 2) + return; + + log_debug ("p12_parse:%s%s%s:%d: @%04zu lvl=%u %s\n", + text, + text2? "/":"", text2? text2:"", + lno, + (size_t)(tlv->buffer - tlv->origbuffer), + tlv->stacklen, + tlv->in_ndef? " in-ndef":""); +} + + + +/* Parse the buffer at the address BUFFER which is of SIZE and return + * the tag and the length part from the TLV triplet. Update BUFFER + * and SIZE on success. Checks that the encoded length does not + * exhaust the length of the provided buffer. */ +static int +parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti) +{ + gpg_error_t err; + int tag; + + err = parse_ber_header (buffer, size, + &ti->class, &tag, + &ti->is_constructed, &ti->ndef, + &ti->length, &ti->nhdr); + if (err) + return err; + if (tag < 0) + return gpg_error (GPG_ERR_EOVERFLOW); + ti->tag = tag; + + if (ti->length > *size) + return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); /* data larger than buffer. */ + + return 0; +} + +/* Public version of parse_tag. */ +gpg_error_t +tlv_parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti) +{ + return parse_tag (buffer, size, ti); +} + + +/* Create a new TLV object. */ +tlv_parser_t +tlv_parser_new (const unsigned char *buffer, size_t bufsize, int verbosity) +{ + tlv_parser_t tlv; + tlv = xtrycalloc (1, sizeof *tlv); + if (tlv) + { + tlv->origbuffer = buffer; + tlv->origbufsize = bufsize; + tlv->buffer = buffer; + tlv->bufsize = bufsize; + tlv->verbosity = verbosity; + } + return tlv; +} + + +/* This function can be used to store a malloced buffer into the TLV + * object. Ownership of BUFFER is thus transferred to TLV. This + * buffer will then only be released by tlv_release. */ +static gpg_error_t +register_buffer (tlv_parser_t tlv, char *buffer) +{ + struct bufferlist_s *item; + + item = xtrycalloc (1, sizeof *item); + if (!item) + return gpg_error_from_syserror (); + item->buffer = buffer; + item->next = tlv->bufferlist; + tlv->bufferlist = item; + return 0; +} + + +void +tlv_parser_release (tlv_parser_t tlv) +{ + if (!tlv) + return; + while (tlv->bufferlist) + { + struct bufferlist_s *save = tlv->bufferlist->next; + xfree (tlv->bufferlist->buffer); + xfree (tlv->bufferlist); + tlv->bufferlist = save; + } + xfree (tlv); +} + + +/* Helper for the tlv_peek functions. */ +static gpg_error_t +_tlv_peek (tlv_parser_t tlv, struct tag_info *ti) +{ + const unsigned char *p; + size_t n; + + /* Note that we want to peek ahead of any current container but of + * course not beyond our entire buffer. */ + p = tlv->buffer; + if ((p - tlv->origbuffer) > tlv->origbufsize) + return gpg_error (GPG_ERR_BUG); + n = tlv->origbufsize - (p - tlv->origbuffer); + return parse_tag (&p, &n, ti); +} + + +/* Look for the next tag and return true if it matches CLASS and TAG. + * Otherwise return false. No state is changed. */ +int +_tlv_parser_peek (tlv_parser_t tlv, int class, int tag) +{ + struct tag_info ti; + + return (!_tlv_peek (tlv, &ti) + && ti.class == class && ti.tag == tag); +} + + +/* Look for the next tag and return true if it is the Null tag. + * Otherwise return false. No state is changed. */ +int +_tlv_parser_peek_null (tlv_parser_t tlv) +{ + struct tag_info ti; + + return (!_tlv_peek (tlv, &ti) + && ti.class == CLASS_UNIVERSAL && ti.tag == TAG_NULL + && !ti.is_constructed && !ti.length); +} + + +/* Helper for tlv_expect_sequence and tlv_expect_context_tag. */ +static gpg_error_t +_tlv_push (tlv_parser_t tlv) +{ + /* Right now our pointer is at the value of the current container. + * We push that info onto the stack. */ + if (tlv->stacklen >= TLV_MAX_DEPTH) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_MANY)); + tlv->stack[tlv->stacklen].buffer = tlv->buffer; + tlv->stack[tlv->stacklen].bufsize = tlv->bufsize; + tlv->stack[tlv->stacklen].in_ndef = tlv->in_ndef; + tlv->stack[tlv->stacklen].length = tlv->ti.length; + tlv->stacklen++; + + tlv->in_ndef = tlv->ti.ndef; + + /* We set the size of the buffer to the TLV length if it is known or + * else to the size of the remaining entire buffer. */ + if (tlv->in_ndef) + { + if ((tlv->buffer - tlv->origbuffer) > tlv->origbufsize) + return (tlv->lasterr = gpg_error (GPG_ERR_BUG)); + tlv->bufsize = tlv->origbufsize - (tlv->buffer - tlv->origbuffer); + } + else + tlv->bufsize = tlv->ti.length; + + _tlv_parser_dump_state (__func__, NULL, 0, tlv); + return 0; +} + + +/* Helper for tlv_next. */ +static gpg_error_t +_tlv_pop (tlv_parser_t tlv) +{ + size_t lastlen; + + /* We reached the end of a container, either due to the size limit + * or due to an end tag. Now we pop the last container so that we + * are positioned at the value of the last container. */ + if (!tlv->stacklen) + return gpg_error (GPG_ERR_EOF); + + tlv->stacklen--; + tlv->in_ndef = tlv->stack[tlv->stacklen].in_ndef; + if (tlv->in_ndef) + { + /* We keep buffer but adjust bufsize to the end of the origbuffer. */ + if ((tlv->buffer - tlv->origbuffer) > tlv->origbufsize) + return (tlv->lasterr = gpg_error (GPG_ERR_BUG)); + tlv->bufsize = tlv->origbufsize - (tlv->buffer - tlv->origbuffer); + } + else + { + lastlen = tlv->stack[tlv->stacklen].length; + tlv->buffer = tlv->stack[tlv->stacklen].buffer; + tlv->bufsize = tlv->stack[tlv->stacklen].bufsize; + if (lastlen > tlv->bufsize) + { + log_debug ("%s: container length larger than buffer (%zu/%zu)\n", + __func__, lastlen, tlv->bufsize); + return gpg_error (GPG_ERR_INV_BER); + } + tlv->buffer += lastlen; + tlv->bufsize -= lastlen; + } + + _tlv_parser_dump_state (__func__, NULL, 0, tlv); + return 0; +} + + +/* Parse the next tag and value. Also detect the end of a + * container. The caller should use the tlv_next macro. */ +gpg_error_t +_tlv_parser_next (tlv_parser_t tlv, int lno) +{ + gpg_error_t err; + + tlv->lasterr = 0; + tlv->lastfunc = __func__; + + if (tlv->pending) + { + tlv->pending = 0; + if (tlv->verbosity > 1) + log_debug ("%s: skipped\n", __func__); + return 0; + } + + if (tlv->verbosity > 1) + log_debug ("%s: called\n", __func__); + /* If we are at the end of an ndef container pop the stack. */ + if (!tlv->in_ndef && !tlv->bufsize) + { + do + err = _tlv_pop (tlv); + while (!err && !tlv->in_ndef && !tlv->bufsize); + if (err) + return (tlv->lasterr = err); + if (tlv->verbosity > 1) + log_debug ("%s: container(s) closed due to size\n", __func__); + } + + again: + /* Get the next tag. */ + err = parse_tag (&tlv->buffer, &tlv->bufsize, &tlv->ti); + if (err) + { + if (tlv->verbosity > 1) + log_debug ("%s: reading tag returned err=%d\n", __func__, err); + return err; + } + + /* If there is an end tag in an ndef container pop the stack. Also + * pop other containers which are fully consumed. */ + if (tlv->in_ndef && (tlv->ti.class == CLASS_UNIVERSAL + && !tlv->ti.tag && !tlv->ti.is_constructed)) + { + do + err = _tlv_pop (tlv); + while (!err && !tlv->in_ndef && !tlv->bufsize); + if (err) + return (tlv->lasterr = err); + if (tlv->verbosity > 1) + log_debug ("%s: container(s) closed due to end tag\n", __func__); + goto again; + } + + _tlv_parser_dump_tag (__func__, lno, tlv); + return 0; +} + + +/* Return the current neting level of the TLV object. */ +unsigned int +tlv_parser_level (tlv_parser_t tlv) +{ + return tlv? tlv->stacklen : 0; +} + +/* Returns the current offset of the parser. */ +size_t +tlv_parser_offset (tlv_parser_t tlv) +{ + return tlv? (size_t)(tlv->buffer - tlv->origbuffer) : 0; +} + + +/* Return a string with the last function used. If TLV is NULL an + * empty string is returned. */ +const char * +tlv_parser_lastfunc (tlv_parser_t tlv) +{ + return tlv? tlv->lastfunc:""; +} + + +const char * +tlv_parser_lasterrstr (tlv_parser_t tlv) +{ + return tlv? gpg_strerror (tlv->lasterr) : "tlv parser not yet initialized"; +} + + +/* Set a flag to indicate that the last tlv_next has not yet been + * consumed. */ +void +tlv_parser_set_pending (tlv_parser_t tlv) +{ + tlv->pending = 1; +} + + +/* Return the length of the last read tag. If with_header is 1 the + * lengtb of the header is added to the returned length. */ +size_t +tlv_parser_tag_length (tlv_parser_t tlv, int with_header) +{ + if (with_header) + return tlv->ti.length + tlv->ti.nhdr; + else + return tlv->ti.length; +} + + +/* Skip over the value of the current tag. Does not yet work for ndef + * containers. */ +void +tlv_parser_skip (tlv_parser_t tlv) +{ + tlv->lastfunc = __func__; + log_assert (tlv->bufsize >= tlv->ti.length); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; +} + + +/* Expect that the current tag is a sequence and setup the context for + * processing. */ +gpg_error_t +tlv_expect_sequence (tlv_parser_t tlv) +{ + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_SEQUENCE + && tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + return _tlv_push (tlv); +} + + +/* Expect that the current tag is a context tag and setup the context + * for processing. The tag of the context is returned at R_TAG. */ +gpg_error_t +tlv_expect_context_tag (tlv_parser_t tlv, int *r_tag) +{ + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_CONTEXT && tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + *r_tag = tlv->ti.tag; + return _tlv_push (tlv); +} + + +/* Expect that the current tag is a SET and setup the context for + * processing. */ +gpg_error_t +tlv_expect_set (tlv_parser_t tlv) +{ + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_SET + && tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + return _tlv_push (tlv); +} + + +/* Expect an object of CLASS with TAG and store its value at + * (R_DATA,R_DATALEN). Then skip over its value to the next tag. + * Note that the stored value is not allocated but points into + * TLV. */ +gpg_error_t +tlv_expect_object (tlv_parser_t tlv, int class, int tag, + unsigned char const **r_data, size_t *r_datalen) +{ + gpg_error_t err; + const unsigned char *p; + size_t n; + int needpush = 0; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == class && tlv->ti.tag == tag)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer; + n = tlv->ti.length; + if (!n && tlv->ti.ndef) + { + n = tlv->bufsize; + needpush = 1; + } + else if (!tlv->ti.length) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + if (class == CLASS_CONTEXT && tag == 0 && tlv->ti.is_constructed + && need_octet_string_cramming (p, n)) + { + char *newbuffer; + + newbuffer = cram_octet_string (p, n, r_datalen); + if (!newbuffer) + return (tlv->lasterr = gpg_error (GPG_ERR_BAD_BER)); + err = register_buffer (tlv, newbuffer); + if (err) + { + xfree (newbuffer); + return (tlv->lasterr = err); + } + *r_data = newbuffer; + } + else + { + *r_data = p; + *r_datalen = n; + } + if (needpush) + return _tlv_push (tlv); + + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; + return 0; +} + + +/* Expect that the current tag is an object string and store its value + * at (R_DATA,R_DATALEN). Then skip over its value to the next tag. + * Note that the stored value are not allocated but point into TLV. + * If ENCAPSULATES is set the octet string is used as a new + * container. R_DATA and R_DATALEN are optional. */ +gpg_error_t +tlv_expect_octet_string (tlv_parser_t tlv, int encapsulates, + unsigned char const **r_data, size_t *r_datalen) +{ + gpg_error_t err; + const unsigned char *p; + size_t n; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_OCTET_STRING + && (!tlv->ti.is_constructed || encapsulates))) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer; + if (!(n=tlv->ti.length) && !tlv->ti.ndef) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + if (encapsulates && tlv->ti.is_constructed + && need_octet_string_cramming (p, n)) + { + char *newbuffer; + + newbuffer = cram_octet_string (p, n, r_datalen); + if (!newbuffer) + return (tlv->lasterr = gpg_error (GPG_ERR_BAD_BER)); + err = register_buffer (tlv, newbuffer); + if (err) + { + xfree (newbuffer); + return (tlv->lasterr = err); + } + *r_data = newbuffer; + } + else + { + if (r_data) + *r_data = p; + if (r_datalen) + *r_datalen = tlv->ti.length; + } + if (encapsulates) + return _tlv_push (tlv); + + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; + return 0; +} + + +/* Expect that the current tag is an integer and return its value at + * R_VALUE. Then skip over its value to the next tag. */ +gpg_error_t +tlv_expect_integer (tlv_parser_t tlv, int *r_value) +{ + const unsigned char *p; + size_t n; + int value; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_INTEGER + && !tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer; + if (!(n=tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + /* We currently support only positive values. */ + if ((*p & 0x80)) + return (tlv->lasterr = gpg_error (GPG_ERR_ERANGE)); + + for (value = 0; n; n--) + { + value <<= 8; + value |= (*p++) & 0xff; + if (value < 0) + return (tlv->lasterr = gpg_error (GPG_ERR_EOVERFLOW)); + } + *r_value = value; + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; + return 0; +} + + +/* Variant of tlv_expect_integer which returns an MPI. If IGNORE_ZERO + * is set a value of 0 is ignored and R_VALUE not changed and the + * function returns GPG_ERR_FALSE. No check for negative encoded + * integers is done because the old code here worked the same and we + * can't foreclose invalid encoded PKCS#12 stuff - after all it is + * PKCS#12 see https://www.cs.auckland.ac.nz/~pgut001/pubs/pfx.html */ +#ifdef GCRYPT_VERSION +gpg_error_t +tlv_expect_mpinteger (tlv_parser_t tlv, int ignore_zero, + gcry_mpi_t *r_value) +{ + const unsigned char *p; + size_t n; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_INTEGER + && !tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer; + if (!(n=tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; + if (ignore_zero && n == 1 && !*p) + return gpg_error (GPG_ERR_FALSE); + + return gcry_mpi_scan (r_value, GCRYMPI_FMT_USG, p, n, NULL); +} +#endif /*GCRYPT_VERSION*/ + + +/* Expect that the current tag is an object id and store its value at + * (R_OID,R_OIDLEN). Then skip over its value to the next tag. Note + * that the stored value is not allocated but points into TLV. */ +gpg_error_t +tlv_expect_object_id (tlv_parser_t tlv, + unsigned char const **r_oid, size_t *r_oidlen) +{ + const unsigned char *p; + size_t n; + + tlv->lastfunc = __func__; + if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_OBJECT_ID + && !tlv->ti.is_constructed)) + return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); + p = tlv->buffer; + if (!(n=tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + + *r_oid = p; + *r_oidlen = tlv->ti.length; + if (!(tlv->bufsize >= tlv->ti.length)) + return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); + tlv->buffer += tlv->ti.length; + tlv->bufsize -= tlv->ti.length; + return 0; +} + + +/* Given an ASN.1 chunk of a structure like: + * + * 24 NDEF: OCTET STRING -- This is not passed to us + * 04 1: OCTET STRING -- INPUT point s to here + * : 30 + * 04 1: OCTET STRING + * : 80 + * [...] + * 04 2: OCTET STRING + * : 00 00 + * : } -- This denotes a Null tag and are the last + * -- two bytes in INPUT. + * + * The example is from Mozilla Firefox 1.0.4 which actually exports + * certs as single byte chunks of octet strings. + * + * Create a new buffer with the content of that octet string. INPUT + * is the original buffer with a LENGTH. Returns + * NULL on error or a new malloced buffer with its actual used length + * stored at R_NEWLENGTH. */ +static unsigned char * +cram_octet_string (const unsigned char *input, size_t length, + size_t *r_newlength) +{ + const unsigned char *s = input; + size_t n = length; + unsigned char *output, *d; + struct tag_info ti; + + /* Allocate output buf. We know that it won't be longer than the + input buffer. */ + d = output = xtrymalloc (length); + if (!output) + goto bailout; + + while (n) + { + if (parse_tag (&s, &n, &ti)) + goto bailout; + if (ti.class == CLASS_UNIVERSAL && ti.tag == TAG_OCTET_STRING + && !ti.ndef && !ti.is_constructed) + { + memcpy (d, s, ti.length); + s += ti.length; + d += ti.length; + n -= ti.length; + } + else if (ti.class == CLASS_UNIVERSAL && !ti.tag && !ti.is_constructed) + break; /* Ready */ + else + goto bailout; + } + + + *r_newlength = d - output; + return output; + + bailout: + xfree (output); + return NULL; +} + + +/* Return true if (INPUT,LENGTH) is a structure which should be passed + * to cram_octet_string. This is basically the same loop as in + * cram_octet_string but without any actual copying. */ +static int +need_octet_string_cramming (const unsigned char *input, size_t length) +{ + const unsigned char *s = input; + size_t n = length; + struct tag_info ti; + + if (!length) + return 0; + + while (n) + { + if (parse_tag (&s, &n, &ti)) + return 0; + if (ti.class == CLASS_UNIVERSAL && ti.tag == TAG_OCTET_STRING + && !ti.ndef && !ti.is_constructed) + { + s += ti.length; + n -= ti.length; + } + else if (ti.class == CLASS_UNIVERSAL && !ti.tag && !ti.is_constructed) + break; /* Ready */ + else + return 0; + } + + return 1; +} diff --git a/common/tlv.h b/common/tlv.h index e371ca57e..afaa649d9 100644 --- a/common/tlv.h +++ b/common/tlv.h @@ -71,10 +71,22 @@ enum tlv_tag_type { TAG_BMP_STRING = 30 }; +struct tag_info +{ + int class; + int is_constructed; + unsigned long tag; + size_t length; /* length part of the TLV */ + size_t nhdr; + int ndef; /* It is an indefinite length */ +}; struct tlv_builder_s; typedef struct tlv_builder_s *tlv_builder_t; +struct tlv_parser_s; +typedef struct tlv_parser_s *tlv_parser_t; + /*-- tlv.c --*/ /* Locate a TLV encoded data object in BUFFER of LENGTH and return a @@ -94,7 +106,7 @@ const unsigned char *find_tlv_unchecked (const unsigned char *buffer, /* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag and the length part from the TLV triplet. Update BUFFER and SIZE - on success. */ + on success. See also tlv_parse_tag. */ gpg_error_t parse_ber_header (unsigned char const **buffer, size_t *size, int *r_class, int *r_tag, int *r_constructed, @@ -137,6 +149,59 @@ void put_tlv_to_membuf (membuf_t *membuf, int class, int tag, size_t get_tlv_length (int class, int tag, int constructed, size_t length); +/*-- tlv-parser.c --*/ + +tlv_parser_t tlv_parser_new (const unsigned char *buffer, size_t bufsize, + int verbosity); +void tlv_parser_release (tlv_parser_t tlv); + +void _tlv_parser_dump_tag (const char *text, int lno, tlv_parser_t tlv); +void _tlv_parser_dump_state (const char *text, const char *text2, + int lno, tlv_parser_t tlv); + +int _tlv_parser_peek (tlv_parser_t tlv, int class, int tag); +int _tlv_parser_peek_null (tlv_parser_t tlv); +gpg_error_t _tlv_parser_next (tlv_parser_t tlv, int lno); + +unsigned int tlv_parser_level (tlv_parser_t tlv); +size_t tlv_parser_offset (tlv_parser_t tlv); +const char *tlv_parser_lastfunc (tlv_parser_t tlv); +const char *tlv_parser_lasterrstr (tlv_parser_t tlv); +void tlv_parser_set_pending (tlv_parser_t tlv); +size_t tlv_parser_tag_length (tlv_parser_t tlv, int with_header); + +void tlv_parser_skip (tlv_parser_t tlv); + +gpg_error_t tlv_expect_sequence (tlv_parser_t tlv); +gpg_error_t tlv_expect_context_tag (tlv_parser_t tlv, int *r_tag); +gpg_error_t tlv_expect_set (tlv_parser_t tlv); +gpg_error_t tlv_expect_object (tlv_parser_t tlv, int class, int tag, + unsigned char const **r_data, + size_t *r_datalen); +gpg_error_t tlv_expect_octet_string (tlv_parser_t tlv, int encapsulates, + unsigned char const **r_data, + size_t *r_datalen); +gpg_error_t tlv_expect_integer (tlv_parser_t tlv, int *r_value); +#ifdef GCRYPT_VERSION +gpg_error_t tlv_expect_mpinteger (tlv_parser_t tlv, int ignore_zero, + gcry_mpi_t *r_value); +#endif +gpg_error_t tlv_expect_object_id (tlv_parser_t tlv, + unsigned char const **r_oid, + size_t *r_oidlen); + +/* Easier to use wrapper around parse_ber_header. */ +gpg_error_t tlv_parse_tag (unsigned char const **buffer, + size_t *size, struct tag_info *ti); + +/* Convenience macro and macros to include the line number. */ +#define tlv_parser_dump_tag(a,b) _tlv_parser_dump_tag ((a),__LINE__,(b)) +#define tlv_parser_dump_state(a,b,c) \ + _tlv_parser_dump_state ((a),(b),__LINE__,(c)) +#define tlv_peek(a,b,c) _tlv_parser_peek ((a),(b),(c)) +#define tlv_peek_null(a) _tlv_parser_peek_null ((a)) +#define tlv_next(a) _tlv_parser_next ((a), __LINE__) + #endif /* SCD_TLV_H */ diff --git a/sm/minip12.c b/sm/minip12.c index 98eb4e3b5..ae81d821b 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -150,57 +150,6 @@ struct buffer_s }; -struct tag_info -{ - int class; - int is_constructed; - unsigned long tag; - size_t length; /* length part of the TLV */ - size_t nhdr; - int ndef; /* It is an indefinite length */ -}; - - -#define TLV_MAX_DEPTH 20 - - -struct bufferlist_s -{ - struct bufferlist_s *next; - char *buffer; -}; - - -/* An object to control the ASN.1 parsing. */ -struct tlv_ctx_s -{ - /* The orginal buffer with the entire pkcs#12 object and its length. */ - const unsigned char *origbuffer; - size_t origbufsize; - - /* The current buffer we are working on and its length. */ - const unsigned char *buffer; - size_t bufsize; - - int in_ndef; /* Flag indicating that we are in a NDEF. */ - int pending; /* The last tlv_next has not yet been processed. */ - - struct tag_info ti; /* The current tag. */ - gpg_error_t lasterr; /* Last error from tlv function. */ - const char *lastfunc;/* Name of last called function. */ - - struct bufferlist_s *bufferlist; /* To keep track of malloced buffers. */ - - unsigned int stacklen; /* Used size of the stack. */ - struct { - const unsigned char *buffer; /* Saved value of BUFFER. */ - size_t bufsize; /* Saved value of BUFSIZE. */ - size_t length; /* Length of the container (ti.length). */ - int in_ndef; /* Saved IN_NDEF flag (ti.ndef). */ - } stack[TLV_MAX_DEPTH]; -}; - - /* Parser communication object. */ struct p12_parse_ctx_s { @@ -225,11 +174,6 @@ struct p12_parse_ctx_s static int opt_verbose; -static unsigned char *cram_octet_string (const unsigned char *input, - size_t length, size_t *r_newlength); -static int need_octet_string_cramming (const unsigned char *input, - size_t length); - @@ -242,44 +186,6 @@ p12_set_verbosity (int verbose, int debug) } -#define dump_tag_info(a,b) _dump_tag_info ((a),__LINE__,(b)) -static void -_dump_tag_info (const char *text, int lno, struct tlv_ctx_s *tlv) -{ - struct tag_info *ti; - - if (opt_verbose < 2) - return; - - ti = &tlv->ti; - - log_debug ("p12_parse:%s:%d: @%04zu class=%d tag=%lu len=%zu nhdr=%zu %s%s\n", - text, lno, - (size_t)(tlv->buffer - tlv->origbuffer) - ti->nhdr, - ti->class, ti->tag, ti->length, ti->nhdr, - ti->is_constructed?" cons":"", - ti->ndef?" ndef":""); -} - - -#define dump_tlv_ctx(a,b,c) _dump_tlv_ctx ((a),(b),__LINE__,(c)) -static void -_dump_tlv_ctx (const char *text, const char *text2, - int lno, struct tlv_ctx_s *tlv) -{ - if (opt_verbose < 2) - return; - - log_debug ("p12_parse:%s%s%s:%d: @%04zu lvl=%u %s\n", - text, - text2? "/":"", text2? text2:"", - lno, - (size_t)(tlv->buffer - tlv->origbuffer), - tlv->stacklen, - tlv->in_ndef? " in-ndef":""); -} - - static int digest_algo_from_oid (unsigned char const *oid, size_t oidlen) { @@ -398,638 +304,6 @@ builder_add_mpi (tlv_builder_t tb, int class, int tag, gcry_mpi_t mpi, } - -/* Parse the buffer at the address BUFFER which is of SIZE and return - * the tag and the length part from the TLV triplet. Update BUFFER - * and SIZE on success. Checks that the encoded length does not - * exhaust the length of the provided buffer. */ -static int -parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti) -{ - gpg_error_t err; - int tag; - - err = parse_ber_header (buffer, size, - &ti->class, &tag, - &ti->is_constructed, &ti->ndef, - &ti->length, &ti->nhdr); - if (err) - return err; - if (tag < 0) - return gpg_error (GPG_ERR_EOVERFLOW); - ti->tag = tag; - - if (ti->length > *size) - return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); /* data larger than buffer. */ - - return 0; -} - - -/* Create a new TLV object. */ -static struct tlv_ctx_s * -tlv_new (const unsigned char *buffer, size_t bufsize) -{ - struct tlv_ctx_s *tlv; - tlv = xtrycalloc (1, sizeof *tlv); - if (tlv) - { - tlv->origbuffer = buffer; - tlv->origbufsize = bufsize; - tlv->buffer = buffer; - tlv->bufsize = bufsize; - } - return tlv; -} - - -/* This function can be used to store a malloced buffer into the TLV - * object. Ownership of BUFFER is thus transferred to TLV. This - * buffer will then only be released by tlv_release. */ -static gpg_error_t -tlv_register_buffer (struct tlv_ctx_s *tlv, char *buffer) -{ - struct bufferlist_s *item; - - item = xtrycalloc (1, sizeof *item); - if (!item) - return gpg_error_from_syserror (); - item->buffer = buffer; - item->next = tlv->bufferlist; - tlv->bufferlist = item; - return 0; -} - - -static void -tlv_release (struct tlv_ctx_s *tlv) -{ - if (!tlv) - return; - while (tlv->bufferlist) - { - struct bufferlist_s *save = tlv->bufferlist->next; - xfree (tlv->bufferlist->buffer); - xfree (tlv->bufferlist); - tlv->bufferlist = save; - } - xfree (tlv); -} - - -/* Helper for the tlv_peek functions. */ -static gpg_error_t -_tlv_peek (struct tlv_ctx_s *tlv, struct tag_info *ti) -{ - const unsigned char *p; - size_t n; - - /* Note that we want to peek ahead of any current container but of - * course not beyond our entire buffer. */ - p = tlv->buffer; - if ((p - tlv->origbuffer) > tlv->origbufsize) - return gpg_error (GPG_ERR_BUG); - n = tlv->origbufsize - (p - tlv->origbuffer); - return parse_tag (&p, &n, ti); -} - - -/* Look for the next tag and return true if it matches CLASS and TAG. - * Otherwise return false. No state is changed. */ -static int -tlv_peek (struct tlv_ctx_s *tlv, int class, int tag) -{ - struct tag_info ti; - - return (!_tlv_peek (tlv, &ti) - && ti.class == class && ti.tag == tag); -} - - -/* Look for the next tag and return true if it is the Null tag. - * Otherwise return false. No state is changed. */ -static int -tlv_peek_null (struct tlv_ctx_s *tlv) -{ - struct tag_info ti; - - return (!_tlv_peek (tlv, &ti) - && ti.class == CLASS_UNIVERSAL && ti.tag == TAG_NULL - && !ti.is_constructed && !ti.length); -} - - -/* Helper for tlv_expect_sequence and tlv_expect_context_tag. */ -static gpg_error_t -_tlv_push (struct tlv_ctx_s *tlv) -{ - /* Right now our pointer is at the value of the current container. - * We push that info onto the stack. */ - if (tlv->stacklen >= TLV_MAX_DEPTH) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_MANY)); - tlv->stack[tlv->stacklen].buffer = tlv->buffer; - tlv->stack[tlv->stacklen].bufsize = tlv->bufsize; - tlv->stack[tlv->stacklen].in_ndef = tlv->in_ndef; - tlv->stack[tlv->stacklen].length = tlv->ti.length; - tlv->stacklen++; - - tlv->in_ndef = tlv->ti.ndef; - - /* We set the size of the buffer to the TLV length if it is known or - * else to the size of the remaining entire buffer. */ - if (tlv->in_ndef) - { - if ((tlv->buffer - tlv->origbuffer) > tlv->origbufsize) - return (tlv->lasterr = gpg_error (GPG_ERR_BUG)); - tlv->bufsize = tlv->origbufsize - (tlv->buffer - tlv->origbuffer); - } - else - tlv->bufsize = tlv->ti.length; - - dump_tlv_ctx (__func__, NULL, tlv); - return 0; -} - - -/* Helper for tlv_next. */ -static gpg_error_t -_tlv_pop (struct tlv_ctx_s *tlv) -{ - size_t lastlen; - - /* We reached the end of a container, either due to the size limit - * or due to an end tag. Now we pop the last container so that we - * are positioned at the value of the last container. */ - if (!tlv->stacklen) - return gpg_error (GPG_ERR_EOF); - - tlv->stacklen--; - tlv->in_ndef = tlv->stack[tlv->stacklen].in_ndef; - if (tlv->in_ndef) - { - /* We keep buffer but adjust bufsize to the end of the origbuffer. */ - if ((tlv->buffer - tlv->origbuffer) > tlv->origbufsize) - return (tlv->lasterr = gpg_error (GPG_ERR_BUG)); - tlv->bufsize = tlv->origbufsize - (tlv->buffer - tlv->origbuffer); - } - else - { - lastlen = tlv->stack[tlv->stacklen].length; - tlv->buffer = tlv->stack[tlv->stacklen].buffer; - tlv->bufsize = tlv->stack[tlv->stacklen].bufsize; - if (lastlen > tlv->bufsize) - { - log_debug ("%s: container length larger than buffer (%zu/%zu)\n", - __func__, lastlen, tlv->bufsize); - return gpg_error (GPG_ERR_INV_BER); - } - tlv->buffer += lastlen; - tlv->bufsize -= lastlen; - } - - dump_tlv_ctx (__func__, NULL, tlv); - return 0; -} - - -/* Parse the next tag and value. Also detect the end of a - * container. */ -#define tlv_next(a) _tlv_next ((a), __LINE__) -static gpg_error_t -_tlv_next (struct tlv_ctx_s *tlv, int lno) -{ - gpg_error_t err; - - tlv->lasterr = 0; - tlv->lastfunc = __func__; - - if (tlv->pending) - { - tlv->pending = 0; - if (opt_verbose > 1) - log_debug ("%s: tlv_next skipped\n", __func__); - return 0; - } - - if (opt_verbose > 1) - log_debug ("%s: tlv_next called\n", __func__); - /* If we are at the end of an ndef container pop the stack. */ - if (!tlv->in_ndef && !tlv->bufsize) - { - do - err = _tlv_pop (tlv); - while (!err && !tlv->in_ndef && !tlv->bufsize); - if (err) - return (tlv->lasterr = err); - if (opt_verbose > 1) - log_debug ("%s: container(s) closed due to size\n", __func__); - } - - again: - /* Get the next tag. */ - err = parse_tag (&tlv->buffer, &tlv->bufsize, &tlv->ti); - if (err) - { - if (opt_verbose > 1) - log_debug ("%s: reading tag returned err=%d\n", __func__, err); - return err; - } - - /* If there is an end tag in an ndef container pop the stack. Also - * pop other containers which are fully consumed. */ - if (tlv->in_ndef && (tlv->ti.class == CLASS_UNIVERSAL - && !tlv->ti.tag && !tlv->ti.is_constructed)) - { - do - err = _tlv_pop (tlv); - while (!err && !tlv->in_ndef && !tlv->bufsize); - if (err) - return (tlv->lasterr = err); - if (opt_verbose > 1) - log_debug ("%s: container(s) closed due to end tag\n", __func__); - goto again; - } - - _dump_tag_info (__func__, lno, tlv); - return 0; -} - - -/* Return the current neting level of the TLV object. */ -static unsigned int -tlv_level (struct tlv_ctx_s *tlv) -{ - return tlv->stacklen; -} - - -/* Set a flag to indicate that the last tlv_next has not yet been - * consumed. */ -static void -tlv_set_pending (struct tlv_ctx_s *tlv) -{ - tlv->pending = 1; -} - - -/* Skip over the value of the current tag. Does not yet work for ndef - * containers. */ -static void -tlv_skip (struct tlv_ctx_s *tlv) -{ - tlv->lastfunc = __func__; - log_assert (tlv->bufsize >= tlv->ti.length); - tlv->buffer += tlv->ti.length; - tlv->bufsize -= tlv->ti.length; -} - - -/* Expect that the current tag is a sequence and setup the context for - * processing. */ -static gpg_error_t -tlv_expect_sequence (struct tlv_ctx_s *tlv) -{ - tlv->lastfunc = __func__; - if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_SEQUENCE - && tlv->ti.is_constructed)) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - return _tlv_push (tlv); -} - - -/* Expect that the current tag is a context tag and setup the context - * for processing. The tag of the context is returned at R_TAG. */ -static gpg_error_t -tlv_expect_context_tag (struct tlv_ctx_s *tlv, int *r_tag) -{ - tlv->lastfunc = __func__; - if (!(tlv->ti.class == CLASS_CONTEXT && tlv->ti.is_constructed)) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - *r_tag = tlv->ti.tag; - return _tlv_push (tlv); -} - - -/* Expect that the current tag is a SET and setup the context for - * processing. */ -static gpg_error_t -tlv_expect_set (struct tlv_ctx_s *tlv) -{ - tlv->lastfunc = __func__; - if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_SET - && tlv->ti.is_constructed)) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - return _tlv_push (tlv); -} - - -/* Expect an object of CLASS with TAG and store its value at - * (R_DATA,R_DATALEN). Then skip over its value to the next tag. - * Note that the stored value is not allocated but points into - * TLV. */ -static gpg_error_t -tlv_expect_object (struct tlv_ctx_s *tlv, int class, int tag, - unsigned char const **r_data, size_t *r_datalen) -{ - gpg_error_t err; - const unsigned char *p; - size_t n; - int needpush = 0; - - tlv->lastfunc = __func__; - if (!(tlv->ti.class == class && tlv->ti.tag == tag)) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer; - n = tlv->ti.length; - if (!n && tlv->ti.ndef) - { - n = tlv->bufsize; - needpush = 1; - } - else if (!tlv->ti.length) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - - if (class == CLASS_CONTEXT && tag == 0 && tlv->ti.is_constructed - && need_octet_string_cramming (p, n)) - { - char *newbuffer; - - newbuffer = cram_octet_string (p, n, r_datalen); - if (!newbuffer) - return (tlv->lasterr = gpg_error (GPG_ERR_BAD_BER)); - err = tlv_register_buffer (tlv, newbuffer); - if (err) - { - xfree (newbuffer); - return (tlv->lasterr = err); - } - *r_data = newbuffer; - } - else - { - *r_data = p; - *r_datalen = n; - } - if (needpush) - return _tlv_push (tlv); - - if (!(tlv->bufsize >= tlv->ti.length)) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - tlv->buffer += tlv->ti.length; - tlv->bufsize -= tlv->ti.length; - return 0; -} - - -/* Expect that the current tag is an object string and store its value - * at (R_DATA,R_DATALEN). Then skip over its value to the next tag. - * Note that the stored value are not allocated but point into TLV. - * If ENCAPSULATES is set the octet string is used as a new - * container. R_DATA and R_DATALEN are optional. */ -static gpg_error_t -tlv_expect_octet_string (struct tlv_ctx_s *tlv, int encapsulates, - unsigned char const **r_data, size_t *r_datalen) -{ - gpg_error_t err; - const unsigned char *p; - size_t n; - - tlv->lastfunc = __func__; - if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_OCTET_STRING - && (!tlv->ti.is_constructed || encapsulates))) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer; - if (!(n=tlv->ti.length) && !tlv->ti.ndef) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - - if (encapsulates && tlv->ti.is_constructed - && need_octet_string_cramming (p, n)) - { - char *newbuffer; - - newbuffer = cram_octet_string (p, n, r_datalen); - if (!newbuffer) - return (tlv->lasterr = gpg_error (GPG_ERR_BAD_BER)); - err = tlv_register_buffer (tlv, newbuffer); - if (err) - { - xfree (newbuffer); - return (tlv->lasterr = err); - } - *r_data = newbuffer; - } - else - { - if (r_data) - *r_data = p; - if (r_datalen) - *r_datalen = tlv->ti.length; - } - if (encapsulates) - return _tlv_push (tlv); - - if (!(tlv->bufsize >= tlv->ti.length)) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - tlv->buffer += tlv->ti.length; - tlv->bufsize -= tlv->ti.length; - return 0; -} - - -/* Expect that the current tag is an integer and return its value at - * R_VALUE. Then skip over its value to the next tag. */ -static gpg_error_t -tlv_expect_integer (struct tlv_ctx_s *tlv, int *r_value) -{ - const unsigned char *p; - size_t n; - int value; - - tlv->lastfunc = __func__; - if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_INTEGER - && !tlv->ti.is_constructed)) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer; - if (!(n=tlv->ti.length)) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - - /* We currently support only positive values. */ - if ((*p & 0x80)) - return (tlv->lasterr = gpg_error (GPG_ERR_ERANGE)); - - for (value = 0; n; n--) - { - value <<= 8; - value |= (*p++) & 0xff; - if (value < 0) - return (tlv->lasterr = gpg_error (GPG_ERR_EOVERFLOW)); - } - *r_value = value; - if (!(tlv->bufsize >= tlv->ti.length)) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - tlv->buffer += tlv->ti.length; - tlv->bufsize -= tlv->ti.length; - return 0; -} - - -/* Variant of tlv_expect_integer which returns an MPI. If IGNORE_ZERO - * is set a value of 0 is ignored and R_VALUE not changed and the - * function returns GPG_ERR_FALSE. No check for negative encoded - * integers is doe because the old code here worked the same and we - * can't foreclose invalid encoded PKCS#12 stuff - after all it is - * PKCS#12 see https://www.cs.auckland.ac.nz/~pgut001/pubs/pfx.html */ -static gpg_error_t -tlv_expect_mpinteger (struct tlv_ctx_s *tlv, int ignore_zero, - gcry_mpi_t *r_value) -{ - const unsigned char *p; - size_t n; - - tlv->lastfunc = __func__; - if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_INTEGER - && !tlv->ti.is_constructed)) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer; - if (!(n=tlv->ti.length)) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - - if (!(tlv->bufsize >= tlv->ti.length)) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - tlv->buffer += tlv->ti.length; - tlv->bufsize -= tlv->ti.length; - if (ignore_zero && n == 1 && !*p) - return gpg_error (GPG_ERR_FALSE); - - return gcry_mpi_scan (r_value, GCRYMPI_FMT_USG, p, n, NULL); -} - - -/* Expect that the current tag is an object id and store its value at - * (R_OID,R_OIDLEN). Then skip over its value to the next tag. Note - * that the stored value is not allocated but points into TLV. */ -static gpg_error_t -tlv_expect_object_id (struct tlv_ctx_s *tlv, - unsigned char const **r_oid, size_t *r_oidlen) -{ - const unsigned char *p; - size_t n; - - tlv->lastfunc = __func__; - if (!(tlv->ti.class == CLASS_UNIVERSAL && tlv->ti.tag == TAG_OBJECT_ID - && !tlv->ti.is_constructed)) - return (tlv->lasterr = gpg_error (GPG_ERR_INV_OBJ)); - p = tlv->buffer; - if (!(n=tlv->ti.length)) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - - *r_oid = p; - *r_oidlen = tlv->ti.length; - if (!(tlv->bufsize >= tlv->ti.length)) - return (tlv->lasterr = gpg_error (GPG_ERR_TOO_SHORT)); - tlv->buffer += tlv->ti.length; - tlv->bufsize -= tlv->ti.length; - return 0; -} - - - -/* Given an ASN.1 chunk of a structure like: - * - * 24 NDEF: OCTET STRING -- This is not passed to us - * 04 1: OCTET STRING -- INPUT point s to here - * : 30 - * 04 1: OCTET STRING - * : 80 - * [...] - * 04 2: OCTET STRING - * : 00 00 - * : } -- This denotes a Null tag and are the last - * -- two bytes in INPUT. - * - * The example is from Mozilla Firefox 1.0.4 which actually exports - * certs as single byte chunks of octet strings. - * - * Create a new buffer with the content of that octet string. INPUT - * is the original buffer with a LENGTH. Returns - * NULL on error or a new malloced buffer with its actual used length - * stored at R_NEWLENGTH. */ -static unsigned char * -cram_octet_string (const unsigned char *input, size_t length, - size_t *r_newlength) -{ - const unsigned char *s = input; - size_t n = length; - unsigned char *output, *d; - struct tag_info ti; - - /* Allocate output buf. We know that it won't be longer than the - input buffer. */ - d = output = gcry_malloc (length); - if (!output) - goto bailout; - - while (n) - { - if (parse_tag (&s, &n, &ti)) - goto bailout; - if (ti.class == CLASS_UNIVERSAL && ti.tag == TAG_OCTET_STRING - && !ti.ndef && !ti.is_constructed) - { - memcpy (d, s, ti.length); - s += ti.length; - d += ti.length; - n -= ti.length; - } - else if (ti.class == CLASS_UNIVERSAL && !ti.tag && !ti.is_constructed) - break; /* Ready */ - else - goto bailout; - } - - - *r_newlength = d - output; - return output; - - bailout: - gcry_free (output); - return NULL; -} - - -/* Return true if (INPUT,LENGTH) is a structure which should be passed - * to cram_octet_string. This is basically the same loop as in - * cram_octet_string but without any actual copying. */ -static int -need_octet_string_cramming (const unsigned char *input, size_t length) -{ - const unsigned char *s = input; - size_t n = length; - struct tag_info ti; - - if (!length) - return 0; - - while (n) - { - if (parse_tag (&s, &n, &ti)) - return 0; - if (ti.class == CLASS_UNIVERSAL && ti.tag == TAG_OCTET_STRING - && !ti.ndef && !ti.is_constructed) - { - s += ti.length; - n -= ti.length; - } - else if (ti.class == CLASS_UNIVERSAL && !ti.tag && !ti.is_constructed) - break; /* Ready */ - else - return 0; - } - - return 1; -} - - static int string_to_key (int id, char *salt, size_t saltlen, int iter, const char *pw, int req_keylen, unsigned char *keybuf) @@ -1379,11 +653,11 @@ bag_decrypted_data_p (const void *plaintext, size_t length) } #endif /*ENABLE_DER_STRUCT_DUMPING*/ - if (parse_tag (&p, &n, &ti)) + if (tlv_parse_tag (&p, &n, &ti)) return 0; if (ti.class || ti.tag != TAG_SEQUENCE) return 0; - if (parse_tag (&p, &n, &ti)) + if (tlv_parse_tag (&p, &n, &ti)) return 0; return 1; @@ -1391,7 +665,7 @@ bag_decrypted_data_p (const void *plaintext, size_t length) static int -parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) +parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) { gpg_error_t err = 0; const char *where; @@ -1510,13 +784,13 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; if (tlv_expect_sequence (tlv)) goto bailout; - parmlen = tlv->ti.length; + parmlen = tlv_parser_tag_length (tlv, 0); if (tlv_next (tlv)) goto bailout; if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; - parmlen -= tlv->ti.length + tlv->ti.nhdr; + parmlen -= tlv_parser_tag_length (tlv, 1); if (datalen < 8 || datalen > sizeof salt) { log_info ("bad length of salt (%zu)\n", datalen); @@ -1530,7 +804,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; if ((err = tlv_expect_integer (tlv, &intval))) goto bailout; - parmlen -= tlv->ti.length + tlv->ti.nhdr; + parmlen -= tlv_parser_tag_length (tlv, 1); if (!intval) /* Not a valid iteration count. */ { err = gpg_error (GPG_ERR_INV_VALUE); @@ -1667,7 +941,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) /* We do not need the TLV anymore and allocated a new one. */ where = "bag.encryptedData.decrypted-text"; - tlv = tlv_new (plain, datalen); + tlv = tlv_parser_new (plain, datalen, opt_verbose); if (!tlv) { err = gpg_error_from_syserror (); @@ -1688,8 +962,8 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) /* Loop over all certificates inside the bag. */ loopcount = 0; - startlevel = tlv_level (tlv); - while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) + startlevel = tlv_parser_level (tlv); + while (!(err = tlv_next (tlv)) && tlv_parser_level (tlv) == startlevel) { int iscrlbag = 0; int iskeybag = 0; @@ -1802,8 +1076,8 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) where = "reading.keybag.key-parameters"; keyelem_count = 0; - startlevel2 = tlv_level (tlv); - while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel2) + startlevel2 = tlv_parser_level (tlv); + while (!(err = tlv_next (tlv)) && tlv_parser_level (tlv) == startlevel2) { if (keyelem_count >= 9) { @@ -1826,7 +1100,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) keyelem_count++; } if (!err) - tlv_set_pending (tlv); + tlv_parser_set_pending (tlv); else if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; err = 0; @@ -1883,13 +1157,13 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) err = tlv_expect_set (tlv); if (err) goto bailout; - tlv_skip (tlv); + tlv_parser_skip (tlv); if (opt_verbose) log_info ("skipping %s\n", where); } } if (!err) - tlv_set_pending (tlv); + tlv_parser_set_pending (tlv); else if (err && gpg_err_code (err) != GPG_ERR_EOF) { if (!loopcount) /* The first while(tlv_next) failed. */ @@ -1900,7 +1174,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) leave: if (renewed_tlv) - tlv_release (tlv); + tlv_parser_release (tlv); gcry_free (plain); if (ctx->badpass) { @@ -1916,9 +1190,9 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) err = gpg_error (GPG_ERR_GENERAL); log_error ("%s(%s): lvl=%u (%s): %s - %s\n", __func__, where, - tlv? tlv->stacklen : 0, - tlv? tlv->lastfunc : "", - tlv ? gpg_strerror (tlv->lasterr) : "init failed", + tlv_parser_level (tlv), + tlv_parser_lastfunc (tlv), + tlv_parser_lasterrstr (tlv), gpg_strerror (err)); goto leave; } @@ -1943,9 +1217,9 @@ bag_data_p (const void *plaintext, size_t length) } #endif /*ENABLE_DER_STRUCT_DUMPING*/ - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) + if (tlv_parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_SEQUENCE) return 0; - if (parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER + if (tlv_parse_tag (&p, &n, &ti) || ti.class || ti.tag != TAG_INTEGER || ti.length != 1 || *p) return 0; @@ -1954,7 +1228,7 @@ bag_data_p (const void *plaintext, size_t length) static gpg_error_t -parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) +parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) { gpg_error_t err = 0; const char *where; @@ -1967,7 +1241,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) size_t saltlen; char iv[16]; unsigned int iter; - struct tlv_ctx_s *saved_tlv = NULL; + tlv_parser_t saved_tlv = NULL; int renewed_tlv = 0; /* True if the TLV must be released. */ unsigned char *plain = NULL; int is_pbes2 = 0; @@ -2039,13 +1313,13 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; if (tlv_expect_sequence (tlv)) goto bailout; - parmlen = tlv->ti.length; + parmlen = tlv_parser_tag_length (tlv, 0); if (tlv_next (tlv)) goto bailout; if (tlv_expect_octet_string (tlv, 0, &data, &datalen)) goto bailout; - parmlen -= tlv->ti.length + tlv->ti.nhdr; + parmlen -= tlv_parser_tag_length (tlv, 1); if (datalen < 8 || datalen > sizeof salt) { log_info ("bad length of salt (%zu) for AES\n", datalen); @@ -2059,7 +1333,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) goto bailout; if ((err = tlv_expect_integer (tlv, &intval))) goto bailout; - parmlen -= tlv->ti.length + tlv->ti.nhdr; + parmlen -= tlv_parser_tag_length (tlv, 1); if (!intval) /* Not a valid iteration count. */ { err = gpg_error (GPG_ERR_INV_VALUE); @@ -2193,7 +1467,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) /* We do not need the TLV anymore and allocated a new one. */ where = "shrouded_key_bag.decrypted-text"; saved_tlv = tlv; - tlv = tlv_new (plain, datalen); + tlv = tlv_parser_new (plain, datalen, opt_verbose); if (!tlv) { err = gpg_error_from_syserror (); @@ -2336,9 +1610,9 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) { int keyelem_count = 0; int firstparam = 1; - unsigned int startlevel = tlv_level (tlv); + unsigned int startlevel = tlv_parser_level (tlv); - while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) + while (!(err = tlv_next (tlv)) && tlv_parser_level (tlv) == startlevel) { if (keyelem_count >= 9) { @@ -2365,7 +1639,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) firstparam = 0; } if (!err) - tlv_set_pending (tlv); + tlv_parser_set_pending (tlv); else if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; err = 0; @@ -2373,7 +1647,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) if (opt_verbose > 1) log_debug ("restoring parser context\n"); - tlv_release (tlv); + tlv_parser_release (tlv); renewed_tlv = 0; tlv = saved_tlv; @@ -2386,7 +1660,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) err = tlv_expect_set (tlv); if (err) goto bailout; - tlv_skip (tlv); + tlv_parser_skip (tlv); if (opt_verbose) log_info ("skipping %s\n", where); } @@ -2396,7 +1670,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) gcry_free (plain); if (renewed_tlv) { - tlv_release (tlv); + tlv_parser_release (tlv); if (opt_verbose > 1) log_debug ("parser context released\n"); } @@ -2405,18 +1679,18 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) bailout: if (!err) err = gpg_error (GPG_ERR_GENERAL); - log_error ("%s(%s): lvl=%d (%s): %s - %s\n", + log_error ("%s(%s): lvl=%u (%s): %s - %s\n", __func__, where, - tlv? tlv->stacklen : 0, - tlv? tlv->lastfunc : "", - tlv ? gpg_strerror (tlv->lasterr) : "init failed", + tlv_parser_level (tlv), + tlv_parser_lastfunc (tlv), + tlv_parser_lasterrstr (tlv), gpg_strerror (err)); goto leave; } static gpg_error_t -parse_cert_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) +parse_cert_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) { gpg_error_t err = 0; const char *where; @@ -2491,7 +1765,7 @@ parse_cert_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) err = tlv_expect_set (tlv); if (err) goto bailout; - tlv_skip (tlv); + tlv_parser_skip (tlv); if (opt_verbose) log_info ("skipping %s\n", where); } @@ -2503,9 +1777,9 @@ parse_cert_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) bailout: log_error ("%s(%s): lvl=%u (%s): %s - %s\n", __func__, where, - tlv? tlv->stacklen : 0, - tlv? tlv->lastfunc : "", - tlv ? gpg_strerror (tlv->lasterr) : "init failed", + tlv_parser_level (tlv), + tlv_parser_lastfunc (tlv), + tlv_parser_lasterrstr (tlv), gpg_strerror (err)); if (!err) err = gpg_error (GPG_ERR_GENERAL); @@ -2514,7 +1788,7 @@ parse_cert_bag (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) static gpg_error_t -parse_bag_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) +parse_bag_data (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) { gpg_error_t err = 0; const char *where; @@ -2559,9 +1833,9 @@ parse_bag_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) if (tlv_expect_sequence (tlv)) goto bailout; - startlevel = tlv_level (tlv); - dump_tlv_ctx ("data.outerseqs", "beginloop", tlv); - while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) + startlevel = tlv_parser_level (tlv); + tlv_parser_dump_state ("data.outerseqs", "beginloop", tlv); + while (!(err = tlv_next (tlv)) && tlv_parser_level (tlv) == startlevel) { /* Expect: * SEQUENCE @@ -2595,13 +1869,13 @@ parse_bag_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) } else { - tlv_skip (tlv); + tlv_parser_skip (tlv); log_info ("unknown inner data type - skipped\n"); } } - dump_tlv_ctx ("data.outerseqs", "endloop", tlv); + tlv_parser_dump_state ("data.outerseqs", "endloop", tlv); if (!err) - tlv_set_pending (tlv); + tlv_parser_set_pending (tlv); else if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; err = 0; @@ -2612,11 +1886,11 @@ parse_bag_data (struct p12_parse_ctx_s *ctx, struct tlv_ctx_s *tlv) bailout: if (!err) err = gpg_error (GPG_ERR_GENERAL); - log_error ("%s(%s): lvl=%d (%s): %s - %s\n", + log_error ("%s(%s): lvl=%u (%s): %s - %s\n", __func__, where, - tlv? tlv->stacklen : 0, - tlv? tlv->lastfunc : "", - tlv ? gpg_strerror (tlv->lasterr) : "init failed", + tlv_parser_level (tlv), + tlv_parser_lastfunc (tlv), + tlv_parser_lasterrstr (tlv), gpg_strerror (err)); goto leave; } @@ -2636,7 +1910,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, { gpg_error_t err; const char *where = ""; - struct tlv_ctx_s *tlv; + tlv_parser_t tlv; struct p12_parse_ctx_s ctx = { NULL }; const unsigned char *oid; size_t oidlen; @@ -2649,7 +1923,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, ctx.certcbarg = certcbarg; ctx.password = pw; - tlv = tlv_new (buffer, length); + tlv = tlv_parser_new (buffer, length, opt_verbose); if (!tlv) { err = gpg_error_from_syserror (); @@ -2706,12 +1980,12 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, if (tlv_expect_sequence (tlv)) goto bailout; - startlevel = tlv_level (tlv); - dump_tlv_ctx ("bags", "beginloop", tlv); - while (!(err = tlv_next (tlv)) && tlv_level (tlv) == startlevel) + startlevel = tlv_parser_level (tlv); + tlv_parser_dump_state ("bags", "beginloop", tlv); + while (!(err = tlv_next (tlv)) && tlv_parser_level (tlv) == startlevel) { where = "bag-sequence"; - dump_tlv_ctx (where, NULL, tlv); + tlv_parser_dump_state (where, NULL, tlv); if (tlv_expect_sequence (tlv)) goto bailout; @@ -2744,18 +2018,18 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, } else { - tlv_skip (tlv); + tlv_parser_skip (tlv); log_info ("unknown outer bag type - skipped\n"); } } - dump_tlv_ctx ("bags", "endloop", tlv); + tlv_parser_dump_state ("bags", "endloop", tlv); if (!err) - tlv_set_pending (tlv); + tlv_parser_set_pending (tlv); else if (err && gpg_err_code (err) != GPG_ERR_EOF) goto bailout; err = 0; - tlv_release (tlv); + tlv_parser_release (tlv); if (r_curve) *r_curve = ctx.curve; else @@ -2767,10 +2041,10 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, *r_badpass = ctx.badpass; log_error ("%s(%s): @%04zu lvl=%u %s: %s - %s\n", __func__, where, - tlv? (size_t)(tlv->buffer - tlv->origbuffer):0, - tlv? tlv->stacklen : 0, - tlv? tlv->lastfunc : "", - tlv? gpg_strerror (tlv->lasterr) : "init failed", + tlv_parser_offset (tlv), + tlv_parser_level (tlv), + tlv_parser_lastfunc (tlv), + tlv_parser_lasterrstr (tlv), gpg_strerror (err)); if (ctx.privatekey) { @@ -2781,7 +2055,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, gcry_free (ctx.privatekey); ctx.privatekey = NULL; } - tlv_release (tlv); + tlv_parser_release (tlv); gcry_free (ctx.curve); if (r_curve) *r_curve = NULL; From 97708e2ac72253fa1ddbcde63b23095ac2d1604f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 24 Oct 2023 14:22:05 +0200 Subject: [PATCH 228/869] sm: Flag Brainpool curves as compliant. * sm/keylist.c (print_compliance_flags): Add arg curve. (list_cert_colon): Pass curve to the compliance check. -- GnuPG-bug-id: 6253 --- sm/keylist.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sm/keylist.c b/sm/keylist.c index d6eccfc45..e84eb31d3 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -430,7 +430,7 @@ email_kludge (const char *name) * number. NBITS is the length of the key in bits. */ static void print_compliance_flags (ksba_cert_t cert, int algo, unsigned int nbits, - estream_t fp) + const char *curvename, estream_t fp) { int indent = 0; int hashalgo; @@ -438,7 +438,7 @@ print_compliance_flags (ksba_cert_t cert, int algo, unsigned int nbits, /* 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)) + if (gnupg_pk_is_compliant (CO_DE_VS, algo, 0, NULL, nbits, curvename)) { hashalgo = gcry_md_map_name (ksba_cert_get_digest_algo (cert)); if (gnupg_digest_is_compliant (CO_DE_VS, hashalgo)) @@ -629,7 +629,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, if (curve) es_fputs (curve, fp); es_putc (':', fp); /* End of field 17. */ - print_compliance_flags (cert, algo, nbits, fp); + print_compliance_flags (cert, algo, nbits, curve, fp); es_putc (':', fp); /* End of field 18. */ es_putc ('\n', fp); From 2c3c049fd8a001dc9937e5ac3884831b6e25d2da Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 24 Oct 2023 14:51:16 +0200 Subject: [PATCH 229/869] sm: Flag Brainpool curves as compliant for all other operations. * sm/fingerprint.c (gpgsm_get_key_algo_info2): Rename to (gpgsm_get_key_algo_info): this. Remove the old wrapper. Adjust all callers. * sm/decrypt.c (gpgsm_decrypt): Pass the curve to the compliance checker. * sm/encrypt.c (gpgsm_encrypt): Ditto. * sm/sign.c (gpgsm_sign): Ditto. * sm/verify.c (gpgsm_verify): Ditto. -- GnuPG-bug-id: 6253 --- sm/decrypt.c | 9 ++++++--- sm/encrypt.c | 10 +++++++--- sm/export.c | 2 +- sm/fingerprint.c | 11 ++--------- sm/gpgsm.h | 5 ++--- sm/keylist.c | 2 +- sm/sign.c | 9 ++++++--- sm/verify.c | 4 ++-- 8 files changed, 27 insertions(+), 25 deletions(-) diff --git a/sm/decrypt.c b/sm/decrypt.c index 62983fe9c..787e2f5e6 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -1065,6 +1065,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) int recp; estream_t in_fp = NULL; struct decrypt_filter_parm_s dfparm; + char *curve = NULL; memset (&dfparm, 0, sizeof dfparm); @@ -1309,14 +1310,15 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) pkfpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); pkalgostr = gpgsm_pubkey_algo_string (cert, NULL); - pk_algo = gpgsm_get_key_algo_info (cert, &nbits); + xfree (curve); + pk_algo = gpgsm_get_key_algo_info (cert, &nbits, &curve); if (!opt.quiet) log_info (_("encrypted to %s key %s\n"), pkalgostr, pkfpr); /* Check compliance. */ if (!gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION, - pk_algo, 0, NULL, nbits, NULL)) + pk_algo, 0, NULL, nbits, curve)) { char kidstr[10+1]; @@ -1334,7 +1336,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) dfparm.is_de_vs = (dfparm.is_de_vs && gnupg_pk_is_compliant (CO_DE_VS, pk_algo, 0, - NULL, nbits, NULL)); + NULL, nbits, curve)); oops: if (rc) @@ -1512,6 +1514,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) log_error ("message decryption failed: %s <%s>\n", gpg_strerror (rc), gpg_strsource (rc)); } + xfree (curve); ksba_cms_release (cms); gnupg_ksba_destroy_reader (b64reader); gnupg_ksba_destroy_writer (b64writer); diff --git a/sm/encrypt.c b/sm/encrypt.c index 6e78a0620..024f48673 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -758,11 +758,12 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) unsigned char *encval; unsigned int nbits; int pk_algo; + char *curve = NULL; /* Check compliance. */ - pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits); + pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits, &curve); if (!gnupg_pk_is_compliant (opt.compliance, pk_algo, 0, - NULL, nbits, NULL)) + NULL, nbits, curve)) { char kidstr[10+1]; @@ -777,9 +778,12 @@ 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 * the key to gnupg_pk_is_compliant. */ if (compliant - && !gnupg_pk_is_compliant (CO_DE_VS, pk_algo, 0, NULL, nbits, NULL)) + && !gnupg_pk_is_compliant (CO_DE_VS, pk_algo, 0, NULL, nbits, curve)) compliant = 0; + xfree (curve); + curve = NULL; + rc = encrypt_dek (dek, cl->cert, pk_algo, &encval); if (rc) { diff --git a/sm/export.c b/sm/export.c index 54893b54d..a6ba40f5d 100644 --- a/sm/export.c +++ b/sm/export.c @@ -430,7 +430,7 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode) if (rawmode == 0) ctrl->pem_name = "PKCS12"; - else if (gpgsm_get_key_algo_info (cert, NULL) == GCRY_PK_ECC) + else if (gpgsm_get_key_algo_info (cert, NULL, NULL) == GCRY_PK_ECC) ctrl->pem_name = "EC PRIVATE KEY"; else if (rawmode == 1) ctrl->pem_name = "PRIVATE KEY"; diff --git a/sm/fingerprint.c b/sm/fingerprint.c index 5f3f6f51f..375a8647e 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -222,7 +222,7 @@ gpgsm_get_keygrip_hexstring (ksba_cert_t cert) * algorithm is used the name or OID of the curve is stored there; the * caller needs to free this value. */ int -gpgsm_get_key_algo_info2 (ksba_cert_t cert, unsigned int *nbits, char **r_curve) +gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits, char **r_curve) { gcry_sexp_t s_pkey; int rc; @@ -299,18 +299,11 @@ gpgsm_get_key_algo_info2 (ksba_cert_t cert, unsigned int *nbits, char **r_curve) } -int -gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits) -{ - return gpgsm_get_key_algo_info2 (cert, nbits, NULL); -} - - /* Return true if CERT is an ECC key. */ int gpgsm_is_ecc_key (ksba_cert_t cert) { - return GCRY_PK_ECC == gpgsm_get_key_algo_info2 (cert, NULL, NULL); + return GCRY_PK_ECC == gpgsm_get_key_algo_info (cert, NULL, NULL); } diff --git a/sm/gpgsm.h b/sm/gpgsm.h index a22327edc..684251fda 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -339,9 +339,8 @@ unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert, unsigned long *r_high); unsigned char *gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array); 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_info2 (ksba_cert_t cert, unsigned int *nbits, - char **r_curve); +int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits, + char **r_curve); int gpgsm_is_ecc_key (ksba_cert_t cert); char *gpgsm_pubkey_algo_string (ksba_cert_t cert, int *r_algoid); gcry_mpi_t gpgsm_get_rsa_modulus (ksba_cert_t cert); diff --git a/sm/keylist.c b/sm/keylist.c index e84eb31d3..ed1b74729 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -562,7 +562,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, if (*truststring) es_fputs (truststring, fp); - algo = gpgsm_get_key_algo_info2 (cert, &nbits, &curve); + algo = gpgsm_get_key_algo_info (cert, &nbits, &curve); es_fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24); ksba_cert_get_validity (cert, 0, t); diff --git a/sm/sign.c b/sm/sign.c index 235dac8cb..c3781506d 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -640,6 +640,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, certlist_t cl; int release_signerlist = 0; int binary_detached = detached && !ctrl->create_pem && !ctrl->create_base64; + char *curve = NULL; audit_set_type (ctrl->audit, AUDIT_TYPE_SIGN); @@ -778,7 +779,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, unsigned int nbits; int pk_algo; - pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits); + xfree (curve); + pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits, &curve); cl->pk_algo = pk_algo; if (opt.forced_digest_algo) @@ -838,8 +840,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, goto leave; } - if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo, 0, - NULL, nbits, NULL)) + if (!gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo, 0, + NULL, nbits, curve)) { char kidstr[10+1]; @@ -1205,6 +1207,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, gpg_strerror (rc), gpg_strsource (rc) ); if (release_signerlist) gpgsm_release_certlist (signerlist); + xfree (curve); ksba_cms_release (cms); gnupg_ksba_destroy_writer (b64writer); keydb_release (kh); diff --git a/sm/verify.c b/sm/verify.c index c7f4492ce..1f5c1d378 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -468,7 +468,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) pkfpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); pkalgostr = gpgsm_pubkey_algo_string (cert, NULL); - pkalgo = gpgsm_get_key_algo_info2 (cert, &nbits, &pkcurve); + pkalgo = gpgsm_get_key_algo_info (cert, &nbits, &pkcurve); /* Remap the ECC algo to the algo we use. Note that EdDSA has * already been mapped. */ if (pkalgo == GCRY_PK_ECC) @@ -504,7 +504,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) /* Check compliance. */ if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION, - pkalgo, pkalgoflags, NULL, nbits, NULL)) + pkalgo, pkalgoflags, NULL, nbits, pkcurve)) { char kidstr[10+1]; From 164c687cb6a1cafe6c1c47456a1837046a3f00f1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 26 Oct 2023 09:59:40 +0200 Subject: [PATCH 230/869] common: New functions timegm_u64, isotime2epoch_u64. * common/mischelp.c (timegm): Move to ... * common/gettime.c (timegm): here. On Windows use timegm_u32. (timegm_u32): New. (isotime2epoch): Factor code out to ... (isotime_make_tm): new helper. (isotime2epoch_u64): New. (_win32_timegm): Remove duplicated code. (parse_timestamp): Use of timegm. (scan_isodatestr): Fallback to isotime2epoch_u64. -- This mainly helps on 32 bit Windows. For Unix we assume everyone is using 64 bit or shall wait until the libc hackers finally provide a time64_t. GnuPG-bug-id: 6736 --- common/gettime.c | 239 ++++++++++++++++++++++++++++++++-------------- common/gettime.h | 8 +- common/mischelp.c | 77 --------------- common/mischelp.h | 6 -- 4 files changed, 176 insertions(+), 154 deletions(-) diff --git a/common/gettime.c b/common/gettime.c index c3b0c6c6c..3f1ce0c5a 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -37,6 +37,10 @@ #ifdef HAVE_LANGINFO_H #include #endif +#ifdef HAVE_W32_SYSTEM +# define WIN32_LEAN_AND_MEAN +# include +#endif /*!HAVE_W32_SYSTEM*/ #include /* We use uint64_t. */ #include "util.h" @@ -62,6 +66,111 @@ static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode; #define JD_DIFF 1721060L + +/* + timegm() is a GNU function that might not be available everywhere. + It's basically the inverse of gmtime() - you give it a struct tm, + and get back a time_t. It differs from mktime() in that it handles + the case where the struct tm is UTC and the local environment isn't. + + Note, that this replacement implementation might not be thread-safe! + + Some BSDs don't handle the putenv("foo") case properly, so we use + unsetenv if the platform has it to remove environment variables. +*/ +#ifndef HAVE_TIMEGM +time_t +timegm (struct tm *tm) +{ +#ifdef HAVE_W32_SYSTEM + uint64_t val = timegm_u64 (tm); + if (val == (uint64_t)(-1)) + return (time_t)(-1); + return (time_t)val; +#else /* (Non thread safe implementation!) */ + + time_t answer; + char *zone; + + zone=getenv("TZ"); + putenv("TZ=UTC"); + tzset(); + answer=mktime(tm); + if(zone) + { + static char *old_zone; + + if (!old_zone) + { + old_zone = malloc(3+strlen(zone)+1); + if (old_zone) + { + strcpy(old_zone,"TZ="); + strcat(old_zone,zone); + } + } + if (old_zone) + putenv (old_zone); + } + else + gnupg_unsetenv("TZ"); + + tzset(); + return answer; +#endif +} +#endif /*!HAVE_TIMEGM*/ + + +/* Version of the GNU timegm which returns an unsigned 64 bit integer + * instead of the usually signed time_t. On error (uint64_t)(-1) is + * returned. This function is mostly here becuase on 32 bit Windows + * we have an internal API to get the system time even after + * 2023-01-19. For 32 bit Unix we need to suffer from the too short + * time_t and no system function to construct the time from a tm. */ +uint64_t +timegm_u64 (struct tm *tm) +{ +#ifdef HAVE_W32_SYSTEM + /* This one is thread safe. */ + SYSTEMTIME st; + FILETIME ft; + unsigned long long cnsecs; + + st.wYear = tm->tm_year + 1900; + st.wMonth = tm->tm_mon + 1; + st.wDay = tm->tm_mday; + st.wHour = tm->tm_hour; + st.wMinute = tm->tm_min; + st.wSecond = tm->tm_sec; + st.wMilliseconds = 0; /* Not available. */ + st.wDayOfWeek = 0; /* Ignored. */ + + /* System time is UTC thus the conversion is pretty easy. */ + if (!SystemTimeToFileTime (&st, &ft)) + { + gpg_err_set_errno (EINVAL); + return (uint64_t)(-1); + } + + cnsecs = (((unsigned long long)ft.dwHighDateTime << 32) + | ft.dwLowDateTime); + cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01. */ + return (uint64_t)(cnsecs / 10000000ULL); + +#else /*Unix*/ + + time_t t = timegm (tm); + if (t == (time_t)(-1)) + return (uint64_t)(-1); + if ((int64_t)t < 0) + return (uint64_t)(-1); + return (uint64_t)t; + +#endif /*Unix*/ +} + + /* Wrapper for the time(3). We use this here so we can fake the time for tests */ time_t @@ -231,7 +340,21 @@ scan_isodatestr( const char *string ) tmbuf.tm_isdst = -1; stamp = mktime( &tmbuf ); if( stamp == (time_t)-1 ) - return 0; + { + /* mktime did not work. Construct an ISO timestring for noon + * of the given day instead. We keep the use of mktime for 64 + * bit system to limit the risk of regressions. */ + gnupg_isotime_t isobuf; + uint64_t tmp64; + + snprintf (isobuf, 16, "%04d%02d%02dT120000", year, month, day); + tmp64 = isotime2epoch_u64 (isobuf); + if (tmp64 == (uint64_t)(-1)) + return 0; /* Error. */ + if (tmp64 >= (u32)(-1)) + return 0; /* Error. */ + return (u32)tmp64; + } return stamp; } @@ -386,18 +509,14 @@ string2isotime (gnupg_isotime_t atime, const char *string) } -/* Scan an ISO timestamp and return an Epoch based timestamp. The - only supported format is "yyyymmddThhmmss[Z]" delimited by white - space, nul, a colon or a comma. Returns (time_t)(-1) for an - invalid string. */ -time_t -isotime2epoch (const char *string) +/* Helper for isotime2epoch. Returns 0 on success. */ +static int +isotime_make_tm (const char *string, struct tm *tmbuf) { int year, month, day, hour, minu, sec; - struct tm tmbuf; if (!isotime_p (string)) - return (time_t)(-1); + return -1; year = atoi_4 (string); month = atoi_2 (string + 4); @@ -409,20 +528,48 @@ isotime2epoch (const char *string) /* Basic checks. */ if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || hour > 23 || minu > 59 || sec > 61 ) + return -1; + + memset (tmbuf, 0, sizeof *tmbuf); + tmbuf->tm_sec = sec; + tmbuf->tm_min = minu; + tmbuf->tm_hour = hour; + tmbuf->tm_mday = day; + tmbuf->tm_mon = month-1; + tmbuf->tm_year = year - 1900; + tmbuf->tm_isdst = -1; + return 0; +} + + +/* Scan an ISO timestamp and return an Epoch based timestamp. The + only supported format is "yyyymmddThhmmss[Z]" delimited by white + space, nul, a colon or a comma. Returns (time_t)(-1) for an + invalid string. */ +time_t +isotime2epoch (const char *string) +{ + struct tm tmbuf; + + if (isotime_make_tm (string, &tmbuf)) return (time_t)(-1); - memset (&tmbuf, 0, sizeof tmbuf); - tmbuf.tm_sec = sec; - tmbuf.tm_min = minu; - tmbuf.tm_hour = hour; - tmbuf.tm_mday = day; - tmbuf.tm_mon = month-1; - tmbuf.tm_year = year - 1900; - tmbuf.tm_isdst = -1; return timegm (&tmbuf); } +uint64_t +isotime2epoch_u64 (const char *string) +{ + struct tm tmbuf; + + if (isotime_make_tm (string, &tmbuf)) + return (uint64_t)(-1); + + return timegm_u64 (&tmbuf); +} + + /* Convert an Epoch time to an iso time stamp. */ void epoch2isotime (gnupg_isotime_t timebuf, time_t atime) @@ -476,41 +623,6 @@ isodate_human_to_tm (const char *string, struct tm *t) } -/* This function is a copy of gpgme/src/conversion.c:_gpgme_timegm. - If you change it, then update the other one too. */ -#ifdef HAVE_W32_SYSTEM -static time_t -_win32_timegm (struct tm *tm) -{ - /* This one is thread safe. */ - SYSTEMTIME st; - FILETIME ft; - unsigned long long cnsecs; - - st.wYear = tm->tm_year + 1900; - st.wMonth = tm->tm_mon + 1; - st.wDay = tm->tm_mday; - st.wHour = tm->tm_hour; - st.wMinute = tm->tm_min; - st.wSecond = tm->tm_sec; - st.wMilliseconds = 0; /* Not available. */ - st.wDayOfWeek = 0; /* Ignored. */ - - /* System time is UTC thus the conversion is pretty easy. */ - if (!SystemTimeToFileTime (&st, &ft)) - { - gpg_err_set_errno (EINVAL); - return (time_t)(-1); - } - - cnsecs = (((unsigned long long)ft.dwHighDateTime << 32) - | ft.dwLowDateTime); - cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01. */ - return (time_t)(cnsecs / 10000000ULL); -} -#endif - - /* Parse the string TIMESTAMP into a time_t. The string may either be seconds since Epoch or in the ISO 8601 format like "20390815T143012". Returns 0 for an empty string or seconds since @@ -519,7 +631,11 @@ _win32_timegm (struct tm *tm) This function is a copy of gpgme/src/conversion.c:_gpgme_parse_timestamp. If you change it, - then update the other one too. */ + then update the other one too. + + FIXME: Replace users of this function by one of the more modern + functions or change the return type to u64. +*/ time_t parse_timestamp (const char *timestamp, char **endp) { @@ -555,24 +671,7 @@ parse_timestamp (const char *timestamp, char **endp) buf.tm_min = atoi_2 (timestamp+11); buf.tm_sec = atoi_2 (timestamp+13); -#ifdef HAVE_W32_SYSTEM - return _win32_timegm (&buf); -#else -#ifdef HAVE_TIMEGM return timegm (&buf); -#else - { - time_t tim; - - putenv ("TZ=UTC"); - tim = mktime (&buf); -#ifdef __GNUC__ -#warning fixme: we must somehow reset TZ here. It is not threadsafe anyway. -#endif - return tim; - } -#endif /* !HAVE_TIMEGM */ -#endif /* !HAVE_W32_SYSTEM */ } else return (time_t)strtoul (timestamp, endp, 10); diff --git a/common/gettime.h b/common/gettime.h index 18f65ab1a..e216ddd36 100644 --- a/common/gettime.h +++ b/common/gettime.h @@ -32,7 +32,7 @@ #include /* We need time_t. */ #include /* We need gpg_error_t. */ - +#include /* We use uint64_t. */ /* A type to hold the ISO time. Note that this is the same as the KSBA type ksba_isotime_t. */ @@ -43,6 +43,11 @@ typedef char gnupg_isotime_t[16]; #define GNUPG_ISOTIME_NONE \ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +#ifndef HAVE_TIMEGM +time_t timegm (struct tm *tm); +#endif /*!HAVE_TIMEGM*/ +uint64_t timegm_u64 (struct tm *tm); + time_t gnupg_get_time (void); struct tm *gnupg_gmtime (const time_t *timep, struct tm *result); void gnupg_get_isotime (gnupg_isotime_t timebuf); @@ -57,6 +62,7 @@ int isotime_p (const char *string); int isotime_human_p (const char *string, int date_only); size_t string2isotime (gnupg_isotime_t atime, const char *string); time_t isotime2epoch (const char *string); +uint64_t isotime2epoch_u64 (const char *string); void epoch2isotime (gnupg_isotime_t timebuf, time_t atime); int isodate_human_to_tm (const char *string, struct tm *t); time_t parse_timestamp (const char *timestamp, char **endp); diff --git a/common/mischelp.c b/common/mischelp.c index ee8500297..ef70c9d83 100644 --- a/common/mischelp.c +++ b/common/mischelp.c @@ -126,80 +126,3 @@ same_file_p (const char *name1, const char *name2) } return yes; } - - -/* - timegm() is a GNU function that might not be available everywhere. - It's basically the inverse of gmtime() - you give it a struct tm, - and get back a time_t. It differs from mktime() in that it handles - the case where the struct tm is UTC and the local environment isn't. - - Note, that this replacement implementation might not be thread-safe! - - Some BSDs don't handle the putenv("foo") case properly, so we use - unsetenv if the platform has it to remove environment variables. -*/ -#ifndef HAVE_TIMEGM -time_t -timegm (struct tm *tm) -{ -#ifdef HAVE_W32_SYSTEM - /* This one is thread safe. */ - SYSTEMTIME st; - FILETIME ft; - unsigned long long cnsecs; - - st.wYear = tm->tm_year + 1900; - st.wMonth = tm->tm_mon + 1; - st.wDay = tm->tm_mday; - st.wHour = tm->tm_hour; - st.wMinute = tm->tm_min; - st.wSecond = tm->tm_sec; - st.wMilliseconds = 0; /* Not available. */ - st.wDayOfWeek = 0; /* Ignored. */ - - /* System time is UTC thus the conversion is pretty easy. */ - if (!SystemTimeToFileTime (&st, &ft)) - { - gpg_err_set_errno (EINVAL); - return (time_t)(-1); - } - - cnsecs = (((unsigned long long)ft.dwHighDateTime << 32) - | ft.dwLowDateTime); - cnsecs -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01. */ - return (time_t)(cnsecs / 10000000ULL); - -#else /* (Non thread safe implementation!) */ - - time_t answer; - char *zone; - - zone=getenv("TZ"); - putenv("TZ=UTC"); - tzset(); - answer=mktime(tm); - if(zone) - { - static char *old_zone; - - if (!old_zone) - { - old_zone = malloc(3+strlen(zone)+1); - if (old_zone) - { - strcpy(old_zone,"TZ="); - strcat(old_zone,zone); - } - } - if (old_zone) - putenv (old_zone); - } - else - gnupg_unsetenv("TZ"); - - tzset(); - return answer; -#endif -} -#endif /*!HAVE_TIMEGM*/ diff --git a/common/mischelp.h b/common/mischelp.h index bdee5a443..7359ec29e 100644 --- a/common/mischelp.h +++ b/common/mischelp.h @@ -38,12 +38,6 @@ int same_file_p (const char *name1, const char *name2); -#ifndef HAVE_TIMEGM -#include -time_t timegm (struct tm *tm); -#endif /*!HAVE_TIMEGM*/ - - #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) From a4fe307b5535ed350fff63941aaa0b19ee2e683a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 26 Oct 2023 12:01:44 +0200 Subject: [PATCH 231/869] gpg: Allow expiration time after 2038-01-19 on 32 bit Windows. * g10/keygen.c (parse_expire_string_with_ct): Use isotime2epoch_u64. (parse_creation_string): Ditto. -- GnuPG-bug-id: 6736 --- g10/keygen.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 06fc39aa1..87940722d 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2748,6 +2748,7 @@ parse_expire_string_with_ct (const char *string, u32 creation_time) u32 seconds; u32 abs_date = 0; time_t tt; + uint64_t tmp64; u32 curtime; if (creation_time == (u32)-1) @@ -2763,11 +2764,16 @@ parse_expire_string_with_ct (const char *string, u32 creation_time) else if ((abs_date = scan_isodatestr(string)) && (abs_date+86400/2) > curtime) seconds = (abs_date+86400/2) - curtime; - else if ((tt = isotime2epoch (string)) != (time_t)(-1)) - seconds = (u32)tt - curtime; + else if ((tt = isotime2epoch_u64 (string)) != (uint64_t)(-1)) + { + tmp64 = tt - curtime; + if (tmp64 >= (u32)(-1)) + seconds = (u32)(-1) - 1; /* cap value. */ + else + seconds = (u32)tmp64; + } else if ((mult = check_valid_days (string))) { - uint64_t tmp64; tmp64 = scan_secondsstr (string) * 86400L * mult; if (tmp64 >= (u32)(-1)) seconds = (u32)(-1) - 1; /* cap value. */ @@ -2800,8 +2806,13 @@ parse_creation_string (const char *string) seconds = scan_secondsstr (string+8); else if ( !(seconds = scan_isodatestr (string))) { - time_t tmp = isotime2epoch (string); - seconds = (tmp == (time_t)(-1))? 0 : tmp; + uint64_t tmp = isotime2epoch_u64 (string); + if (tmp == (uint64_t)(-1)) + seconds = 0; + else if (tmp > (u32)(-1)) + seconds = 0; + else + seconds = tmp; } return seconds; } From 95b9a31f81e4a56518269d2476b54a1f10fe8b3e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 27 Oct 2023 14:20:47 +0200 Subject: [PATCH 232/869] gpg: Fix minor memory leak during certain smartcard operations. * g10/keygen.c (card_store_key_with_backup): Fix memory leak on error. --- g10/keygen.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 87940722d..2f8528278 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -5386,17 +5386,26 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk, { ecdh_param_str = ecdh_param_str_from_pk (sk); if (!ecdh_param_str) - return gpg_error_from_syserror (); + { + free_public_key (sk); + return gpg_error_from_syserror (); + } } err = hexkeygrip_from_pk (sk, &hexgrip); if (err) - goto leave; + { + xfree (ecdh_param_str); + free_public_key (sk); + goto leave; + } memset(&info, 0, sizeof (info)); rc = agent_scd_getattr ("SERIALNO", &info); if (rc) { + xfree (ecdh_param_str); + free_public_key (sk); err = (gpg_error_t)rc; goto leave; } From 678c81902750a5a40573d708c5e14dad5225121e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 27 Oct 2023 14:00:59 +0200 Subject: [PATCH 233/869] w32: Use utf8 for the asctimestamp function. * common/gettime.c (asctimestamp) [W32]: Use ".UTF8" for the locale. -- This has been suggested by the reporter of GnuPG-bug-id: 6741 --- NEWS | 2 ++ common/gettime.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f4ecb1d64..7f6162cbb 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ Noteworthy changes in version 2.4.4 (unreleased) ------------------------------------------------ + * Fix garbled time output in non-English Windows. [T6741] + Release-info: https://dev.gnupg.org/T6578 diff --git a/common/gettime.c b/common/gettime.c index 3f1ce0c5a..136c47ca7 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -850,7 +850,7 @@ asctimestamp (u32 stamp) * 2018 has a lot of additional support but that will for sure * break other things. We should move to ISO strings to get * rid of such problems. */ - setlocale (LC_TIME, ""); + setlocale (LC_TIME, ".UTF8"); done = 1; /* log_debug ("LC_ALL now '%s'\n", setlocale (LC_ALL, NULL)); */ /* log_debug ("LC_TIME now '%s'\n", setlocale (LC_TIME, NULL)); */ From 05ef8c0cc005fcdf412be6819428c677f0185d33 Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Sat, 28 Oct 2023 14:20:31 +0200 Subject: [PATCH 234/869] g10: Fix uninitalized variable use in sign_file * g10/sign.c (sign_file): Initialize gcry_md_hd_t to NULL. -- There are several jumps to leave before gcry_md_open is called so md should be initialized to NULL to avoid calling gcry_md_close on an uninitalized variable. GnuPG-Bug-Id: T6780 --- g10/sign.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/sign.c b/g10/sign.c index f68ea3bc7..ee3fac1df 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1020,7 +1020,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, const char *fname; armor_filter_context_t *afx; compress_filter_context_t zfx; - gcry_md_hd_t md; + gcry_md_hd_t md = NULL; md_filter_context_t mfx; md_thd_filter_context_t mfx2 = NULL; text_filter_context_t tfx; From c2812a9bbc3539e40bde0c9ea804aee39147a87c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 2 Nov 2023 15:05:19 +0900 Subject: [PATCH 235/869] doc: Fix to avoid using en-dash for command options. -- GnuPG-bug-id: 6746 Signed-off-by: NIIBE Yutaka --- doc/dirmngr.texi | 2 +- doc/gpg-agent.texi | 2 +- doc/gpg.texi | 30 +++++++++++++++--------------- doc/gpgsm.texi | 4 ++-- doc/gpgv.texi | 2 +- doc/tools.texi | 11 ++++++----- 6 files changed, 26 insertions(+), 25 deletions(-) diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 0d0cb018d..9fc58ea24 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -295,7 +295,7 @@ seconds. @opindex connect-quick-timeout Set the timeout for HTTP and generic TCP connection attempts to N seconds. The value set with the quick variant is used when the ---quick option has been given to certain Assuan commands. The quick +@option{--quick} option has been given to certain Assuan commands. The quick value is capped at the value of the regular connect timeout. The default values are 15 and 2 seconds. Note that the timeout values are for each connection attempt; the connection code will attempt to diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 6d6cf97ec..08dd7f49f 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -177,7 +177,7 @@ Windows. If in @file{common.conf} the option @option{no-autostart} is set, any start attempts will be ignored. -In --supervised mode, different file descriptors can be provided for +In @option{--supervised} mode, different file descriptors can be provided for use as different socket types (e.g., ssh, extra) as long as they are identified in the environment variable @code{LISTEN_FDNAMES} (see sd_listen_fds(3) on some Linux distributions for more information on diff --git a/doc/gpg.texi b/doc/gpg.texi index b5a9ccc51..760582c8e 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -362,9 +362,9 @@ public keys are listed. The variant @option{--locate-external-keys} does not consider a locally existing key and can thus be used to force the refresh of a key via the defined external methods. If a fingerprint is given and -and the methods defined by --auto-key-locate define LDAP servers, the -key is fetched from these resources; defined non-LDAP keyservers are -skipped. +and the methods defined by @option{--auto-key-locate} define LDAP +servers, the key is fetched from these resources; defined non-LDAP +keyservers are skipped. @item --show-keys @@ -1455,10 +1455,10 @@ give the opposite meaning. The options are: @item sort-sigs @opindex list-options:sort-sigs - With --list-sigs and --check-sigs sort the signatures by keyID and - creation time to make it easier to view the history of these - signatures. The self-signature is also listed before other - signatures. Defaults to yes. + With @option{--list-sigs} and @option{--check-sigs} sort the + signatures by keyID and creation time to make it easier to view the + history of these signatures. The self-signature is also listed + before other signatures. Defaults to yes. @end table @@ -1515,12 +1515,12 @@ the opposite meaning. The options are: @itemx --disable-large-rsa @opindex enable-large-rsa @opindex disable-large-rsa -With --generate-key and --batch, enable the creation of RSA secret keys as -large as 8192 bit. Note: 8192 bit is more than is generally -recommended. These large keys don't significantly improve security, -but they are more expensive to use, and their signatures and -certifications are larger. This option is only available if the -binary was build with large-secmem support. +With @option{--generate-key} and @option{--batch}, enable the creation +of RSA secret keys as large as 8192 bit. Note: 8192 bit is more than +is generally recommended. These large keys don't significantly +improve security, but they are more expensive to use, and their +signatures and certifications are larger. This option is only +available if the binary was build with large-secmem support. @item --enable-dsa2 @itemx --disable-dsa2 @@ -2624,12 +2624,12 @@ The available filter types are: @item drop-subkey This filter drops the selected subkeys. - Currently only implemented for --export-filter. + Currently only implemented for @option{--export-filter}. @item drop-sig This filter drops the selected key signatures on user ids. Self-signatures are not considered. - Currently only implemented for --import-filter. + Currently only implemented for @option{--import-filter}. @item select This filter is only implemented by @option{--list-filter}. All diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 41eb08d16..22738c492 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -642,8 +642,8 @@ By default gpgsm prints distinguished names (DNs) like the Issuer or Subject in a more readable format (e.g., using a well defined order of the parts). However, this format can't be used as input strings. This option reverts printing to standard RFC-2253 format and thus -avoids the need to use --dump-cert or --with-colons to get the -``real'' name. +avoids the need to use @option{--dump-cert} or @option{--with-colons} +to get the ``real'' name. @end table diff --git a/doc/gpgv.texi b/doc/gpgv.texi index 2dd9576b6..c8ba9fa5e 100644 --- a/doc/gpgv.texi +++ b/doc/gpgv.texi @@ -91,7 +91,7 @@ Add @var{file} to the list of keyrings. If @var{file} begins with a tilde and a slash, these are replaced by the HOME directory. If the filename does not contain a slash, it is assumed to be in the -home-directory ("~/.gnupg" if --homedir is not used). +home-directory ("~/.gnupg" if @option{--homedir} is not used). @item --output @var{file} @itemx -o @var{file} diff --git a/doc/tools.texi b/doc/tools.texi index 9cac81e4c..a7c141cfc 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -133,8 +133,8 @@ for the configuration files is: log-file socket:// @end example -If the default socket as given above and returned by "echo $(gpgconf ---list-dirs socketdir)/S.log" is not desired an arbitrary socket name +If the default socket as given above and returned by @code{"echo $(gpgconf +--list-dirs socketdir)/S.log"} is not desired an arbitrary socket name can be specified, for example @file{socket:///home/foo/bar/mysocket}. For debugging purposes it is also possible to do remote logging. Take care if you use this feature because the information is send in the @@ -2066,9 +2066,10 @@ Pass the specified extra options to @command{gpg}. @item --tar-args @var{args} @opindex tar-args Assume @var{args} are standard options of the command @command{tar} -and parse them. The only supported tar options are "--directory", -"--files-from", and "--null" This is an obsolete options because those -supported tar options can also be given directly. +and parse them. The only supported tar options are +@option{--directory}, @option{--files-from}, and @option{--null}. +This is an obsolete options because those supported tar options can +also be given directly. @item --tar @var{command} @opindex tar From 00da0e9f936efebce1ad41c966cbd871e3515248 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 6 Nov 2023 14:47:21 +0900 Subject: [PATCH 236/869] doc: Remove stray .RE in doc/gpgsm.texi. -- Signed-off-by: NIIBE Yutaka --- doc/gpgsm.texi | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 22738c492..91760abc3 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -984,7 +984,6 @@ X.509 certificates. This global file is installed in the data directory @end table -@c man:.RE Note that on larger installations, it is useful to put predefined files into the directory @file{/etc/skel/.gnupg/} so that newly created users start up with a working configuration. For existing users a small From 337de21f4b4f1e617ef875606e6f29df4629d52a Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 7 Nov 2023 13:55:29 +0900 Subject: [PATCH 237/869] doc: Use the em dash to mark a break in a sentence. -- Signed-off-by: NIIBE Yutaka --- doc/dirmngr.texi | 2 +- doc/gpg.texi | 30 +++++++++++++++--------------- doc/gpgsm.texi | 10 +++++----- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 9fc58ea24..8da4dcd37 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -749,7 +749,7 @@ certificate exists it is used to access the special keyservers Please note that @command{gpgsm} accepts Root CA certificates for its own purposes only if they are listed in its file @file{trustlist.txt}. -@command{dirmngr} does not make use of this list - except FIXME. +@command{dirmngr} does not make use of this list --- except FIXME. @mansect notes diff --git a/doc/gpg.texi b/doc/gpg.texi index 760582c8e..8203c1466 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1006,13 +1006,13 @@ signing. @item keytocard @opindex keyedit:keytocard Transfer the selected secret subkey (or the primary key if no subkey - has been selected) to a smartcard. The secret key in the keyring will - be replaced by a stub if the key could be stored successfully on the - card and you use the save command later. Only certain key types may be - transferred to the card. A sub menu allows you to select on what card - to store the key. Note that it is not possible to get that key back - from the card - if the card gets broken your secret key will be lost - unless you have a backup somewhere. + has been selected) to a smartcard. The secret key in the keyring + will be replaced by a stub if the key could be stored successfully + on the card and you use the save command later. Only certain key + types may be transferred to the card. A sub menu allows you to + select on what card to store the key. Note that it is not possible + to get that key back from the card --- if the card gets broken your + secret key will be lost unless you have a backup somewhere. @item bkuptocard @var{file} @opindex keyedit:bkuptocard @@ -1266,13 +1266,13 @@ behaviour and to change the default configuration. @end menu Long options can be put in an options file (default -"~/.gnupg/gpg.conf"). Short option names will not work - for example, -"armor" is a valid option for the options file, while "a" is not. Do not -write the 2 dashes, but simply the name of the option and any required -arguments. Lines with a hash ('#') as the first non-white-space -character are ignored. Commands may be put in this file too, but that is -not generally useful as the command will execute automatically with -every execution of gpg. +"~/.gnupg/gpg.conf"). Short option names will not work --- for +example, "armor" is a valid option for the options file, while "a" is +not. Do not write the 2 dashes, but simply the name of the option and +any required arguments. Lines with a hash ('#') as the first +non-white-space character are ignored. Commands may be put in this +file too, but that is not generally useful as the command will execute +automatically with every execution of gpg. Please remember that option parsing stops as soon as a non-option is encountered, you can explicitly stop parsing by using the special option @@ -2047,7 +2047,7 @@ option is ignored if the option @option{--with-colons} is used. @item --keyserver @var{name} @opindex keyserver -This option is deprecated - please use the @option{--keyserver} in +This option is deprecated --- please use the @option{--keyserver} in @file{dirmngr.conf} instead. Use @var{name} as your keyserver. This is the server that diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 91760abc3..602a39f50 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -1380,11 +1380,11 @@ The decryption is done by using the command DECRYPT @end example -It performs the decrypt operation after doing some check on the internal -state (e.g., that all needed data has been set). Because it utilizes -the GPG-Agent for the session key decryption, there is no need to ask -the client for a protecting passphrase - GpgAgent takes care of this by -requesting this from the user. +It performs the decrypt operation after doing some check on the +internal state (e.g., that all needed data has been set). Because it +utilizes the GPG-Agent for the session key decryption, there is no +need to ask the client for a protecting passphrase --- GpgAgent takes +care of this by requesting this from the user. @node GPGSM SIGN From e6b3d53db36dba8aef640fc0a99cc079551a965a Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 8 Nov 2023 11:39:57 +0900 Subject: [PATCH 238/869] scd: Return GPG_ERR_PIN_BLOCKED when it's blocked. * scd/app-openpgp.c (build_enter_admin_pin_prompt): Fix to use GPG_ERR_PIN_BLOCKED. (check_pin): Likewise. -- GnuPG-bug-id: 6425 Signed-off-by: NIIBE Yutaka --- scd/app-openpgp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index fd9ce554c..014cd9395 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -2859,7 +2859,7 @@ build_enter_admin_pin_prompt (app_t app, char **r_prompt, int *r_remaining) if (!remaining) { log_info (_("card is permanently locked!\n")); - return gpg_error (GPG_ERR_BAD_PIN); + return gpg_error (GPG_ERR_PIN_BLOCKED); } log_info (ngettext("%d Admin PIN attempt remaining before card" @@ -5998,7 +5998,7 @@ do_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr, if (!count) { log_info (_("card is permanently locked!\n")); - return gpg_error (GPG_ERR_BAD_PIN); + return gpg_error (GPG_ERR_PIN_BLOCKED); } else if (count < 3) { From 4257cbb06c8e091e834e989064612f94aa879239 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 8 Nov 2023 11:39:57 +0900 Subject: [PATCH 239/869] scd: Return GPG_ERR_PIN_BLOCKED when it's blocked. * scd/app-openpgp.c (build_enter_admin_pin_prompt): Fix to use GPG_ERR_PIN_BLOCKED. (check_pin): Likewise. -- Cherry-pick from master commit: e6b3d53db36dba8aef640fc0a99cc079551a965a GnuPG-bug-id: 6425 Signed-off-by: NIIBE Yutaka --- scd/app-openpgp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index fd9ce554c..014cd9395 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -2859,7 +2859,7 @@ build_enter_admin_pin_prompt (app_t app, char **r_prompt, int *r_remaining) if (!remaining) { log_info (_("card is permanently locked!\n")); - return gpg_error (GPG_ERR_BAD_PIN); + return gpg_error (GPG_ERR_PIN_BLOCKED); } log_info (ngettext("%d Admin PIN attempt remaining before card" @@ -5998,7 +5998,7 @@ do_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr, if (!count) { log_info (_("card is permanently locked!\n")); - return gpg_error (GPG_ERR_BAD_PIN); + return gpg_error (GPG_ERR_PIN_BLOCKED); } else if (count < 3) { From 65607fb81def5fc55320a1abfbb8ebdad9512011 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 8 Nov 2023 13:31:55 +0900 Subject: [PATCH 240/869] tools:gpg-card: Fix an error code for Reset Code. * tools/gpg-card.c (cmd_unblock): Use GPG_ERR_NO_RESET_CODE. -- GnuPG-bug-id: 6425 Signed-off-by: NIIBE Yutaka --- tools/gpg-card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 12b4be25f..e66348232 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -2983,7 +2983,7 @@ cmd_unblock (card_info_t info) else if (!info->chvinfo[1]) { log_error (_("Reset Code not or not anymore available\n")); - err = gpg_error (GPG_ERR_PIN_BLOCKED); + err = gpg_error (GPG_ERR_NO_RESET_CODE); } else { From 64f5f7b74e428b15205f6e8ae14dec84663c3076 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 8 Nov 2023 13:41:16 +0900 Subject: [PATCH 241/869] gpg,tools: Handle GPG_ERR_PIN_BLOCKED and GPG_ERR_NO_RESET_CODE. * g10/card-util.c (write_sc_op_status): Emit 3 and 4 in status line. * tools/card-call-scd.c (status_sc_op_failure): Likewise. -- GnuPG-bug-id: 6425 Signed-off-by: NIIBE Yutaka --- g10/card-util.c | 6 ++++++ tools/card-call-scd.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/g10/card-util.c b/g10/card-util.c index 088ea824a..7df505f62 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -59,6 +59,12 @@ write_sc_op_status (gpg_error_t err) case GPG_ERR_BAD_RESET_CODE: write_status_text (STATUS_SC_OP_FAILURE, "2"); break; + case GPG_ERR_PIN_BLOCKED: + write_status_text (STATUS_SC_OP_FAILURE, "3"); + break; + case GPG_ERR_NO_RESET_CODE: + write_status_text (STATUS_SC_OP_FAILURE, "4"); + break; default: write_status (STATUS_SC_OP_FAILURE); break; diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 2bdbacb7a..17815c61b 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -238,6 +238,12 @@ status_sc_op_failure (gpg_error_t err) case GPG_ERR_BAD_RESET_CODE: gnupg_status_printf (STATUS_SC_OP_FAILURE, "2"); break; + case GPG_ERR_PIN_BLOCKED: + gnupg_status_printf (STATUS_SC_OP_FAILURE, "3"); + break; + case GPG_ERR_NO_RESET_CODE: + gnupg_status_printf (STATUS_SC_OP_FAILURE, "4"); + break; default: gnupg_status_printf (STATUS_SC_OP_FAILURE, NULL); break; From 4db2e13e2c8c9dd711500c772eedd9a5f7ca6300 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 8 Nov 2023 13:31:55 +0900 Subject: [PATCH 242/869] tools:gpg-card: Fix an error code for Reset Code. * tools/gpg-card.c (cmd_unblock): Use GPG_ERR_NO_RESET_CODE. -- Cherry-pick from master commit of: 65607fb81def5fc55320a1abfbb8ebdad9512011 GnuPG-bug-id: 6425 Signed-off-by: NIIBE Yutaka --- tools/gpg-card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 290ed485d..4b0457ab9 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -2981,7 +2981,7 @@ cmd_unblock (card_info_t info) else if (!info->chvinfo[1]) { log_error (_("Reset Code not or not anymore available\n")); - err = gpg_error (GPG_ERR_PIN_BLOCKED); + err = gpg_error (GPG_ERR_NO_RESET_CODE); } else { From d6f738729f0f4bf83c3a44fc4bba33ea6aaba622 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 8 Nov 2023 13:41:16 +0900 Subject: [PATCH 243/869] gpg,tools: Handle GPG_ERR_PIN_BLOCKED and GPG_ERR_NO_RESET_CODE. * g10/card-util.c (write_sc_op_status): Emit 3 and 4 in status line. * tools/card-call-scd.c (status_sc_op_failure): Likewise. -- Cherry-pick from master commit of: 64f5f7b74e428b15205f6e8ae14dec84663c3076 GnuPG-bug-id: 6425 Signed-off-by: NIIBE Yutaka --- g10/card-util.c | 6 ++++++ tools/card-call-scd.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/g10/card-util.c b/g10/card-util.c index b83472285..a66c2e3de 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -65,6 +65,12 @@ write_sc_op_status (gpg_error_t err) case GPG_ERR_BAD_RESET_CODE: write_status_text (STATUS_SC_OP_FAILURE, "2"); break; + case GPG_ERR_PIN_BLOCKED: + write_status_text (STATUS_SC_OP_FAILURE, "3"); + break; + case GPG_ERR_NO_RESET_CODE: + write_status_text (STATUS_SC_OP_FAILURE, "4"); + break; default: write_status (STATUS_SC_OP_FAILURE); break; diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 98d3ddeb7..34b03e694 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -238,6 +238,12 @@ status_sc_op_failure (gpg_error_t err) case GPG_ERR_BAD_RESET_CODE: gnupg_status_printf (STATUS_SC_OP_FAILURE, "2"); break; + case GPG_ERR_PIN_BLOCKED: + gnupg_status_printf (STATUS_SC_OP_FAILURE, "3"); + break; + case GPG_ERR_NO_RESET_CODE: + gnupg_status_printf (STATUS_SC_OP_FAILURE, "4"); + break; default: gnupg_status_printf (STATUS_SC_OP_FAILURE, NULL); break; From 3a669f175f0d23a845088902e1bca884a525cedb Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 8 Nov 2023 16:07:08 +0100 Subject: [PATCH 244/869] gpgsm: Cleanup of legacy variable name use. * sm/encrypt.c (gpgsm_encrypt): Unify use of RC and ERR. * sm/sign.c (gpgsm_sign): ditto. -- Initially we didn't used the gpg_error_t thingy and while migrating we sometimes used RC and ERR for tracking the error. This is pretty error prone and thus we better remove it (after 20 years). --- sm/encrypt.c | 78 +++++++++++++------------------ sm/sign.c | 128 ++++++++++++++++++++++----------------------------- 2 files changed, 89 insertions(+), 117 deletions(-) diff --git a/sm/encrypt.c b/sm/encrypt.c index 024f48673..3c43edf61 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -576,9 +576,8 @@ encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread) int gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) { - int rc = 0; + gpg_error_t err = 0; gnupg_ksba_io_t b64writer = NULL; - gpg_error_t err; ksba_writer_t writer; ksba_reader_t reader = NULL; ksba_cms_t cms = NULL; @@ -607,7 +606,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) log_error(_("no valid recipients given\n")); gpgsm_status (ctrl, STATUS_NO_RECP, "0"); audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, 0); - rc = gpg_error (GPG_ERR_NO_PUBKEY); + err = gpg_error (GPG_ERR_NO_PUBKEY); goto leave; } @@ -619,7 +618,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) if (!kh) { log_error (_("failed to allocate keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; } @@ -627,29 +626,27 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) data_fp = es_fdopen_nc (data_fd, "rb"); if (!data_fp) { - rc = gpg_error_from_syserror (); - log_error ("fdopen() failed: %s\n", strerror (errno)); + err = gpg_error_from_syserror (); + log_error ("fdopen() failed: %s\n", gpg_strerror (err)); goto leave; } err = ksba_reader_new (&reader); + if (!err) + err = ksba_reader_set_cb (reader, encrypt_cb, &encparm); if (err) - rc = err; - if (!rc) - rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm); - if (rc) - goto leave; + goto leave; encparm.fp = data_fp; ctrl->pem_name = "ENCRYPTED MESSAGE"; - rc = gnupg_ksba_create_writer + err = gnupg_ksba_create_writer (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), ctrl->pem_name, out_fp, &writer); - if (rc) + if (err) { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); + log_error ("can't create writer: %s\n", gpg_strerror (err)); goto leave; } @@ -659,17 +656,13 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) err = ksba_cms_new (&cms); if (err) - { - rc = err; - goto leave; - } + goto leave; err = ksba_cms_set_reader_writer (cms, reader, writer); if (err) { log_error ("ksba_cms_set_reader_writer failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } @@ -684,7 +677,6 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) { log_error ("ksba_cms_set_content_type failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } @@ -696,34 +688,34 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) log_error (_("cipher algorithm '%s' may not be used in %s mode\n"), opt.def_cipher_algoid, gnupg_compliance_option_string (opt.compliance)); - rc = gpg_error (GPG_ERR_CIPHER_ALGO); + err = gpg_error (GPG_ERR_CIPHER_ALGO); goto leave; } if (!gnupg_rng_is_compliant (opt.compliance)) { - rc = gpg_error (GPG_ERR_FORBIDDEN); + err = gpg_error (GPG_ERR_FORBIDDEN); log_error (_("%s is not compliant with %s mode\n"), "RNG", gnupg_compliance_option_string (opt.compliance)); gpgsm_status_with_error (ctrl, STATUS_ERROR, - "random-compliance", rc); + "random-compliance", err); goto leave; } /* Create a session key */ dek = xtrycalloc_secure (1, sizeof *dek); if (!dek) - rc = out_of_core (); + err = gpg_error_from_syserror (); else - { - dek->algoid = opt.def_cipher_algoid; - rc = init_dek (dek); - } - if (rc) + { + dek->algoid = opt.def_cipher_algoid; + err = init_dek (dek); + } + if (err) { log_error ("failed to create the session key: %s\n", - gpg_strerror (rc)); + gpg_strerror (err)); goto leave; } @@ -732,7 +724,6 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) { log_error ("ksba_cms_set_content_enc_algo failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } @@ -742,7 +733,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) encparm.buffer = xtrymalloc (encparm.bufsize); if (!encparm.buffer) { - rc = out_of_core (); + err = gpg_error_from_syserror (); goto leave; } @@ -784,12 +775,12 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) xfree (curve); curve = NULL; - rc = encrypt_dek (dek, cl->cert, pk_algo, &encval); - if (rc) + err = encrypt_dek (dek, cl->cert, pk_algo, &encval); + if (err) { - audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, rc); + audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err); log_error ("encryption failed for recipient no. %d: %s\n", - recpno, gpg_strerror (rc)); + recpno, gpg_strerror (err)); goto leave; } @@ -799,7 +790,6 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err); log_error ("ksba_cms_add_recipient failed: %s\n", gpg_strerror (err)); - rc = err; xfree (encval); goto leave; } @@ -811,7 +801,6 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) { log_error ("ksba_cms_set_enc_val failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } } @@ -825,7 +814,7 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) log_error (_("operation forced to fail due to" " unfulfilled compliance rules\n")); gpgsm_errors_seen = 1; - rc = gpg_error (GPG_ERR_FORBIDDEN); + err = gpg_error (GPG_ERR_FORBIDDEN); goto leave; } @@ -837,7 +826,6 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) if (err) { log_error ("creating CMS object failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } } @@ -846,15 +834,15 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) if (encparm.readerror) { log_error ("error reading input: %s\n", strerror (encparm.readerror)); - rc = gpg_error (gpg_err_code_from_errno (encparm.readerror)); + err = gpg_error (gpg_err_code_from_errno (encparm.readerror)); goto leave; } - rc = gnupg_ksba_finish_writer (b64writer); - if (rc) + err = gnupg_ksba_finish_writer (b64writer); + if (err) { - log_error ("write failed: %s\n", gpg_strerror (rc)); + log_error ("write failed: %s\n", gpg_strerror (err)); goto leave; } audit_log (ctrl->audit, AUDIT_ENCRYPTION_DONE); @@ -869,5 +857,5 @@ gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp) xfree (dek); es_fclose (data_fp); xfree (encparm.buffer); - return rc; + return err; } diff --git a/sm/sign.c b/sm/sign.c index c3781506d..cd0ddceb3 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -624,8 +624,8 @@ int gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, int data_fd, int detached, estream_t out_fp) { - int i, rc; gpg_error_t err; + int i; gnupg_ksba_io_t b64writer = NULL; ksba_writer_t writer; estream_t sig_fp = NULL; /* Used for detached signatures. */ @@ -648,18 +648,18 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, if (!kh) { log_error (_("failed to allocate keyDB handle\n")); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; } if (!gnupg_rng_is_compliant (opt.compliance)) { - rc = gpg_error (GPG_ERR_FORBIDDEN); + err = gpg_error (GPG_ERR_FORBIDDEN); log_error (_("%s is not compliant with %s mode\n"), "RNG", gnupg_compliance_option_string (opt.compliance)); gpgsm_status_with_error (ctrl, STATUS_ERROR, - "random-compliance", rc); + "random-compliance", err); goto leave; } @@ -671,20 +671,20 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, if (binary_detached) { sig_fp = es_fopenmem (0, "w+"); - rc = sig_fp? 0 : gpg_error_from_syserror (); - if (!rc) - rc = gnupg_ksba_create_writer (&b64writer, 0, NULL, sig_fp, &writer); + err = sig_fp? 0 : gpg_error_from_syserror (); + if (!err) + err = gnupg_ksba_create_writer (&b64writer, 0, NULL, sig_fp, &writer); } else { - rc = gnupg_ksba_create_writer + err = gnupg_ksba_create_writer (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0) | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)), ctrl->pem_name, out_fp, &writer); } - if (rc) + if (err) { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); + log_error ("can't create writer: %s\n", gpg_strerror (err)); goto leave; } @@ -694,17 +694,13 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, err = ksba_cms_new (&cms); if (err) - { - rc = err; - goto leave; - } + goto leave; err = ksba_cms_set_reader_writer (cms, NULL, writer); if (err) { log_debug ("ksba_cms_set_reader_writer failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } @@ -721,7 +717,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, { log_debug ("ksba_cms_set_content_type failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } @@ -734,23 +729,23 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, log_error ("no default signer found\n"); gpgsm_status2 (ctrl, STATUS_INV_SGNR, get_inv_recpsgnr_code (GPG_ERR_NO_SECKEY), NULL); - rc = gpg_error (GPG_ERR_GENERAL); + err = gpg_error (GPG_ERR_GENERAL); goto leave; } /* Although we don't check for ambiguous specification we will check that the signer's certificate is usable and valid. */ - rc = gpgsm_cert_use_sign_p (cert, 0); - if (!rc) - rc = gpgsm_validate_chain (ctrl, cert, + err = gpgsm_cert_use_sign_p (cert, 0); + if (!err) + err = gpgsm_validate_chain (ctrl, cert, GNUPG_ISOTIME_NONE, NULL, 0, NULL, 0, NULL); - if (rc) + if (err) { char *tmpfpr; tmpfpr = gpgsm_get_fingerprint_hexstring (cert, 0); gpgsm_status2 (ctrl, STATUS_INV_SGNR, - get_inv_recpsgnr_code (rc), tmpfpr, NULL); + get_inv_recpsgnr_code (err), tmpfpr, NULL); xfree (tmpfpr); goto leave; } @@ -759,7 +754,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, signerlist = xtrycalloc (1, sizeof *signerlist); if (!signerlist) { - rc = out_of_core (); + err = gpg_error_from_syserror (); ksba_cert_release (cert); goto leave; } @@ -867,22 +862,21 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, /* Gather certificates of signers and store them in the CMS object. */ for (cl=signerlist; cl; cl = cl->next) { - rc = gpgsm_cert_use_sign_p (cl->cert, 0); - if (rc) + err = gpgsm_cert_use_sign_p (cl->cert, 0); + if (err) goto leave; err = ksba_cms_add_signer (cms, cl->cert); if (err) { log_error ("ksba_cms_add_signer failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } - rc = add_certificate_list (ctrl, cms, cl->cert); - if (rc) + err = add_certificate_list (ctrl, cms, cl->cert); + if (err) { log_error ("failed to store list of certificates: %s\n", - gpg_strerror(rc)); + gpg_strerror (err)); goto leave; } /* Set the hash algorithm we are going to use */ @@ -891,7 +885,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, { log_debug ("ksba_cms_add_digest_algo failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } } @@ -913,7 +906,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, { log_error (_("checking for qualified certificate failed: %s\n"), gpg_strerror (err)); - rc = err; goto leave; } if (*buffer) @@ -921,19 +913,16 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, else err = gpgsm_not_qualified_warning (ctrl, cl->cert); if (err) - { - rc = err; - goto leave; - } + goto leave; } } /* Prepare hashing (actually we are figuring out what we have set above). */ - rc = gcry_md_open (&data_md, 0, 0); - if (rc) + err = gcry_md_open (&data_md, 0, 0); + if (err) { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); + log_error ("md_open failed: %s\n", gpg_strerror (err)); goto leave; } if (DBG_HASHING) @@ -945,7 +934,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, if (!algo) { log_error ("unknown hash algorithm '%s'\n", algoid? algoid:"?"); - rc = gpg_error (GPG_ERR_BUG); + err = gpg_error (GPG_ERR_BUG); goto leave; } gcry_md_enable (data_md, algo); @@ -970,7 +959,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, if ( !digest || !digest_len ) { log_error ("problem getting the hash of the data\n"); - rc = gpg_error (GPG_ERR_BUG); + err = gpg_error (GPG_ERR_BUG); goto leave; } err = ksba_cms_set_message_digest (cms, signer, digest, digest_len); @@ -978,7 +967,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, { log_error ("ksba_cms_set_message_digest failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } } @@ -992,7 +980,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, { log_error ("ksba_cms_set_signing_time failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } } @@ -1034,7 +1021,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, if (err) { log_error ("creating CMS object failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } @@ -1046,8 +1032,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, log_assert (!detached); - rc = hash_and_copy_data (data_fd, data_md, writer); - if (rc) + err = hash_and_copy_data (data_fd, data_md, writer); + if (err) goto leave; audit_log (ctrl->audit, AUDIT_GOT_DATA); for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) @@ -1057,7 +1043,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, if ( !digest || !digest_len ) { log_error ("problem getting the hash of the data\n"); - rc = gpg_error (GPG_ERR_BUG); + err = gpg_error (GPG_ERR_BUG); goto leave; } err = ksba_cms_set_message_digest (cms, signer, @@ -1066,7 +1052,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, { log_error ("ksba_cms_set_message_digest failed: %s\n", gpg_strerror (err)); - rc = err; goto leave; } } @@ -1076,10 +1061,10 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, /* Compute the signature for all signers. */ gcry_md_hd_t md; - rc = gcry_md_open (&md, 0, 0); - if (rc) + err = gcry_md_open (&md, 0, 0); + if (err) { - log_error ("md_open failed: %s\n", gpg_strerror (rc)); + log_error ("md_open failed: %s\n", gpg_strerror (err)); goto leave; } if (DBG_HASHING) @@ -1104,20 +1089,20 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, } } - rc = ksba_cms_hash_signed_attrs (cms, signer); - if (rc) + err = ksba_cms_hash_signed_attrs (cms, signer); + if (err) { log_debug ("hashing signed attrs failed: %s\n", - gpg_strerror (rc)); + gpg_strerror (err)); gcry_md_close (md); goto leave; } - rc = gpgsm_create_cms_signature (ctrl, cl->cert, - md, cl->hash_algo, &sigval); - if (rc) + err = gpgsm_create_cms_signature (ctrl, cl->cert, + md, cl->hash_algo, &sigval); + if (err) { - audit_log_cert (ctrl->audit, AUDIT_SIGNED_BY, cl->cert, rc); + audit_log_cert (ctrl->audit, AUDIT_SIGNED_BY, cl->cert, err); gcry_md_close (md); goto leave; } @@ -1129,7 +1114,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, audit_log_cert (ctrl->audit, AUDIT_SIGNED_BY, cl->cert, err); log_error ("failed to store the signature: %s\n", gpg_strerror (err)); - rc = err; gcry_md_close (md); goto leave; } @@ -1138,11 +1122,10 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, fpr = gpgsm_get_fingerprint_hexstring (cl->cert, GCRY_MD_SHA1); if (!fpr) { - rc = gpg_error (GPG_ERR_ENOMEM); + err = gpg_error (GPG_ERR_ENOMEM); gcry_md_close (md); goto leave; } - rc = 0; if (opt.verbose) { char *pkalgostr = gpgsm_pubkey_algo_string (cl->cert, NULL); @@ -1159,9 +1142,9 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, signed_at, fpr); if (!buf) - rc = gpg_error_from_syserror (); + err = gpg_error_from_syserror (); xfree (fpr); - if (rc) + if (err) { gcry_md_close (md); goto leave; @@ -1175,10 +1158,10 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, } while (stopreason != KSBA_SR_READY); - rc = gnupg_ksba_finish_writer (b64writer); - if (rc) + err = gnupg_ksba_finish_writer (b64writer); + if (err) { - log_error ("write failed: %s\n", gpg_strerror (rc)); + log_error ("write failed: %s\n", gpg_strerror (err)); goto leave; } @@ -1187,13 +1170,14 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, void *blob = NULL; size_t bloblen; - rc = es_fclose_snatch (sig_fp, &blob, &bloblen); + err = (es_fclose_snatch (sig_fp, &blob, &bloblen)? + gpg_error_from_syserror () : 0); sig_fp = NULL; - if (rc) + if (err) goto leave; - rc = write_detached_signature (ctrl, blob, bloblen, out_fp); + err = write_detached_signature (ctrl, blob, bloblen, out_fp); xfree (blob); - if (rc) + if (err) goto leave; } @@ -1202,9 +1186,9 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, log_info ("signature created\n"); leave: - if (rc) + if (err) log_error ("error creating signature: %s <%s>\n", - gpg_strerror (rc), gpg_strsource (rc) ); + gpg_strerror (err), gpg_strsource (err) ); if (release_signerlist) gpgsm_release_certlist (signerlist); xfree (curve); @@ -1213,5 +1197,5 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, keydb_release (kh); gcry_md_close (data_md); es_fclose (sig_fp); - return rc; + return err; } From bf7b785b0e471533e5bb2db0e6a2b05b8e17d59d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 8 Nov 2023 16:08:25 +0100 Subject: [PATCH 245/869] common: Declare two LibrePGP constants for future use * common/openpgpdefs.h (SIGSUBPKT_META_HASH): New. (SIGSUBPKT_TRUST_ALIAS): New. --- common/openpgpdefs.h | 3 +++ g10/keyedit.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index 625747983..180680bcc 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -122,6 +122,9 @@ typedef enum SIGSUBPKT_ATTST_SIGS = 37, /* Attested Certifications. */ SIGSUBPKT_KEY_BLOCK = 38, /* Entire key used. */ + SIGSUBPKT_META_HASH = 40, /* Literal Data Meta Hash. */ + SIGSUBPKT_TRUST_ALIAS = 41, /* Trust Alias. */ + SIGSUBPKT_FLAG_CRITICAL = 128 } sigsubpkttype_t; diff --git a/g10/keyedit.c b/g10/keyedit.c index 21c1ee8d8..1f614fb7e 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -4794,7 +4794,7 @@ fail: /* * Ask for a new additional decryption subkey and add it to the key * block. Returns true if the keyblock was changed and false - * otherwise. If ADSKFPR is not NULL, this fucntion has been called + * otherwise. If ADSKFPR is not NULL, this function has been called * by quick_addadsk and gives the fingerprint of the to be added key. */ static int From 3572b19fbd8f6eea1edcaa8f753a7c9654702bed Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 8 Nov 2023 17:09:04 +0100 Subject: [PATCH 246/869] gpgsm: Support ECDSA in de-vs mode. * common/compliance.h (PK_ALGO_FLAG_ECC18): New. * common/compliance.c (gnupg_pk_is_allowed): Implement. * sm/decrypt.c (gpgsm_decrypt): Pass new flag. * sm/sign.c (gpgsm_sign): Ditto. * sm/verify.c (gpgsm_verify): Ditto. -- GnuPG-bug-id: 6802 --- NEWS | 2 ++ common/compliance.c | 13 +++++++++++-- common/compliance.h | 1 + sm/decrypt.c | 3 ++- sm/sign.c | 4 ++-- sm/verify.c | 1 + 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 7f6162cbb..889aff8e1 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ Noteworthy changes in version 2.4.4 (unreleased) ------------------------------------------------ + * gpgsm: Support ECDSA in de-vs compliance mode. [T6802] + * Fix garbled time output in non-English Windows. [T6741] Release-info: https://dev.gnupg.org/T6578 diff --git a/common/compliance.c b/common/compliance.c index 59d94038d..04978ed1b 100644 --- a/common/compliance.c +++ b/common/compliance.c @@ -256,6 +256,13 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance, if (! initialized) return 1; + /* Map the the generic ECC algo to ECDSA if requested. */ + if ((algo_flags & PK_ALGO_FLAG_ECC18) + && algo == GCRY_PK_ECC + && (use == PK_USE_VERIFICATION + || use == PK_USE_SIGNING)) + algo = GCRY_PK_ECDSA; + switch (compliance) { case CO_DE_VS: @@ -280,7 +287,6 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance, default: log_assert (!"reached"); } - (void)algo_flags; break; case PUBKEY_ALGO_DSA: @@ -301,7 +307,7 @@ gnupg_pk_is_allowed (enum gnupg_compliance_mode compliance, result = (use == PK_USE_DECRYPTION); break; - case PUBKEY_ALGO_ECDH: + case PUBKEY_ALGO_ECDH: /* Same value as GCRY_PK_ECC, i.e. 18 */ case GCRY_PK_ECDH: if (use == PK_USE_DECRYPTION) result = 1; @@ -549,6 +555,9 @@ gnupg_rng_is_compliant (enum gnupg_compliance_mode compliance) int *result; int res; + /* #warning debug code ahead */ + /* return 1; */ + result = get_compliance_cache (compliance, 1); if (result && *result != -1) diff --git a/common/compliance.h b/common/compliance.h index ead11472c..111fdc74b 100644 --- a/common/compliance.h +++ b/common/compliance.h @@ -50,6 +50,7 @@ enum pk_use_case /* Flags to distinguish public key algorithm variants. */ #define PK_ALGO_FLAG_RSAPSS 1 /* Use rsaPSS padding. */ +#define PK_ALGO_FLAG_ECC18 256 /* GCRY_PK_ECC is used in a generic way. */ int gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo, diff --git a/sm/decrypt.c b/sm/decrypt.c index 787e2f5e6..6d63189b8 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -1318,7 +1318,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) /* Check compliance. */ if (!gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION, - pk_algo, 0, NULL, nbits, curve)) + pk_algo, PK_ALGO_FLAG_ECC18, + NULL, nbits, curve)) { char kidstr[10+1]; diff --git a/sm/sign.c b/sm/sign.c index cd0ddceb3..3e8f26cbd 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -835,8 +835,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, goto leave; } - if (!gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo, 0, - NULL, nbits, curve)) + if (!gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo, + PK_ALGO_FLAG_ECC18, NULL, nbits, curve)) { char kidstr[10+1]; diff --git a/sm/verify.c b/sm/verify.c index 1f5c1d378..e83a24f44 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -503,6 +503,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo); /* Check compliance. */ + pkalgoflags |= PK_ALGO_FLAG_ECC18; if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_VERIFICATION, pkalgo, pkalgoflags, NULL, nbits, pkcurve)) { From ec1446f9446506b5fbdf90cdeb9cbe1f410a657e Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 9 Nov 2023 13:36:12 +0900 Subject: [PATCH 247/869] gpg,sm: Set confidential in assuan communication for password. * g10/call-agent.c (default_inq_cb): Call assuan_begin_confidential and assuan_end_confidential. * sm/call-agent.c (default_inq_cb): Likewise. -- GnuPG-bug-id: 6654 Signed-off-by: NIIBE Yutaka --- g10/call-agent.c | 2 ++ sm/call-agent.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/g10/call-agent.c b/g10/call-agent.c index cb7053396..c44c1cddb 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -161,6 +161,7 @@ default_inq_cb (void *opaque, const char *line) || has_leading_keyword (line, "NEW_PASSPHRASE")) && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK) { + assuan_begin_confidential (parm->ctx); if (have_static_passphrase ()) { s = get_static_passphrase (); @@ -187,6 +188,7 @@ default_inq_cb (void *opaque, const char *line) err = assuan_send_data (parm->ctx, pw, strlen (pw)); xfree (pw); } + assuan_end_confidential (parm->ctx); } else if ((s = has_leading_keyword (line, "CONFIRM")) && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK diff --git a/sm/call-agent.c b/sm/call-agent.c index 883c0c644..7f7205f26 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -222,7 +222,9 @@ default_inq_cb (void *opaque, const char *line) && have_static_passphrase ()) { const char *s = get_static_passphrase (); + assuan_begin_confidential (parm->ctx); err = assuan_send_data (parm->ctx, s, strlen (s)); + assuan_end_confidential (parm->ctx); } else log_error ("ignoring gpg-agent inquiry '%s'\n", line); From bafa7bf27f7d059708d73abc739dbd4e5f5c5682 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 9 Nov 2023 13:36:12 +0900 Subject: [PATCH 248/869] gpg,sm: Set confidential in assuan communication for password. * g10/call-agent.c (default_inq_cb): Call assuan_begin_confidential and assuan_end_confidential. * sm/call-agent.c (default_inq_cb): Likewise. -- Cherry pick from master commit of: ec1446f9446506b5fbdf90cdeb9cbe1f410a657e GnuPG-bug-id: 6654 Signed-off-by: NIIBE Yutaka --- g10/call-agent.c | 2 ++ sm/call-agent.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/g10/call-agent.c b/g10/call-agent.c index eb9f8e29b..4defa7990 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -161,6 +161,7 @@ default_inq_cb (void *opaque, const char *line) || has_leading_keyword (line, "NEW_PASSPHRASE")) && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK) { + assuan_begin_confidential (parm->ctx); if (have_static_passphrase ()) { s = get_static_passphrase (); @@ -187,6 +188,7 @@ default_inq_cb (void *opaque, const char *line) err = assuan_send_data (parm->ctx, pw, strlen (pw)); xfree (pw); } + assuan_end_confidential (parm->ctx); } else if ((s = has_leading_keyword (line, "CONFIRM")) && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK diff --git a/sm/call-agent.c b/sm/call-agent.c index 698039504..71768910f 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -221,7 +221,9 @@ default_inq_cb (void *opaque, const char *line) && have_static_passphrase ()) { const char *s = get_static_passphrase (); + assuan_begin_confidential (parm->ctx); err = assuan_send_data (parm->ctx, s, strlen (s)); + assuan_end_confidential (parm->ctx); } else log_error ("ignoring gpg-agent inquiry '%s'\n", line); From 6fab7b075adfa2931e2c0bbccf3038b3d916f37c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 13 Nov 2023 16:10:05 +0100 Subject: [PATCH 249/869] gpg: Implement a parser for Kyber encrypted packets. * g10/misc.c (pubkey_get_nenc): Add ky768 and ky1024 values. * g10/parse-packet.c (read_octet_string): New. (read_size_body): Rename to ... (read_sized_octet_string): this and change args to update-able PKTLEN. (parse_pubkeyenc): Split general parsing loop for easier reading. Implement parser for the Kyber algorithms. -- Take care: this has not been tested at all, it merely passes the regression test for the other algos. Kyber is also known as ML-KEM in FIPS-203. The list mode is slighly changed: In case of a parsing error no data is printed - before that already parsed data was printed. GnuPG-bug-id: 6815 --- common/openpgpdefs.h | 12 +-- g10/misc.c | 2 + g10/parse-packet.c | 177 +++++++++++++++++++++++++++++++------------ 3 files changed, 137 insertions(+), 54 deletions(-) diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index 8553a889f..c97995568 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -169,11 +169,11 @@ typedef enum PUBKEY_ALGO_ELGAMAL = 20, /* Elgamal encrypt+sign (legacy). */ /* 21 reserved by OpenPGP. */ PUBKEY_ALGO_EDDSA = 22, /* EdDSA. */ - PUBKEY_ALGO_KY768_25519 = 29, /* Kyber768 + X25519 */ - PUBKEY_ALGO_KY1024_448 = 30, /* Kyber1024 + X448 */ - PUBKEY_ALGO_DIL3_25519 = 35, /* Dilithium3 + Ed25519 */ - PUBKEY_ALGO_DIL5_448 = 36, /* Dilithium5 + Ed448 */ - PUBKEY_ALGO_SPHINX_SHA2 = 41, /* SPHINX+-simple-SHA2 */ + PUBKEY_ALGO_KY768_25519 = 29, /* Kyber768 + X25519 (aka ML-KEM-768) */ + PUBKEY_ALGO_KY1024_448 = 30, /* Kyber1024 + X448 (aka ML-KEM-1024) */ + PUBKEY_ALGO_DIL3_25519 = 35, /* Dilithium3 + Ed25519 (aka ML-DSA-65) */ + PUBKEY_ALGO_DIL5_448 = 36, /* Dilithium5 + Ed448 (aka ML-DSA-87) */ + PUBKEY_ALGO_SPHINX_SHA2 = 41, /* SPHINX+-simple-SHA2 (aka SLH-DSA-SHA2) */ PUBKEY_ALGO_PRIVATE10 = 110 } pubkey_algo_t; @@ -208,7 +208,7 @@ compress_algo_t; #define OPENPGP_MAX_NPKEY 5 /* Maximum number of public key parameters. */ #define OPENPGP_MAX_NSKEY 7 /* Maximum number of secret key parameters. */ #define OPENPGP_MAX_NSIG 2 /* Maximum number of signature parameters. */ -#define OPENPGP_MAX_NENC 2 /* Maximum number of encryption parameters. */ +#define OPENPGP_MAX_NENC 4 /* Maximum number of encryption parameters. */ /* Decode an rfc4880 encoded S2K count. */ diff --git a/g10/misc.c b/g10/misc.c index ec9b9025d..24242cc30 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1783,6 +1783,8 @@ pubkey_get_nenc (pubkey_algo_t algo) case PUBKEY_ALGO_ECDSA: return 0; case PUBKEY_ALGO_ELGAMAL: return 2; case PUBKEY_ALGO_EDDSA: return 0; + case PUBKEY_ALGO_KY768_25519: return 4; + case PUBKEY_ALGO_KY1024_448: return 4; default: return 0; } } diff --git a/g10/parse-packet.c b/g10/parse-packet.c index a033732ec..31c77de93 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -188,6 +188,65 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure) } +/* Read an octet string of length NBYTES from INP and return it at + * R_DATA. On error return an error code and store NULL at R_DATA. + * PKTLEN shall give the current lenhgth of the packt and is updated + * with each read. If SECURE is true, the integer is stored in secure + * memory (allocated using gcry_xmalloc_secure). */ +static gpg_error_t +read_octet_string (iobuf_t inp, unsigned long *pktlen, unsigned int nbytes, + int secure, gcry_mpi_t *r_data) +{ + gpg_error_t err; + int c, i; + byte *buf = NULL; + byte *p; + + *r_data = NULL; + + if (nbytes*8 > MAX_EXTERN_MPI_BITS) + { + log_error ("octet string too large (%u octets)\n", nbytes); + err = gpg_error (GPG_ERR_TOO_LARGE); + goto leave; + } + if (nbytes > *pktlen) + { + log_error ("octet string larger than packet (%u octets)\n", nbytes); + err = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + + buf = secure ? gcry_malloc_secure (nbytes) : gcry_malloc (nbytes); + if (!buf) + { + err = gpg_error_from_syserror (); + goto leave; + } + p = buf; + for (i = 0; i < nbytes; i++) + { + c = iobuf_get (inp); + if (c == -1) + { + err = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + + p[i] = c; + --*pktlen; + } + + *r_data = gcry_mpi_set_opaque (NULL, buf, nbytes*8); + gcry_mpi_set_flag (*r_data, GCRYMPI_FLAG_USER2); + return 0; + + leave: + gcry_free (buf); + return err; +} + + /* Read an external representation of an SOS and return the opaque MPI with GCRYMPI_FLAG_USER2. The external format is a 16-bit unsigned value stored in network byte order giving information for the @@ -1102,32 +1161,29 @@ read_rest (IOBUF inp, size_t pktlen) /* Read a special size+body from INP. On success store an opaque MPI - with it at R_DATA. On error return an error code and store NULL at - R_DATA. Even in the error case store the number of read bytes at - R_NREAD. The caller shall pass the remaining size of the packet in - PKTLEN. */ + * with it at R_DATA. The caller shall store the remaining size of + * the packet at PKTLEN. On error return an error code and store NULL + * at R_DATA. Even in the error case store the number of read bytes + * at PKTLEN is updated. */ static gpg_error_t -read_size_body (iobuf_t inp, int pktlen, size_t *r_nread, - gcry_mpi_t *r_data) +read_sized_octet_string (iobuf_t inp, unsigned long *pktlen, gcry_mpi_t *r_data) { char buffer[256]; char *tmpbuf; int i, c, nbytes; - *r_nread = 0; *r_data = NULL; - if (!pktlen) + if (!*pktlen) return gpg_error (GPG_ERR_INV_PACKET); c = iobuf_readbyte (inp); if (c < 0) return gpg_error (GPG_ERR_INV_PACKET); - pktlen--; - ++*r_nread; + --*pktlen; nbytes = c; if (nbytes < 2 || nbytes > 254) return gpg_error (GPG_ERR_INV_PACKET); - if (nbytes > pktlen) + if (nbytes > *pktlen) return gpg_error (GPG_ERR_INV_PACKET); buffer[0] = nbytes; @@ -1137,7 +1193,7 @@ read_size_body (iobuf_t inp, int pktlen, size_t *r_nread, c = iobuf_get (inp); if (c < 0) return gpg_error (GPG_ERR_INV_PACKET); - ++*r_nread; + --*pktlen; buffer[1+i] = c; } @@ -1350,7 +1406,9 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, { int rc = 0; int i, ndata; + unsigned int n; PKT_pubkey_enc *k; + int is_ky1024 = 0; k = packet->pkt.pubkey_enc = xmalloc_clear (sizeof *packet->pkt.pubkey_enc); if (pktlen < 12) @@ -1392,46 +1450,71 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, unknown_pubkey_warning (k->pubkey_algo); k->data[0] = NULL; /* No need to store the encrypted data. */ } + else if (k->pubkey_algo == PUBKEY_ALGO_ECDH) + { + log_assert (ndata == 2); + /* Get the ephemeral public key. */ + n = pktlen; + k->data[0] = sos_read (inp, &n, 0); + pktlen -= n; + if (!k->data[0]) + { + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + /* Get the wrapped symmetric key. */ + rc = read_sized_octet_string (inp, &pktlen, k->data + 1); + if (rc) + goto leave; + } + else if (k->pubkey_algo == PUBKEY_ALGO_KY768_25519 + || (is_ky1024 = (k->pubkey_algo == PUBKEY_ALGO_KY1024_448))) + { + log_assert (ndata == 4); + /* Get the ephemeral public key. */ + n = is_ky1024? 56 : 32; + rc = read_octet_string (inp, &pktlen, n, 0, k->data + 0); + if (rc) + goto leave; + /* Get the Kyber ciphertext. */ + n = is_ky1024? 1568 : 1088; + rc = read_octet_string (inp, &pktlen, n, 0, k->data + 1); + if (rc) + goto leave; + /* Get the algorithm id. */ + n = 1; + rc = read_octet_string (inp, &pktlen, n, 0, k->data + 2); + if (rc) + goto leave; + /* Get the wrapped symmetric key. */ + rc = read_sized_octet_string (inp, &pktlen, k->data + 3); + if (rc) + goto leave; + } else { for (i = 0; i < ndata; i++) { - if (k->pubkey_algo == PUBKEY_ALGO_ECDH) - { - if (i == 1) - { - size_t n; - rc = read_size_body (inp, pktlen, &n, k->data+i); - pktlen -= n; - } - else - { - int n = pktlen; - k->data[i] = sos_read (inp, &n, 0); - pktlen -= n; - if (!k->data[i]) - rc = gpg_error (GPG_ERR_INV_PACKET); - } - } - else - { - int n = pktlen; - k->data[i] = mpi_read (inp, &n, 0); - pktlen -= n; - if (!k->data[i]) - rc = gpg_error (GPG_ERR_INV_PACKET); - } - if (rc) - goto leave; - if (list_mode) - { - es_fprintf (listfp, "\tdata: "); - mpi_print (listfp, k->data[i], mpi_print_mode); - es_putc ('\n', listfp); - } + n = pktlen; + k->data[i] = mpi_read (inp, &n, 0); + pktlen -= n; + if (!k->data[i]) + rc = gpg_error (GPG_ERR_INV_PACKET); + } + if (rc) + goto leave; + } + if (list_mode) + { + for (i = 0; i < ndata; i++) + { + es_fprintf (listfp, "\tdata: "); + mpi_print (listfp, k->data[i], mpi_print_mode); + es_putc ('\n', listfp); } } + leave: iobuf_skip_rest (inp, pktlen, 0); return rc; @@ -2601,9 +2684,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, || (algorithm == PUBKEY_ALGO_ECDH && (i == 0 || i == 2))) { /* Read the OID (i==0) or the KDF params (i==2). */ - size_t n; - err = read_size_body (inp, pktlen, &n, pk->pkey+i); - pktlen -= n; + err = read_sized_octet_string (inp, &pktlen, pk->pkey+i); } else { From e6cedba11900226caf781d39ab4193d98e2cc0d7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 14 Nov 2023 09:47:13 +0100 Subject: [PATCH 250/869] gpgsm: Re-introduce the bad passphrase hint for pkcs#12. * sm/minip12.c (parse_bag_encrypted_data): Set the badpass flag. (parse_shrouded_key_bag): Ditto. -- --- sm/minip12.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sm/minip12.c b/sm/minip12.c index ae81d821b..1bbe126ae 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -936,6 +936,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) if (!datalen) { err = gpg_error (GPG_ERR_DECRYPT_FAILED); + ctx->badpass = 1; /* This is the most likley reason. */ goto bailout; } @@ -1461,6 +1462,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) if (!datalen) { err = gpg_error (GPG_ERR_DECRYPT_FAILED); + ctx->badpass = 1; goto bailout; } From def8f5f3d28bd5b19fd68e9fbd2eeb1d04c08db1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 14 Nov 2023 15:08:20 +0100 Subject: [PATCH 251/869] gpg,gpgsm: Hide password in debug output also for asked passwords. * g10/call-agent.c (agent_get_passphrase): Call assuan_begin_confidential and assuan_end_confidential. * sm/call-agent.c (gpgsm_agent_ask_passphrase): Ditto. -- GnuPG-bug-id: 6654 The drawback of this solution is that we don't see any IPC lines from the assuan_transact. Everything else would require larger changes to libassuan. --- g10/call-agent.c | 6 +++++- sm/call-agent.c | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index 4defa7990..c90cdfda5 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1995,7 +1995,7 @@ agent_get_passphrase (const char *cache_id, char *arg4 = NULL; membuf_t data; struct default_inq_parm_s dfltparm; - int have_newsymkey; + int have_newsymkey, wasconf; memset (&dfltparm, 0, sizeof dfltparm); @@ -2047,10 +2047,14 @@ agent_get_passphrase (const char *cache_id, xfree (arg4); init_membuf_secure (&data, 64); + wasconf = assuan_get_flag (agent_ctx, ASSUAN_CONFIDENTIAL); + assuan_begin_confidential (agent_ctx); rc = assuan_transact (agent_ctx, line, put_membuf_cb, &data, default_inq_cb, &dfltparm, NULL, NULL); + if (!wasconf) + assuan_end_confidential (agent_ctx); if (rc) xfree (get_membuf (&data, NULL)); diff --git a/sm/call-agent.c b/sm/call-agent.c index 71768910f..eb6671692 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -1322,6 +1322,7 @@ gpgsm_agent_ask_passphrase (ctrl_t ctrl, const char *desc_msg, int repeat, char *arg4 = NULL; membuf_t data; struct default_inq_parm_s inq_parm; + int wasconf; *r_passphrase = NULL; @@ -1340,9 +1341,13 @@ gpgsm_agent_ask_passphrase (ctrl_t ctrl, const char *desc_msg, int repeat, xfree (arg4); init_membuf_secure (&data, 64); + wasconf = assuan_get_flag (agent_ctx, ASSUAN_CONFIDENTIAL); + assuan_begin_confidential (agent_ctx); err = assuan_transact (agent_ctx, line, put_membuf_cb, &data, default_inq_cb, &inq_parm, NULL, NULL); + if (!wasconf) + assuan_end_confidential (agent_ctx); if (err) xfree (get_membuf (&data, NULL)); From 2600047470169a43592df2a67f843491bbacf6d5 Mon Sep 17 00:00:00 2001 From: Max-Julian Pogner Date: Sat, 11 Nov 2023 18:09:17 +0100 Subject: [PATCH 252/869] gpgv: Update used keyrings in doc FILES section * doc/gpgv.texi: Explicitely list all searched default keyrings in the FILES section. * doc/gpgv.texi: use ${GNUPGHOME} placeholder to be extra precise. --- doc/gpgv.texi | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/gpgv.texi b/doc/gpgv.texi index c8ba9fa5e..997f62743 100644 --- a/doc/gpgv.texi +++ b/doc/gpgv.texi @@ -180,12 +180,13 @@ If set directory used instead of "~/.gnupg". @mansect files @subsection FILES -@table @asis +By default gpgv searches for the keyring holding the allowed keys +in the following locations (First file found is used): -@item ~/.gnupg/trustedkeys.gpg -The default keyring with the allowed keys. - -@end table +@itemize @bullet +@item $@{GNUPGHOME@}/trustedkeys.kbx +@item $@{GNUPGHOME@}/trustedkeys.gpg +@end itemize @mansect see also @command{gpg}(1) From 42ee84197695aca44f5f909a0b1eb59298497da0 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 16 Nov 2023 13:31:42 +0900 Subject: [PATCH 253/869] doc: Update for gpgv. -- GnuPG-bug-id: 6810 Signed-off-by: NIIBE Yutaka --- doc/gpgv.texi | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/doc/gpgv.texi b/doc/gpgv.texi index 997f62743..1cf699b70 100644 --- a/doc/gpgv.texi +++ b/doc/gpgv.texi @@ -180,13 +180,20 @@ If set directory used instead of "~/.gnupg". @mansect files @subsection FILES -By default gpgv searches for the keyring holding the allowed keys -in the following locations (First file found is used): +Default keyring file is expected in the GnuPG home directory +(@pxref{option --homedir}, @code{GNUPGHOME}). -@itemize @bullet -@item $@{GNUPGHOME@}/trustedkeys.kbx -@item $@{GNUPGHOME@}/trustedkeys.gpg -@end itemize +@table @file +@item ~/.gnupg/trustedkeys.kbx +@efindex trustedkeys.kbx +The default keyring with the allowed keys, using the new keybox format. + +@item ~/.gnupg/trustedkeys.gpg +@efindex trustedkeys.gpg +When @file{trustedkeys.kbx} is not available, the default keyring with +the allowed keys, using a legacy format. + +@end table @mansect see also @command{gpg}(1) From a33ad8f9bf92d144285769a7d17891c595365fa2 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 Nov 2023 17:04:02 +0100 Subject: [PATCH 254/869] scd: Minor debug output tweak * scd/apdu.c (send_le): Do not dump "[all zero]" if tehre is no data. * scd/iso7816.c (iso7816_select_mf): Cosmetic fix. --- scd/apdu.c | 4 +++- scd/iso7816.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index deb1134e6..7f3c320d2 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -3049,7 +3049,9 @@ send_le (int slot, int class, int ins, int p0, int p1, sw, (unsigned int)resultlen); if ( !retbuf && (sw == SW_SUCCESS || (sw & 0xff00) == SW_MORE_DATA)) { - if (all_zero_p (result, resultlen)) + if (!resultlen) + ; + else if (all_zero_p (result, resultlen)) log_debug (" dump: [all zero]\n"); else log_printhex (result, resultlen, " dump:"); diff --git a/scd/iso7816.c b/scd/iso7816.c index 47e16056c..703f1fdab 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -166,7 +166,7 @@ iso7816_select_mf (int slot) { int sw; - sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE, 0x000, 0x0c, -1, NULL); + sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE, 0x00, 0x0c, -1, NULL); return map_sw (sw); } From 5304c9b080b407bcbf8944ccd3ed669a6ab02616 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 Nov 2023 17:10:08 +0100 Subject: [PATCH 255/869] scd:p15: Basic support for Starcos 3.2. * scd/app-p15.c (CARD_TYPE_STARCOS_32): New. (card_atr_list): Add ATR for my sample card. (cardtype2str): Add starcos string. (select_ef_by_path): Factor all code out to ... (select_by_path): this. Add arg to request a directory. Simplify the case pathlen>1 case. Fix error printing. (select_df_by_path): New. (prepare_verify_pin): For starcos select a DF. (app_select_p15): Don't use extended mode for starcos. -- This allows reading the certificates from my sample cards. Signing does not yet work; I need to do get some I/O traces using other software. The basic support for AET cards shut still work but I have not found my AET card. --- scd/app-p15.c | 85 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 4338a623e..85c28d9a7 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -75,7 +75,8 @@ typedef enum CARD_TYPE_CARDOS_50, CARD_TYPE_CARDOS_53, CARD_TYPE_AET, /* A.E.T. Europe JCOP card. */ - CARD_TYPE_BELPIC /* Belgian eID card specs. */ + CARD_TYPE_BELPIC, /* Belgian eID card specs. */ + CARD_TYPE_STARCOS_32 } card_type_t; @@ -126,6 +127,9 @@ static struct { 24, X("\x3b\xfe\x18\x00\x00\x80\x31\xfe\x45\x53\x43\x45" "\x36\x30\x2d\x43\x44\x30\x38\x31\x2d\x6e\x46\xa9"), CARD_TYPE_AET }, + { 25, X("\x3b\x9f\x96\x81\xb1\xfe\x45\x1f\x07\x00\x64\x05" + "\x1e\xb2\x00\x31\xb0\x73\x96\x21\xdb\x05\x90\x00\x5c"), + CARD_TYPE_STARCOS_32 }, { 0 } }; #undef X @@ -518,6 +522,8 @@ struct app_local_s /*** Local prototypes. ***/ static gpg_error_t select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen); +static gpg_error_t select_df_by_path (app_t app, const unsigned short *path, + size_t pathlen); static gpg_error_t keygrip_from_prkdf (app_t app, prkdf_object_t prkdf); static gpg_error_t readcert_by_cdf (app_t app, cdf_object_t cdf, unsigned char **r_cert, size_t *r_certlen); @@ -538,6 +544,7 @@ cardtype2str (card_type_t cardtype) case CARD_TYPE_CARDOS_53: return "CardOS 5.3"; case CARD_TYPE_BELPIC: return "Belgian eID"; case CARD_TYPE_AET: return "AET"; + case CARD_TYPE_STARCOS_32:return "STARCOS 3.2"; } return ""; } @@ -765,20 +772,28 @@ select_and_read_record (app_t app, unsigned short efid, int recno, /* This function calls select file to read a file using a complete - path which may or may not start at the master file (MF). */ + * path which may or may not start at the master file (MF). If + * EXPECT_DF is set a directory or file is expected - otherwise an + * elementary file expected. */ static gpg_error_t -select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen) +select_by_path (app_t app, const unsigned short *path, size_t pathlen, + int expect_df) { gpg_error_t err; int i, j; + int home_df_used = 0; if (!pathlen) return gpg_error (GPG_ERR_INV_VALUE); - /* log_debug ("%s: path=", __func__); */ - /* for (j=0; j < pathlen; j++) */ - /* log_printf ("%s%04hX", j? "/":"", path[j]); */ - /* log_printf ("%s\n",app->app_local->direct_path_selection?" (direct)":"");*/ + if (opt.debug) + { + log_debug ("%s: path=", __func__); + for (j=0; j < pathlen; j++) + log_printf ("%s%04hX", j? "/":"", path[j]); + log_printf ("%s\n",expect_df?" (DF requested)":""); + log_printf ("%s\n",app->app_local->direct_path_selection?" (direct)":""); + } if (app->app_local->direct_path_selection) { @@ -791,35 +806,17 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen) 0); } else - err = iso7816_select_path (app_get_slot (app), path, pathlen, - app->app_local->home_df); + { + home_df_used = 1; + err = iso7816_select_path (app_get_slot (app), path, pathlen, + app->app_local->home_df); + } if (err) { log_error ("p15: error selecting path "); goto err_print_path; } } - else if (pathlen > 1 && path[0] == 0x3fff) - { - err = iso7816_select_file (app_get_slot (app), 0x3f00, 0); - if (err) - { - log_error ("p15: error selecting part %d from path ", 0); - goto err_print_path; - } - path++; - pathlen--; - for (i=0; i < pathlen; i++) - { - err = iso7816_select_file (app_get_slot (app), - path[i], (i+1 == pathlen)? 2 : 1); - if (err) - { - log_error ("p15: error selecting part %d from path ", i); - goto err_print_path; - } - } - } else { if (pathlen && *path != 0x3f00 ) @@ -829,7 +826,7 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen) for (i=0; i < pathlen; i++) { err = iso7816_select_file (app_get_slot (app), - path[i], !(i+1 == pathlen)); + path[i], (expect_df || (i+1 < pathlen))); if (err) { log_error ("p15: error selecting part %d from path ", i); @@ -842,7 +839,7 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen) err_print_path: if (pathlen && *path != 0x3f00 ) log_printf ("3F00/"); - else + else if (home_df_used) log_printf ("%04hX/", app->app_local->home_df); for (j=0; j < pathlen; j++) log_printf ("%s%04hX", j? "/":"", path[j]); @@ -851,6 +848,20 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen) } +static gpg_error_t +select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen) +{ + return select_by_path (app, path, pathlen, 0); +} + + +static gpg_error_t +select_df_by_path (app_t app, const unsigned short *path, size_t pathlen) +{ + return select_by_path (app, path, pathlen, 1); +} + + /* Parse a cert Id string (or a key Id string) and return the binary object Id string in a newly allocated buffer stored at R_OBJID and R_OBJIDLEN. On Error NULL will be stored there and an error code @@ -3245,7 +3256,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result) if (aodf->max_length_valid) log_printf (" max=%lu", aodf->max_length); if (aodf->pad_char_valid) - log_printf (" pad=0x%02x", aodf->pad_char); + log_printf (" pad=0x%02x", (unsigned char)aodf->pad_char); log_info ("p15: flags="); s = ""; @@ -5023,6 +5034,13 @@ prepare_verify_pin (app_t app, const char *keyref, log_error ("p15: error selecting D-TRUST's AID for key %s: %s\n", keyref, gpg_strerror (err)); } + else if (prkdf && app->app_local->card_type == CARD_TYPE_STARCOS_32) + { + err = select_df_by_path (app, prkdf->path, prkdf->pathlen); + if (err) + log_error ("p15: error selecting file for key %s: %s\n", + keyref, gpg_strerror (err)); + } else if (prkdf) { /* Standard case: Select the key file. Note that this may @@ -6287,6 +6305,7 @@ app_select_p15 (app_t app) direct = 1; break; case CARD_TYPE_AET: + case CARD_TYPE_STARCOS_32: app->app_local->no_extended_mode = 1; break; default: From 960877b10f42ba664af4fb29130a3ba48141e64a Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 24 May 2023 10:36:04 +0900 Subject: [PATCH 256/869] gpg: Report BEGIN_* status before examining the input. * common/miscellaneous.c (is_openpgp_compressed_packet) (is_file_compressed): Moved to ... * common/iobuf.c: ... in this file. (is_file_compressed): Change the argument to INP, the iobuf. * common/util.h (is_file_compressed): Remove. * common/iobuf.h (is_file_compressed): Add. * g10/cipher-aead.c (write_header): Don't call write_status_printf here. (cipher_filter_aead): Call write_status_printf when called with IOBUFCTRL_INIT. * g10/cipher-cfb.c (write_header): Don't call write_status_printf here. (cipher_filter_cfb): Call write_status_printf when called with IOBUFCTRL_INIT. * g10/encrypt.c (encrypt_simple): Use new is_file_compressed function, after call of iobuf_push_filter. (encrypt_crypt): Likewise. * g10/sign.c (sign_file): Likewise. -- Cherry-pick from master commit of: 2f872fa68c6576724b9dabee9fb0844266f55d0d GnuPG-bug-id: 6481 Signed-off-by: NIIBE Yutaka --- common/iobuf.c | 120 +++++++++++++++++++++++++++++++++++++++++ common/iobuf.h | 3 ++ common/miscellaneous.c | 106 ------------------------------------ common/util.h | 2 - g10/cipher-aead.c | 7 ++- g10/cipher-cfb.c | 9 ++-- g10/encrypt.c | 103 ++++++++++++++--------------------- g10/sign.c | 13 +---- 8 files changed, 174 insertions(+), 189 deletions(-) diff --git a/common/iobuf.c b/common/iobuf.c index 161769a35..748e6935d 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -3028,3 +3028,123 @@ iobuf_skip_rest (iobuf_t a, unsigned long n, int partial) } } } + + +/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed + * packet. LEN should be at least 6. */ +static int +is_openpgp_compressed_packet (const unsigned char *buf, size_t len) +{ + int c, ctb, pkttype; + int lenbytes; + + ctb = *buf++; len--; + if (!(ctb & 0x80)) + return 0; /* Invalid packet. */ + + if ((ctb & 0x40)) /* New style (OpenPGP) CTB. */ + { + pkttype = (ctb & 0x3f); + if (!len) + return 0; /* Expected first length octet missing. */ + c = *buf++; len--; + if (c < 192) + ; + else if (c < 224) + { + if (!len) + return 0; /* Expected second length octet missing. */ + } + else if (c == 255) + { + if (len < 4) + return 0; /* Expected length octets missing */ + } + } + else /* Old style CTB. */ + { + pkttype = (ctb>>2)&0xf; + lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); + if (len < lenbytes) + return 0; /* Not enough length bytes. */ + } + + return (pkttype == 8); +} + + +/* + * Check if the file is compressed, by peeking the iobuf. You need to + * pass the iobuf with INP. Returns true if the buffer seems to be + * compressed. + */ +int +is_file_compressed (iobuf_t inp) +{ + int i; + char buf[32]; + int buflen; + + struct magic_compress_s + { + byte len; + byte extchk; + byte magic[5]; + } magic[] = + { + { 3, 0, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */ + { 3, 0, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */ + { 4, 0, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */ + { 5, 0, { '%', 'P', 'D', 'F', '-'} }, /* PDF */ + { 4, 1, { 0xff, 0xd8, 0xff, 0xe0 } }, /* Maybe JFIF */ + { 5, 2, { 0x89, 'P','N','G', 0x0d} } /* Likely PNG */ + }; + + if (!inp) + return 0; + + for ( ; inp->chain; inp = inp->chain ) + ; + + buflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof buf, buf); + if (buflen < 0) + { + buflen = 0; + log_debug ("peeking at input failed\n"); + } + + if ( buflen < 6 ) + { + return 0; /* Too short to check - assume uncompressed. */ + } + + for ( i = 0; i < DIM (magic); i++ ) + { + if (!memcmp( buf, magic[i].magic, magic[i].len)) + { + switch (magic[i].extchk) + { + case 0: + return 1; /* Is compressed. */ + case 1: + if (buflen > 11 && !memcmp (buf + 6, "JFIF", 5)) + return 1; /* JFIF: this likely a compressed JPEG. */ + break; + case 2: + if (buflen > 8 + && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a) + return 1; /* This is a PNG. */ + break; + default: + break; + } + } + } + + if (buflen >= 6 && is_openpgp_compressed_packet (buf, buflen)) + { + return 1; /* Already compressed. */ + } + + return 0; /* Not detected as compressed. */ +} diff --git a/common/iobuf.h b/common/iobuf.h index 751ae73c3..04e6b4421 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -625,6 +625,9 @@ void iobuf_set_partial_body_length_mode (iobuf_t a, size_t len); from the following filter (which may or may not return EOF). */ void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial); +/* Check if the file is compressed, by peeking the iobuf. */ +int is_file_compressed (iobuf_t inp); + #define iobuf_where(a) "[don't know]" /* Each time a filter is allocated (via iobuf_alloc()), a diff --git a/common/miscellaneous.c b/common/miscellaneous.c index f19cc539d..1a090b1f5 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -415,112 +415,6 @@ decode_c_string (const char *src) } -/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed - * packet. LEN should be at least 6. */ -static int -is_openpgp_compressed_packet (const unsigned char *buf, size_t len) -{ - int c, ctb, pkttype; - int lenbytes; - - ctb = *buf++; len--; - if (!(ctb & 0x80)) - return 0; /* Invalid packet. */ - - if ((ctb & 0x40)) /* New style (OpenPGP) CTB. */ - { - pkttype = (ctb & 0x3f); - if (!len) - return 0; /* Expected first length octet missing. */ - c = *buf++; len--; - if (c < 192) - ; - else if (c < 224) - { - if (!len) - return 0; /* Expected second length octet missing. */ - } - else if (c == 255) - { - if (len < 4) - return 0; /* Expected length octets missing */ - } - } - else /* Old style CTB. */ - { - pkttype = (ctb>>2)&0xf; - lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); - if (len < lenbytes) - return 0; /* Not enough length bytes. */ - } - - return (pkttype == 8); -} - - - -/* - * Check if the file is compressed. You need to pass the first bytes - * of the file as (BUF,BUFLEN). Returns true if the buffer seems to - * be compressed. - */ -int -is_file_compressed (const byte *buf, unsigned int buflen) -{ - int i; - - struct magic_compress_s - { - byte len; - byte extchk; - byte magic[5]; - } magic[] = - { - { 3, 0, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */ - { 3, 0, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */ - { 4, 0, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */ - { 5, 0, { '%', 'P', 'D', 'F', '-'} }, /* PDF */ - { 4, 1, { 0xff, 0xd8, 0xff, 0xe0 } }, /* Maybe JFIF */ - { 5, 2, { 0x89, 'P','N','G', 0x0d} } /* Likely PNG */ - }; - - if ( buflen < 6 ) - { - return 0; /* Too short to check - assume uncompressed. */ - } - - for ( i = 0; i < DIM (magic); i++ ) - { - if (!memcmp( buf, magic[i].magic, magic[i].len)) - { - switch (magic[i].extchk) - { - case 0: - return 1; /* Is compressed. */ - case 1: - if (buflen > 11 && !memcmp (buf + 6, "JFIF", 5)) - return 1; /* JFIF: this likely a compressed JPEG. */ - break; - case 2: - if (buflen > 8 - && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a) - return 1; /* This is a PNG. */ - break; - default: - break; - } - } - } - - if (buflen >= 6 && is_openpgp_compressed_packet (buf, buflen)) - { - return 1; /* Already compressed. */ - } - - return 0; /* Not detected as compressed. */ -} - - /* Try match against each substring of multistr, delimited by | */ int match_multistr (const char *multistr,const char *match) diff --git a/common/util.h b/common/util.h index 875969187..fff2e6e83 100644 --- a/common/util.h +++ b/common/util.h @@ -367,8 +367,6 @@ char *try_make_printable_string (const void *p, size_t n, int delim); char *make_printable_string (const void *p, size_t n, int delim); char *decode_c_string (const char *src); -int is_file_compressed (const byte *buf, unsigned int buflen); - int match_multistr (const char *multistr,const char *match); int gnupg_compare_version (const char *a, const char *b); diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c index 640d8432f..0c07e65de 100644 --- a/g10/cipher-aead.c +++ b/g10/cipher-aead.c @@ -174,8 +174,6 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) log_debug ("aead packet: len=%lu extralen=%d\n", (unsigned long)ed.len, ed.extralen); - write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d", - cfx->dek->algo, ed.aead_algo); print_cipher_algo_note (cfx->dek->algo); if (build_packet( a, &pkt)) @@ -488,6 +486,11 @@ cipher_filter_aead (void *opaque, int control, { mem2str (buf, "cipher_filter_aead", *ret_len); } + else if (control == IOBUFCTRL_INIT) + { + write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d", + cfx->dek->algo, cfx->dek->use_aead); + } return rc; } diff --git a/g10/cipher-cfb.c b/g10/cipher-cfb.c index 3ba8eb738..29bf2477c 100644 --- a/g10/cipher-cfb.c +++ b/g10/cipher-cfb.c @@ -72,9 +72,6 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) log_info (_("Hint: Do not use option %s\n"), "--rfc2440"); } - write_status_printf (STATUS_BEGIN_ENCRYPTION, "%d %d", - ed.mdc_method, cfx->dek->algo); - init_packet (&pkt); pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED; pkt.pkt.encrypted = &ed; @@ -182,6 +179,12 @@ cipher_filter_cfb (void *opaque, int control, { mem2str (buf, "cipher_filter_cfb", *ret_len); } + else if (control == IOBUFCTRL_INIT) + { + write_status_printf (STATUS_BEGIN_ENCRYPTION, "%d %d", + cfx->dek->use_mdc ? DIGEST_ALGO_SHA1 : 0, + cfx->dek->algo); + } return rc; } diff --git a/g10/encrypt.c b/g10/encrypt.c index 9aeafa292..b335b9797 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -410,8 +410,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) text_filter_context_t tfx; progress_filter_context_t *pfx; int do_compress = !!default_compress_algo(); - char peekbuf[32]; - int peekbuflen; if (!gnupg_rng_is_compliant (opt.compliance)) { @@ -448,14 +446,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) return rc; } - peekbuflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof peekbuf, peekbuf); - if (peekbuflen < 0) - { - peekbuflen = 0; - if (DBG_FILTER) - log_debug ("peeking at input failed\n"); - } - handle_progress (pfx, inp, filename); if (opt.textmode) @@ -517,17 +507,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) /**/ : "CFB"); } - if (do_compress - && cfx.dek - && (cfx.dek->use_mdc || cfx.dek->use_aead) - && !opt.explicit_compress_option - && is_file_compressed (peekbuf, peekbuflen)) - { - if (opt.verbose) - log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); - do_compress = 0; - } - if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, 0, &out ))) { iobuf_cancel (inp); @@ -598,6 +577,24 @@ encrypt_simple (const char *filename, int mode, int use_seskey) else filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ + /* Register the cipher filter. */ + if (mode) + iobuf_push_filter (out, + cfx.dek->use_aead? cipher_filter_aead + /**/ : cipher_filter_cfb, + &cfx ); + + if (do_compress + && cfx.dek + && (cfx.dek->use_mdc || cfx.dek->use_aead) + && !opt.explicit_compress_option + && is_file_compressed (inp)) + { + if (opt.verbose) + log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); + do_compress = 0; + } + if (!opt.no_literal) { /* Note that PT has been initialized above in !no_literal mode. */ @@ -617,13 +614,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) pkt.pkt.generic = NULL; } - /* Register the cipher filter. */ - if (mode) - iobuf_push_filter (out, - cfx.dek->use_aead? cipher_filter_aead - /**/ : cipher_filter_cfb, - &cfx ); - /* Register the compress filter. */ if ( do_compress ) { @@ -783,7 +773,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, PKT_plaintext *pt = NULL; DEK *symkey_dek = NULL; STRING2KEY *symkey_s2k = NULL; - int rc = 0, rc2 = 0; + int rc = 0; u32 filesize; cipher_filter_context_t cfx; armor_filter_context_t *afx = NULL; @@ -792,8 +782,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, progress_filter_context_t *pfx; PK_LIST pk_list; int do_compress; - char peekbuf[32]; - int peekbuflen; if (filefd != -1 && filename) return gpg_error (GPG_ERR_INV_ARG); /* Both given. */ @@ -866,14 +854,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, if (opt.verbose) log_info (_("reading from '%s'\n"), iobuf_get_fname_nonnull (inp)); - peekbuflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof peekbuf, peekbuf); - if (peekbuflen < 0) - { - peekbuflen = 0; - if (DBG_FILTER) - log_debug ("peeking at input failed\n"); - } - handle_progress (pfx, inp, filename); if (opt.textmode) @@ -900,25 +880,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, if (!cfx.dek->use_aead) cfx.dek->use_mdc = !!use_mdc (pk_list, cfx.dek->algo); - /* Only do the is-file-already-compressed check if we are using a - * MDC or AEAD. This forces compressed files to be re-compressed if - * we do not have a MDC to give some protection against chosen - * ciphertext attacks. */ - if (do_compress - && (cfx.dek->use_mdc || cfx.dek->use_aead) - && !opt.explicit_compress_option - && is_file_compressed (peekbuf, peekbuflen)) - { - if (opt.verbose) - log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); - do_compress = 0; - } - if (rc2) - { - rc = rc2; - goto leave; - } - make_session_key (cfx.dek); if (DBG_CRYPTO) log_printhex (cfx.dek->key, cfx.dek->keylen, "DEK is: "); @@ -959,6 +920,26 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, else filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ + /* Register the cipher filter. */ + iobuf_push_filter (out, + cfx.dek->use_aead? cipher_filter_aead + /**/ : cipher_filter_cfb, + &cfx); + + /* Only do the is-file-already-compressed check if we are using a + * MDC or AEAD. This forces compressed files to be re-compressed if + * we do not have a MDC to give some protection against chosen + * ciphertext attacks. */ + if (do_compress + && (cfx.dek->use_mdc || cfx.dek->use_aead) + && !opt.explicit_compress_option + && is_file_compressed (inp)) + { + if (opt.verbose) + log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); + do_compress = 0; + } + if (!opt.no_literal) { pt->timestamp = make_timestamp(); @@ -973,12 +954,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, else cfx.datalen = filesize && !do_compress ? filesize : 0; - /* Register the cipher filter. */ - iobuf_push_filter (out, - cfx.dek->use_aead? cipher_filter_aead - /**/ : cipher_filter_cfb, - &cfx); - /* Register the compress filter. */ if (do_compress) { diff --git a/g10/sign.c b/g10/sign.c index f9984f811..d6ab396af 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1034,9 +1034,6 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, int multifile = 0; u32 duration=0; pt_extra_hash_data_t extrahash = NULL; - char peekbuf[32]; - int peekbuflen = 0; - pfx = new_progress_context (); afx = new_armor_context (); @@ -1095,14 +1092,6 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, goto leave; } - peekbuflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof peekbuf, peekbuf); - if (peekbuflen < 0) - { - peekbuflen = 0; - if (DBG_FILTER) - log_debug ("peeking at input failed\n"); - } - handle_progress (pfx, inp, fname); } @@ -1260,7 +1249,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, int compr_algo = opt.compress_algo; if (!opt.explicit_compress_option - && is_file_compressed (peekbuf, peekbuflen)) + && is_file_compressed (inp)) { if (opt.verbose) log_info(_("'%s' already compressed\n"), fname? fname: "[stdin]"); From 2fa916ebff0b815dbb1b7a2d01e1d989a0cbbbb5 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 20 Nov 2023 10:53:09 +0900 Subject: [PATCH 257/869] po: Update Japanese Translation. -- Signed-off-by: NIIBE Yutaka --- po/ja.po | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/po/ja.po b/po/ja.po index d9a1dcd71..d067bf202 100644 --- a/po/ja.po +++ b/po/ja.po @@ -9,9 +9,9 @@ # msgid "" msgstr "" -"Project-Id-Version: gnupg 2.4.1\n" +"Project-Id-Version: gnupg 2.4.3\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-05-25 11:12+0900\n" +"PO-Revision-Date: 2023-11-20 10:50+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -226,8 +226,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"パスフレーズを入力してください。gpg-agentの鍵の保管で受信した秘密鍵%%0A %s" -"%%0A %s%%0Aを保護します。" +"パスフレーズを入力してください。gpg-agentの鍵の保管で受信した秘密鍵%%0A " +"%s%%0A %s%%0Aを保護します。" #, c-format msgid "failed to create stream from socket: %s\n" @@ -755,8 +755,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "本当にこの鍵: keygrip%%0A %s%%0A %%C%%0Aを削除しますか?" msgid "Delete key" @@ -1788,14 +1788,14 @@ msgstr "S2Kモードのため、SKESKパケットを使えません\n" msgid "using cipher %s.%s\n" msgstr "暗号方式 %s.%s を使います\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s'はもう圧縮済みです\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "*警告*: '%s'は空のファイルです\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s'はもう圧縮済みです\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "ダイジェスト・アルゴリズム'%s'を%sモードで使うことはできません\n" @@ -1869,7 +1869,7 @@ msgstr "'%s'への書き込み\n" #, c-format msgid "key %s: key material on-card - skipped\n" -msgstr "鍵%s: 鍵マテリアルはカード上にあります - スキップします\n" +msgstr "鍵%s: 鍵の実体はカード上にあります - スキップします\n" #, c-format msgid "exporting secret keys not allowed\n" @@ -2893,7 +2893,7 @@ msgstr "鍵 %s: エージェントへの送信エラー: %s\n" #, c-format msgid "key %s: card reference is overridden by key material\n" -msgstr "鍵 %s: カード参照が鍵マテリアルで上書きされます\n" +msgstr "鍵 %s: カード参照が鍵の実体で上書きされます\n" #. TRANSLATORS: For a smartcard, each private key on host has a #. * reference (stub) to a smartcard and actual private key data From e43bd2a7a7831a2d23fb9aa06b913f17dad89478 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 17 Nov 2023 14:40:38 +0100 Subject: [PATCH 258/869] scd: New option --debug-allow-pin-logging. * scd/scdaemon.c (oDebugAllowPINLogging): New. (opts): Add option. (main): Set option. * scd/scdaemon.h (opt): Add debug_allow_pin_logging. * scd/apdu.c (pcsc_send_apdu): Do not hide the PIN dat in the debug output if the option is set. (send_apdu_ccid): Ditto. -- This option is only required during development. --- scd/apdu.c | 8 ++++---- scd/scdaemon.c | 5 +++++ scd/scdaemon.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/scd/apdu.c b/scd/apdu.c index 7f3c320d2..98158648b 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -775,8 +775,8 @@ pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, if (DBG_CARD_IO) { /* Do not dump the PIN in a VERIFY command. */ - if (apdulen > 5 && apdu[1] == 0x20) - log_debug ("PCSC_data: %02X %02X %02X %02X %02X [redacted]\n", + if (apdulen > 5 && apdu[1] == 0x20 && !opt.debug_allow_pin_logging) + log_debug ("PCSC_data: %02X %02X %02X %02X %02X [hidden]\n", apdu[0], apdu[1], apdu[2], apdu[3], apdu[4]); else log_printhex (apdu, apdulen, "PCSC_data:"); @@ -1564,8 +1564,8 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, if (DBG_CARD_IO) { /* Do not dump the PIN in a VERIFY command. */ - if (apdulen > 5 && apdu[1] == 0x20) - log_debug (" raw apdu: %02x%02x%02x%02x%02x [redacted]\n", + if (apdulen > 5 && apdu[1] == 0x20 && !opt.debug_allow_pin_logging) + log_debug (" raw apdu: %02x%02x%02x%02x%02x [hidden]\n", apdu[0], apdu[1], apdu[2], apdu[3], apdu[4]); else log_printhex (apdu, apdulen, " raw apdu:"); diff --git a/scd/scdaemon.c b/scd/scdaemon.c index e43769f85..ed7fdc03a 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -79,6 +79,7 @@ enum cmd_and_opt_values oDebugAllowCoreDump, oDebugCCIDDriver, oDebugLogTid, + oDebugAllowPINLogging, oDebugAssuanLogCats, oNoGreeting, oNoOptions, @@ -138,6 +139,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oDebugAllowCoreDump, "debug-allow-core-dump", "@"), ARGPARSE_s_n (oDebugCCIDDriver, "debug-ccid-driver", "@"), ARGPARSE_s_n (oDebugLogTid, "debug-log-tid", "@"), + ARGPARSE_s_n (oDebugAllowPINLogging, "debug-allow-pin-logging", "@"), ARGPARSE_p_u (oDebugAssuanLogCats, "debug-assuan-log-cats", "@"), ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write a log to FILE")), @@ -587,6 +589,9 @@ main (int argc, char **argv ) case oDebugLogTid: log_set_pid_suffix_cb (tid_log_callback); break; + case oDebugAllowPINLogging: + opt.debug_allow_pin_logging = 1; + break; case oDebugAssuanLogCats: set_libassuan_log_cats (pargs.r.ret_ulong); break; diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 68136b886..7b82d1b21 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -66,6 +66,7 @@ struct strlist_t disabled_applications; /* Card applications we do not want to use. */ unsigned long card_timeout; /* Disconnect after N seconds of inactivity. */ + int debug_allow_pin_logging; /* Allow PINs in debug output. */ } opt; From cf2d3f7ba0b7ffd0f1c014186fb60630c132dba1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 21 Nov 2023 08:34:04 +0100 Subject: [PATCH 259/869] agent: Update the key file only if not changed. * common/name-value.c (struct name_value_container): Add flag "modified". (nvc_modified): New. (nvc_new): Set flag. (_nvc_add): Set flag. (nvc_delete): Set flag. (nvc_set): Set flag unless value did not change. (nve_set): Add arg PK. Change the caller. * agent/findkey.c (agent_write_private_key): Update only if modified. -- This helps software which uses a file system watcher to track changes to private keys. In particular smartcard triggered changes are a problem for such software because this may at worst trigger another smartcard read. GnuPG-bug-id: 6829 --- agent/findkey.c | 11 ++++++++++- common/name-value.c | 47 +++++++++++++++++++++++++++++++++++++++------ common/name-value.h | 7 +++++-- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/agent/findkey.c b/agent/findkey.c index a5f022574..9e5550225 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -146,6 +146,8 @@ agent_write_private_key (const unsigned char *grip, } } + nvc_modified (pk, 1); /* Clear that flag after a read. */ + if (!pk) { /* Key is still in the old format or does not exist - create a @@ -242,7 +244,7 @@ agent_write_private_key (const unsigned char *grip, ; /* No need to update Token entry. */ else { - err = nve_set (item, token); + err = nve_set (pk, item, token); if (err) goto leave; } @@ -263,6 +265,13 @@ agent_write_private_key (const unsigned char *grip, goto leave; } + /* Check whether we need to write the file at all. */ + if (!nvc_modified (pk, 0)) + { + err = 0; + goto leave; + } + /* Create a temporary file for writing. */ tmpfname = fname_from_keygrip (grip, 1); fp = tmpfname ? es_fopen (tmpfname, "wbx,mode=-rw") : NULL; diff --git a/common/name-value.c b/common/name-value.c index 0dffc63b4..b7bc32844 100644 --- a/common/name-value.c +++ b/common/name-value.c @@ -48,6 +48,7 @@ struct name_value_container struct name_value_entry *first; struct name_value_entry *last; unsigned int private_key_mode:1; + unsigned int modified:1; }; @@ -87,11 +88,15 @@ my_error (gpg_err_code_t ec) /* Allocation and deallocation. */ -/* Allocate a private key container structure. */ +/* Allocate a name value container structure. */ nvc_t nvc_new (void) { - return xtrycalloc (1, sizeof (struct name_value_container)); + nvc_t nvc; + nvc = xtrycalloc (1, sizeof (struct name_value_container)); + if (nvc) + nvc->modified = 1; + return nvc; } @@ -142,6 +147,24 @@ nvc_release (nvc_t pk) xfree (pk); } + +/* Return the modified-flag of the container and clear it if CLEAR is + * set. That flag is set for a new container and set with each + * update. */ +int +nvc_modified (nvc_t pk, int clear) +{ + int modified; + + if (!pk) + return 0; + modified = pk->modified; + if (clear) + pk->modified = 0; + return modified; +} + + /* Dealing with names and values. */ @@ -427,6 +450,8 @@ _nvc_add (nvc_t pk, char *name, char *value, strlist_t raw_value, else pk->first = pk->last = e; + pk->modified = 1; + leave: if (err) { @@ -470,6 +495,7 @@ gpg_error_t nvc_set (nvc_t pk, const char *name, const char *value) { nve_t e; + char *v; if (! valid_name (name)) return GPG_ERR_INV_NAME; @@ -477,7 +503,12 @@ nvc_set (nvc_t pk, const char *name, const char *value) e = nvc_lookup (pk, name); if (e) { - char *v; + if (e->value && value && !strcmp (e->value, value)) + { + /* Setting same value - ignore this call and don't set the + * modified flag. */ + return 0; + } v = xtrystrdup (value); if (v == NULL) @@ -489,7 +520,7 @@ nvc_set (nvc_t pk, const char *name, const char *value) wipememory (e->value, strlen (e->value)); xfree (e->value); e->value = v; - + pk->modified = 1; return 0; } else @@ -497,9 +528,10 @@ nvc_set (nvc_t pk, const char *name, const char *value) } -/* Update entry E to VALUE. */ +/* Update entry E to VALUE. PK is optional; if given its modified + * flag will be updated. */ gpg_error_t -nve_set (nve_t e, const char *value) +nve_set (nvc_t pk, nve_t e, const char *value) { char *v; @@ -516,6 +548,8 @@ nve_set (nve_t e, const char *value) wipememory (e->value, strlen (e->value)); xfree (e->value); e->value = v; + if (pk) + pk->modified = 1; return 0; } @@ -536,6 +570,7 @@ nvc_delete (nvc_t pk, nve_t entry) pk->last = entry->prev; nve_release (entry, pk->private_key_mode); + pk->modified = 1; } diff --git a/common/name-value.h b/common/name-value.h index b3fc2f63c..dfded6678 100644 --- a/common/name-value.h +++ b/common/name-value.h @@ -50,6 +50,9 @@ nvc_t nvc_new_private_key (void); /* Release a name value container structure. */ void nvc_release (nvc_t pk); +/* Return the modified flag and optionally clear it. */ +int nvc_modified (nvc_t pk, int clear); + /* Get the name. */ char *nve_name (nve_t pke); @@ -92,8 +95,8 @@ gpg_error_t nvc_add (nvc_t pk, const char *name, const char *value); first entry is updated. */ gpg_error_t nvc_set (nvc_t pk, const char *name, const char *value); -/* Update entry E to VALUE. */ -gpg_error_t nve_set (nve_t e, const char *value); +/* Update entry E to VALUE. PK is optional. */ +gpg_error_t nve_set (nvc_t pk, nve_t e, const char *value); /* Delete the given entry from PK. */ void nvc_delete (nvc_t pk, nve_t pke); From 813bb65d952d7d02039f8c04c18cc74a512eacf7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 21 Nov 2023 08:55:56 +0100 Subject: [PATCH 260/869] common: Check wether to set the modified flag in nve_set. * common/name-value.c (nvc_set): Factor code out to ... (nve_set): here. --- common/name-value.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/common/name-value.c b/common/name-value.c index b7bc32844..ea6a84f56 100644 --- a/common/name-value.c +++ b/common/name-value.c @@ -495,34 +495,13 @@ gpg_error_t nvc_set (nvc_t pk, const char *name, const char *value) { nve_t e; - char *v; if (! valid_name (name)) return GPG_ERR_INV_NAME; e = nvc_lookup (pk, name); if (e) - { - if (e->value && value && !strcmp (e->value, value)) - { - /* Setting same value - ignore this call and don't set the - * modified flag. */ - return 0; - } - - v = xtrystrdup (value); - if (v == NULL) - return my_error_from_syserror (); - - free_strlist_wipe (e->raw_value); - e->raw_value = NULL; - if (e->value) - wipememory (e->value, strlen (e->value)); - xfree (e->value); - e->value = v; - pk->modified = 1; - return 0; - } + return nve_set (pk, e, value); else return nvc_add (pk, name, value); } @@ -538,6 +517,13 @@ nve_set (nvc_t pk, nve_t e, const char *value) if (!e) return GPG_ERR_INV_ARG; + if (e->value && value && !strcmp (e->value, value)) + { + /* Setting same value - ignore this call and don't set the + * modified flag (if PK is given). */ + return 0; + } + v = xtrystrdup (value? value:""); if (!v) return my_error_from_syserror (); From 09329d52b5f0e1dba32d44cecc8c50ab57cb31bd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 21 Nov 2023 12:13:50 +0100 Subject: [PATCH 261/869] agent: Update the key file only if changed (slight return). * agent/findkey.c (read_key_file): Add optional arg r_orig_key_value to return the old Key value. Change all callers. (agent_write_private_key): Detect whether the Key entry was really changed. -- GnuPG-bug-id: 6829 --- agent/findkey.c | 64 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/agent/findkey.c b/agent/findkey.c index 9e5550225..4e55119e3 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -41,7 +41,8 @@ static gpg_error_t read_key_file (const unsigned char *grip, - gcry_sexp_t *result, nvc_t *r_keymeta); + gcry_sexp_t *result, nvc_t *r_keymeta, + char **r_orig_key_value); static gpg_error_t is_shadowed_key (gcry_sexp_t s_skey); @@ -129,12 +130,15 @@ agent_write_private_key (const unsigned char *grip, char **tokenfields = NULL; int is_regular; int blocksigs = 0; + char *orig_key_value = NULL; + const char *s; + int force_modify = 0; fname = fname_from_keygrip (grip, 0); if (!fname) return gpg_error_from_syserror (); - err = read_key_file (grip, &key, &pk); + err = read_key_file (grip, &key, &pk, &orig_key_value); if (err) { if (gpg_err_code (err) == GPG_ERR_ENOENT) @@ -158,6 +162,7 @@ agent_write_private_key (const unsigned char *grip, err = gpg_error_from_syserror (); goto leave; } + force_modify = 1; } /* Check whether we already have a regular key. */ @@ -173,6 +178,19 @@ agent_write_private_key (const unsigned char *grip, if (err) goto leave; + /* Detect whether the key value actually changed and if not clear + * the modified flag. This extra check is required because + * read_key_file removes the Key entry from the container and we + * then create a new Key entry which might be the same, though. */ + if (!force_modify + && orig_key_value && (s = nvc_get_string (pk, "Key:")) + && !strcmp (orig_key_value, s)) + { + nvc_modified (pk, 1); /* Clear that flag. */ + } + xfree (orig_key_value); + orig_key_value = NULL; + /* Check that we do not update a regular key with a shadow key. */ if (is_regular && gpg_err_code (is_shadowed_key (key)) == GPG_ERR_TRUE) { @@ -194,7 +212,6 @@ agent_write_private_key (const unsigned char *grip, if (serialno && keyref) { nve_t item; - const char *s; size_t token0len; if (dispserialno) @@ -319,6 +336,7 @@ agent_write_private_key (const unsigned char *grip, es_fclose (fp); if (removetmp && tmpfname) gnupg_remove (tmpfname); + xfree (orig_key_value); xfree (fname); xfree (tmpfname); xfree (token); @@ -865,10 +883,13 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, * return it as an gcrypt S-expression object in RESULT. If R_KEYMETA * is not NULL and the extended key format is used, the meta data * items are stored there. However the "Key:" item is removed from - * it. On failure returns an error code and stores NULL at RESULT and - * R_KEYMETA. */ + * it. If R_ORIG_KEY_VALUE is non-NULL and the Key item was removed, + * its original value is stored at that R_ORIG_KEY_VALUE and the + * caller must free it. On failure returns an error code and stores + * NULL at RESULT and R_KEYMETA. */ static gpg_error_t -read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta) +read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, + char **r_orig_key_value) { gpg_error_t err; char *fname; @@ -882,6 +903,8 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta) *result = NULL; if (r_keymeta) *r_keymeta = NULL; + if (r_orig_key_value) + *r_orig_key_value = NULL; fname = fname_from_keygrip (grip, 0); if (!fname) @@ -936,7 +959,24 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta) log_error ("error getting private key from '%s': %s\n", fname, gpg_strerror (err)); else - nvc_delete_named (pk, "Key:"); + { + if (r_orig_key_value) + { + const char *s = nvc_get_string (pk, "Key:"); + if (s) + { + *r_orig_key_value = xtrystrdup (s); + if (!*r_orig_key_value) + { + err = gpg_error_from_syserror (); + nvc_release (pk); + xfree (fname); + return err; + } + } + } + nvc_delete_named (pk, "Key:"); + } } if (!err && r_keymeta) @@ -1186,7 +1226,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, if (!grip && !ctrl->have_keygrip) return gpg_error (GPG_ERR_NO_SECKEY); - err = read_key_file (grip? grip : ctrl->keygrip, &s_skey, &keymeta); + err = read_key_file (grip? grip : ctrl->keygrip, &s_skey, &keymeta, NULL); if (err) { if (gpg_err_code (err) == GPG_ERR_ENOENT) @@ -1445,7 +1485,7 @@ agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip, *result = NULL; - err = read_key_file (grip, &s_skey, r_keymeta); + err = read_key_file (grip, &s_skey, r_keymeta, NULL); if (!err) *result = s_skey; return err; @@ -1488,7 +1528,7 @@ public_key_from_file (ctrl_t ctrl, const unsigned char *grip, if (r_sshorder) *r_sshorder = 0; - err = read_key_file (grip, &s_skey, for_ssh? &keymeta : NULL); + err = read_key_file (grip, &s_skey, for_ssh? &keymeta : NULL, NULL); if (err) return err; @@ -1660,7 +1700,7 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, { gcry_sexp_t sexp; - err = read_key_file (grip, &sexp, NULL); + err = read_key_file (grip, &sexp, NULL, NULL); if (err) { if (gpg_err_code (err) == GPG_ERR_ENOENT) @@ -1744,7 +1784,7 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text, char *default_desc = NULL; int key_type; - err = read_key_file (grip, &s_skey, NULL); + err = read_key_file (grip, &s_skey, NULL, NULL); if (gpg_err_code (err) == GPG_ERR_ENOENT) err = gpg_error (GPG_ERR_NO_SECKEY); if (err) From 4c456bf07508cb65f4937394afc1ee18f1fd2655 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 23 Nov 2023 16:01:58 +0100 Subject: [PATCH 262/869] scd:openpgp: Fallback to default ECDH params in writekey. * scd/app-openpgp.c (ecc_writekey): Use default ECDH parameters and remove the now useless check. -- This seems to be better than bailing out. In almost all cases our standard parameters are used and if not, well, the fingerprint will be wrong. GnuPG-bug-id: 6378 --- scd/app-openpgp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 014cd9395..3e77f8540 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -4733,9 +4733,11 @@ ecc_writekey (app_t app, ctrl_t ctrl, if (algo == PUBKEY_ALGO_ECDH && !ecdh_param) { - log_error ("opgp: ecdh parameters missing\n"); - err = gpg_error (GPG_ERR_INV_VALUE); - goto leave; + /* In case this is used by older clients we fallback to our + * default ecc parameters. */ + log_info ("opgp: using default ecdh parameters\n"); + ecdh_param = ecdh_params (curve); + ecdh_param_len = 4; } oidstr = openpgp_curve_to_oid (curve, &n, NULL); From 73aa6dc6e41f16fd0b4fdd52c4a01a9f29ab9fea Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 27 Nov 2023 12:34:38 +0100 Subject: [PATCH 263/869] gpgsm: Set validity flag in keylisting to n for untrusted root cert. * sm/keylist.c (list_cert_colon): Map not_trusted to 'n' for non-root certs like we do for root certs. -- GnuPG-bug-id: 6841 --- sm/keylist.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sm/keylist.c b/sm/keylist.c index ed1b74729..47fe69f30 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -532,6 +532,8 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity, { if (gpgsm_cert_has_well_known_private_key (cert)) *truststring = 'w'; /* Well, this is dummy CA. */ + else if (gpg_err_code (valerr) == GPG_ERR_NOT_TRUSTED) + *truststring = 'n'; /* Likely the root cert is not trusted. */ else *truststring = 'i'; } From a14f73a1921e6cd002a58ff8a5ba3d39129729f3 Mon Sep 17 00:00:00 2001 From: Daniel Cerqueira Date: Wed, 29 Nov 2023 13:54:47 +0000 Subject: [PATCH 264/869] po: Update Portuguese Translation. -- This commit log (with no ChangeLog entry) is written by gniibe, following the practice; Translation update don't need a ChangeLog entry in a commit log. Signed-off-by: Daniel Cerqueira --- doc/help.pt.txt | 413 ++- po/pt.po | 8886 +++++++++++++++++------------------------------ 2 files changed, 3531 insertions(+), 5768 deletions(-) diff --git a/doc/help.pt.txt b/doc/help.pt.txt index da9a18153..95bd3f650 100644 --- a/doc/help.pt.txt +++ b/doc/help.pt.txt @@ -1,4 +1,4 @@ -# help.pt.txt - pt GnuPG online help +# help.pt.txt - Portuguese GnuPG online help # Copyright (C) 2007 Free Software Foundation, Inc. # # This file is part of GnuPG. @@ -7,247 +7,436 @@ # 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 . +# Note that this help file needs to be UTF-8 encoded. When looking +# for a help item, GnuPG scans the help files in the following order +# (assuming a GNU or Unix system): +# +# /etc/gnupg/help.LL_TT.txt +# /etc/gnupg/help.LL.txt +# /etc/gnupg/help.txt +# /usr/share/gnupg/help.LL_TT.txt +# /usr/share/gnupg/help.LL.txt +# /usr/share/gnupg/help.txt +# +# Here LL_TT denotes the full name of the current locale with the +# territory (.e.g. "de_DE"), LL denotes just the locale name +# (e.g. "de"). The first matching item is returned. To put a dot or +# a hash mark at the beginning of a help text line, it needs to be +# prefixed with ". ". A single dot may be used to terminated a help +# entry. + +.pinentry.qualitybar.tooltip +# [remove the hash mark from the key to enable this text] +# This entry is just an example on how to customize the tooltip shown +# when hovering over the quality bar of the pinentry. We don't +# install this text so that the hardcoded translation takes +# precedence. An administrator should write up a short help to tell +# the users about the configured passphrase constraints and save that +# to /etc/gnupg/help.txt. The help text should not be longer than +# about 800 characters. +Esta barra indica a qualidade da frase-secreta introduzida acima. + +Enquanto a barra estiver vermelha, o GnuPG considera a frase-secreta +demasiada fraca para a aceitar. Peça ao seu administrador detalhes +sobre as restrições de frase-secreta configuradas. +. + +.pinentry.constraints.hint.short +# [remove the hash mark from the key to enable this hint] +# This entry is used by some pinentries to display a hint about +# enabled passphrase constraints. These constraints are configurable +# and the admin may give a hint about them by using this help entry. +Use letras e dígitos. +. + +.pinentry.constraints.hint.long +# [remove the hash mark from the key to enable this hint] +# This entry is used by some pinentries to show a tooltip with more +# information about the configured passphrase constraints. +Use letras e dígitos. +Restrições extras são impostas, por exemplo +o uso de matrículas comuns de veículos. +. + +.pinentry.formatted_passphrase.hint", +# [remove the hash mark from the key to enable this hint] +# If this entry is not set a standard text is shown +Nota: Os espaços em branco não fazem parte da frase-secreta. +. + +.gnupg.agent-problem +# There was a problem accessing or starting the agent. +Não foi possível conectar-se a um Gpg-Agent em execução ou +ocorreu um problema de comunicação com um agent em execução. + +O sistema usa um processo em segundo plano, chamado Gpg-Agent, para +procestamento chaves privadas e pedir frase-secretas. O agent +geralmente é iniciado quando o utilizador faz login e é executado, +enquanto o utilizador estiver logado. Caso nenhum agent esteja +disponível, o sistema tenta iniciar um em tempo real mas esta versão +do agent é um pouco limitada em funcionalidade e assim, pode levar a +pequenos problemas. + +Você provavelmente precisa perguntar ao seu administrador sobre como +resolver o problema. Como solução alternativa, você pode tentar sair +e entrar na sua sessão e ver se isso ajuda. Se isso ajudar, por +favor, informe mesmo assim o administrador, porque isto indica um bug +no software. +. + +.gnupg.dirmngr-problem +# There was a problen accessing the dirmngr. +Não foi possível conectar-se a um Dirmngr em execução ou ocorreu um +problema de comunicação com um Dirmngr em execução. + +Para pesquisar listas de revogação de certificados (CRLs), executar +validação OCSP e para pesquisar chaves através de servidores LDAP, o +sistema usa um programa de serviço externo chamado Dirmngr. O Dirmngr +geralmente está em execução como um serviço do sistema (daemon) e não +precisa de qualquer atenção por parte do utilizador. Em caso de +problemas, o sistema poderá iniciar sua própria cópia do Dirmngr tendo +por base uma requisição; esta é a solução alternativa e produz +desempenho limitado. + +Se você encontrar este problema, você deve perguntar ao seu +administrador de sistema como proceder. Como uma solução provisória, +você pode tentar desabilitar a verificação de CRL na configuração do +gpgsm. +. + .gpg.edit_ownertrust.value -Você decide que valor usar aqui; este valor nunca será exportado para -terceiros. Precisamos dele implementar a rede de confiança, que não tem -nada a ver com a rede de certificados (implicitamente criada). +# The help identies prefixed with "gpg." used to be hard coded in gpg +# but may now be overridden by help texts from this file. +Cabe a você atribuir um valor aqui; este valor nunca será exportado a +quaisquer terceiros. Precisamos dele para implementar a +Rede-da-Confiança; que tem nada a ver com a rede-de-certificados +(criada implicitamente). . .gpg.edit_ownertrust.set_ultimate.okay -Para construir a Teia-de-Confiança ('Web-of-Trust'), o GnuPG precisa de -saber quais são as chaves em que deposita confiança absoluta - normalmente -estas são as chaves a que tem acesso à chave privada. Responda "sim" para -que esta chave seja de confiança absoluta. - +Para construir a Rede-da-Confiança, o GnuPG precisa saber quais são as +chaves plenamente confiáveis - essas são geralmente as chaves +para as quais você tem acesso à chave secreta. Responder "sim" para +definir esta chave como plenamente confiável. . .gpg.untrusted_key.override -Se você quiser usar esta chave, não de confiança, assim mesmo, responda "sim". +Se você, mesmo assim, quiser usar esta chave não confiável, responder +"sim". . .gpg.pklist.user_id.enter -Digite o ID de utilizador do destinatário para quem quer enviar a -mensagem. +Introduzir a ID de utilizador do destinatário para quem você deseja +enviar a mensagem. . -.#gpg.keygen.algo -# fixme: Please translate and remove the hash mark from the key line. -Select the algorithm to use. +.gpg.keygen.algo +Selecionar o algoritmo a ser usado. -DSA (aka DSS) is the Digital Signature Algorithm and can only be used -for signatures. +DSA (aka DSS) é o Algoritmo de Assinatura Digital e só pode ser usado +para assinaturas. -Elgamal is an encrypt-only algorithm. +Elgamal é um algoritmo só para cifração. -RSA may be used for signatures or encryption. +O RSA pode ser usado para assinaturas ou cifração. -The first (primary) key must always be a key which is capable of signing. +A primeira chave (principal) deve ser sempre uma chave capaz de +assinar. . .gpg.keygen.algo.rsa_se -Em geral não é uma boa ideia utilizar a mesma chave para assinar e para -cifrar. Este algoritmo só deve ser utilizado em alguns domínios. -Por favor consulte primeiro o seu perito em segurança. +De modo geral, não é uma boa ideia usar a mesma chave para assinar e +cifrar. Este algoritmo só deve ser usado em determinados domínios. +Consulte primeiro o seu especialista em segurança. +. + +.gpg.keygen.cardkey +Selecionar qual chave do cartão será utilizada. + +A listagem mostra o índice de seleção, o keygrip (uma string de +dígitos hex), a referência da chave específica do cartão, o algoritmo +que foi usado para esta chave, e, entre parênteses, a utilização da +chave (cert, sign, auth, encr). Se conhecida, a utilização padrão de +uma chave está marcada com um asterisco. +. + +.gpg.keygen.keygrip +Introduzir o keygrip da chave a ser adicionada. + +O keygrip é uma string de 40 dígitos hex que identifica uma chave. +Ele deve pertencer a uma chave secreta ou a uma subchave secreta +armazenada no seu porta-chaves. +. + +.gpg.keygen.flags +Alterne as capacidades da chave. + +Só é possível alternar as capacidades que são possíveis para o +algoritmo selecionado. + +Para definir rapidamente os recursos de uma só vez, é possível inserir +um '=' como primeiro caractere seguido de uma lista de letras +indicando a capacidade a definir: 's' para assinatura, 'e' para +cifração e 'a' para autenticação. Letras inválidas e capacidades +impossíveis são ignoradas. Este submenu é imediatamente fechado +depois de usar este atalho. . .gpg.keygen.size -Insira o tamanho da chave +Introduzir o tamanho da chave. + +A pré-definição sugerida geralmente é uma boa escolha. + +Se você quiser usar um tamanho de chave grande, por exemplo, 4096 bit, +pense novamente se realmente faz sentido para você. Você poderá +querer ver a página web https://www.xkcd.com/538/ . . .gpg.keygen.size.huge.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keygen.size.large.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keygen.valid -Digite o valor necessário conforme pedido. -É possível digitar uma data ISO (AAAA-MM-DD) mas você não terá uma boa -reacção a erros - o sistema tentará interpretar o valor dado como um intervalo. +Introduzir o valor exigido, conforme mostrado no prompt. +É possível inserir uma data ISO (AAAA-MM-DD), mas você não vai obter +uma boa resposta de erro - em vez disso, o sistema tenta interpretar o +valor dado como um intervalo. . .gpg.keygen.valid.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keygen.name -Digite o nome do possuidor da chave +Introduzir o nome do titular da chave. +Os caracteres "<" e ">" não são permitidos. +Exemplo: Heinrich Heine . .gpg.keygen.email -por favor digite um endereço de email (opcional mas recomendado) +Introduza um endereço de email opcional, mas altamente sugerido. +Exemplo: heinrichh@duesteldorf.de . .gpg.keygen.comment -Por favor digite um comentário (opcional) +Introduza um comentário opcional. +Os caracteres "(" e ")" não são permitidos. +De modo geral, não há necessidade de comentários. . .gpg.keygen.userid.cmd -N para mudar o nome. -C para mudar o comentário. -E para mudar o endereço de email -O para continuar a geração da chave. -S para interromper a geração da chave. +# (Keep a leading empty line) + +N para alterar o nome. +C para alterar o comentário. +E para alterar o endereço de email. +O para continuar com a geração de chaves. +Q para sair da geração de chaves. . .gpg.keygen.sub.okay -Responda "sim" (ou apenas "s") se quiser gerar a subchave. +Responder "sim" (ou apenas "s") se não houver problema em gerar a +subchave. . .gpg.sign_uid.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.sign_uid.class -Quando assina uma chave de identificação de um utilizador, deve primeiro -verificar que a chave pertence realmente à pessoa em questão. É útil para -terceiros saberem com que cuidado é que efectuou esta verificação. +Ao assinar uma ID de utilizador de uma chave, você deve primeiro +verificar que a chave pertence à pessoa correta da ID de utilizador. +É útil para os outros saber com que cuidado você verificou isso. -"0" significa que não deseja declarar a forma com verificou a chave +"0" significa que você faz nenhuma reivindicação específica sobre o + quão cuidadosamente você verificou o chave. -"1" significa que acredita que a chave pertence à pessoa em questão, mas - não conseguiu ou não tentou verificar. Este grau é útil para quando - assina a chave de uma utilizador pseudo-anónimo. +"1" significa que você acredita que a pessoa é dona da chave que + afirma possuí-la mas você não pôde, ou não verificou a chave. + Isto é útil para uma verificação de "persona", onde você assina a + chave de um utilizador pseudónimo. -"2" significa que efectuou uma verificação normal da chave. Por exemplo, - isto pode significar que verificou a impressão digital da chave e - verificou o identificador de utilizador da chave contra uma identificação - fotográfica. +"2" significa que você fez uma verificação casual da chave. Por + exemplo, isso poderia significar que você verificou a impressão + digital da chave e verificou a ID de utilizador da chave em + relação a uma ID fotográfica. -"3" significa que efectuou uma verificação exaustiva da chave. Por exemplo, - isto pode significar que efectuou a verificação pessoalmente, e que - utilizou um documento, com fotografia, difícil de falsificar - (como por exemplo um passaporte) que o nome do dono da chave é o - mesmo do que o identificador da chave, e que, finalmente, verificou - (através de troca de e-mail) que o endereço de email da chave pertence - ao done da chave. +"3" significa que você fez uma verificação completa da chave. Por + exemplo, isto poderia significa que você verificou a impressão + digital da chave com o dono da chave em pessoa, e que você + verificou, por meio de um documento difícil de falsificar com uma + ID fotográfica (como um passaporte) que o nome do dono da chave + corresponde ao na ID de utilizador na chave e, finalmente, que + você verificou (por troca de email) que o endereço de email na + chave pertence ao dono da chave. -Atenção: os exemplos dados para os níveis 2 e 3 são *apenas* exemplos. -Compete-lhe a si decidir o que considera, ao assinar chaves, uma verificação -"normal" e uma verificação "exaustiva". +Note que os exemplos dados acima para os níveis 2 e 3 são *apenas* +exemplos. No final, cabe a você decidir o que "casual" e "completo" +significa para você quando você assina outras chaves. -Se não sabe qual é a resposta correcta, responda "0". +Se você não sabe qual é a resposta certa, responda "0". . .gpg.change_passwd.empty.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keyedit.save.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keyedit.cancel.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . -.#gpg.keyedit.sign_all.okay -# fixme: Please translate and remove the hash mark from the key line. -Answer "yes" if you want to sign ALL the user IDs +.gpg.keyedit.sign_all.okay +Responder "sim" se quiser assinar TODAS as IDs de utilizador. . .gpg.keyedit.remove.uid.okay -Responda "sim" se quiser realmente remover este ID de utilizador. -Todos os certificados também serão perdidos! +Responda "sim" se tem a certeza que você quer apagar esta ID de +utilizador. Todos os certificados também são perdidos! . .gpg.keyedit.remove.subkey.okay -Responda "sim" se quiser remover a subchave +Responder "sim" se não houver problema em apagar a subchave. . .gpg.keyedit.delsig.valid -Esta é uma assinatura válida na chave; normalmente não é desejável -remover esta assinatura porque ela pode ser importante para estabelecer -uma conexão de confiança à chave ou a outra chave certificada por esta. +Esta é uma assinatura válida na chave; você normalmente não quer +apagar esta assinatura porque pode ser importante para estabelecer uma +conexão de confiança com a chave ou com outra chave certificada por +esta chave. . .gpg.keyedit.delsig.unknown Esta assinatura não pode ser verificada porque você não tem a chave -correspondente. Você deve adiar sua remoção até saber que chave foi usada -porque a chave desta assinatura pode estabelecer uma conexão de confiança -através de outra chave já certificada. +correspondente. Você deve adiar apagar, até quando você souber qual +chave foi usada, porque esta chave de assinatura pode estabelecer uma +conexão de confiança por meio de outra chave já certificada. . .gpg.keyedit.delsig.invalid -A assinatura não é válida. Faz sentido removê-la do seu porta-chaves. +A assinatura não é válida. Faz sentido removê-la de seu porta-chaves. . .gpg.keyedit.delsig.selfsig -Esta é uma assinatura que liga o ID de utilizador à chave. Geralmente -não é uma boa idéia remover tal assinatura. É possível que o GnuPG -não consiga mais usar esta chave. Faça isto apenas se por alguma -razão esta auto-assinatura não for válida e há uma segunda disponível. +Esta é uma assinatura que vincula a ID de utilizador à chave. +Geralmente não é uma boa ideia remover tal assinatura. Até porque o +GnuPG pode deixar de ser capaz de usar esta chave. Por isso, faça +isso só se, por algum motivo, esta auto-assinatura não for válida e +uma segunda assinatura estiver disponível. . .gpg.keyedit.updpref.okay -Muda as preferências de todos os identificadores de utilizadores -(ou apenas dos seleccionados) para a lista actual de preferências. -O 'timestamp' de todas as auto-assinaturas afectuadas será avançado -em um segundo. - +Alterar as preferências de todas as IDs de utilizador (ou apenas das +selecionadas) para a lista atual de preferências. O timestamp de todas +as auto-assinaturas afetadas serão adiantadas em um segundo. . .gpg.passphrase.enter -Por favor digite a frase secreta +# (keep a leading empty line) +Introduza a frase-secreta; esta é uma frase que é secreta. . .gpg.passphrase.repeat -Por favor repita a frase secreta, para ter certeza do que digitou. +Repita a última frase-secreta, para ter certeza da que introduziu. . .gpg.detached_signature.filename -Dê o nome para o ficheiro ao qual a assinatura se aplica +Fornecer o nome do ficheiro ao qual a assinatura se aplica. . .gpg.openfile.overwrite.okay -Responda "sim" se quiser escrever por cima do ficheiro +# openfile.c (overwrite_filep) +Responder "sim" se não houver problema em sobrescrever o ficheiro. . .gpg.openfile.askoutname -Por favor digite um novo nome de ficheiro. Se você apenas carregar em RETURN -o ficheiro por omissão (que é mostrado entre parênteses) será utilizado. +# openfile.c (ask_outfile_name) +Introduza um novo nome de ficheiro. Se você apenas carregar RETURN o +ficheiro pré-definido (que está entre parênteses) será usado. . .gpg.ask_revocation_reason.code -Deve especificar uma razão para a emissão do certificado. Dependendo no -contexto, pode escolher as seguintes opções desta lista: - "A chave foi comprometida" - Utilize esta opção se tem razões para acreditar que indivíduos não - autorizados obtiveram acesso à sua chave secreta. - "A chave foi substituida" - Utilize esta opção se substituiu esta chave com uma mais recente. - "A chave já não é utilizada" - Utilize esta opção se já não utiliza a chave. - "O identificador do utilizador já não é válido" - Utilize esta opção para comunicar que o identificador do utilizador - não deve ser mais utilizado; normalmente utilizada para indicar - que um endereço de email é inválido. +# revoke.c (ask_revocation_reason) +Você deve especificar um motivo para a revogação. Dependendo do +contexto que você pode escolher a partir desta lista: + "Chave foi comprometida" + Usar isto se você tiver um motivo para acreditar que pessoas não + autorizadas tiveram acesso à sua chave secreta. + "Chave foi substituída" + Usar isto se você tiver substituído esta chave por uma mais + recente. + "Chave não é mais usada" + Usar isto se você tiver desativado esta chave. + "ID de utilizador não é mais válido" + Usar isto para declarar que a ID de utilizador não deve ser mais + utilizada; isto normalmente é usado para marcar um endereço de + email como inválido. . .gpg.ask_revocation_reason.text -Se desejar, pode inserir uma texto descrevendo a razão pela qual criou -este certificado de revogação. Por favor mantenha este texto conciso. +# revoke.c (ask_revocation_reason) +Se desejar, você pode introduzir um texto descrevendo porque você emite +este certificado de revogação. Mantenha este texto conciso. Uma linha vazia termina o texto. +. +.gpg.tofu.conflict +# tofu.c +TOFU detetou outra chave com o mesmo endereço de email (ou um muito +semelhante). Pode ser que o utilizador tenha criado uma nova +chave. Neste caso, você pode confiar com segurança na nova chave (mas +confirme perguntando à pessoa). No entanto, também pode ser que a +chave seja uma falsificação ou esteja a occorrer um ataque de +Man-in-the-Middle (MitM). Neste caso, você deve marcar a chave como +sendo incorreta, para que não seja confiável. Marcar uma chave como +sendo não confiável significa que quaisquer assinaturas serão +consideradas incorretas e que as tentativas de cifrar para a chave +serão sinalizadas. Se você tem dúvidas e não pode verificar de +momento, você deve ou aceitar uma vez ou rejeitar uma vez. +. + +.gpgsm.root-cert-not-trusted +# This text gets displayed by the audit log if +# a root certificates was not trusted. +O certificado raiz (a âncora-de-confiança) não é confiável. Dependendo +da configuração, você poderá aparecer-lhe um prompt, para marcar esse +certificado raiz como confiável ou você poderá precisar de dizer +manualmente ao GnuPG para confiar nesse certificado. Os certificados +confiáveis são configurados no ficheiro trustlist.txt da pasta home do +GnuPG. Em caso de dúvida, pergunte ao seu administrador de sistema se +deve confiar neste certificado. +. + +.gpgsm.crl-problem +# This text is displayed by the audit log for problems with +# the CRL or OCSP checking. +Dependendo da sua configuração, ocorreu um problema ao obter a CRL ou +a realizar de uma verificação OCSP. Há uma grande variedade de razões +pelas quais isto não funcionou. Verifique o manual para possíveis +soluções. . - # Local variables: -# mode: fundamental +# mode: default-generic # coding: utf-8 # End: diff --git a/po/pt.po b/po/pt.po index e7ba4118c..cf440b3a3 100644 --- a/po/pt.po +++ b/po/pt.po @@ -1,25 +1,80 @@ # pt messages for gnupg -# Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -# Pedro Morais +# Copyright (C) 1999, 2000, 2001, 2002, 2023 Free Software Foundation, Inc. +# Daniel Cerqueira # # Based on pt_PT work done by: +# Pedro Morais # Thiago Jung Bauermann # Rafael Caetano dos Santos +# +# +# GnuPG glossary for Portuguese translators +# +# English | Portuguese +# ----------------------------------+-------------------------------------- +# cryptography | cifragem +# encryption | cifração +# (to) encrypt | cifrar +# decryption | decifração +# (to) decrypt | decifrar +# cipher | a cifra +# passphrase(s) | frase-secreta(s) +# password | senha +# socket | socket +# directory | pasta +# handler | handler +# string | string +# batch mode | modo batch +# delete | apagar +# request | pedido +# armor | blindagem +# compression | compressão +# ownership | ownership +# self-sign | auto-assinar +# keyring | porta-chaves +# enter | introduzir +# prompt | perguntar +# agent | agent +# smartcard | smartcard +# primary | principal +# digest | digest +# deprecated | depreciado +# stale | obsoleto +# photo ID | ID fotográfica +# subject | entidade +# chain | corrente +# write | escrever +# a record | um registo +# timestamp | timestamp +# S-expression | S-expression +# keyflag | keyflag +# flag | flag +# (to) flag | marcar +# merge | fundir +# homedir | homedir +# overwrite | sobrescrever +# (conjugation) please enter (verb) | introduza +# (conjugation) enter (verb) | introduzir +# usage: | uso: +# usage | utilização +# +# msgid "" msgstr "" "Project-Id-Version: gnupg\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2015-02-11 19:17+0100\n" -"Last-Translator: Pedro Morais \n" -"Language-Team: pt \n" +"PO-Revision-Date: 2023-11-29 13:11+0000\n" +"Last-Translator: Daniel Cerqueira \n" +"Language-Team: pt \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#, fuzzy, c-format +#, c-format msgid "failed to acquire the pinentry lock: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao adquirir o bloqueio pinentry: %s\n" #. TRANSLATORS: These are labels for buttons etc as used in #. * Pinentries. In your translation copy the text before the @@ -28,42 +83,39 @@ msgstr "falha ao inicializar a base de dados de confiança: %s\n" #. * used as an accelerator. Double the underscore to have #. * pinentry display a literal underscore. msgid "|pinentry-label|_OK" -msgstr "" +msgstr "|pinentry-label|_OK" msgid "|pinentry-label|_Cancel" -msgstr "" +msgstr "|pinentry-label|_Cancelar" msgid "|pinentry-label|_Yes" -msgstr "" +msgstr "|pinentry-label|_Sim" msgid "|pinentry-label|_No" -msgstr "" +msgstr "|pinentry-label|_Não" msgid "|pinentry-label|PIN:" -msgstr "" +msgstr "|pinentry-label|PIN:" msgid "|pinentry-label|_Save in password manager" -msgstr "" +msgstr "|pinentry-label|_Guardar no gestor de senhas" -#, fuzzy msgid "Do you really want to make your passphrase visible on the screen?" -msgstr "Você quer realmente remover as chaves selecionadas? " +msgstr "De certeza que você deseja tornar sua frase-secreta visível no ecrã?" msgid "|pinentry-tt|Make passphrase visible" -msgstr "" +msgstr "|pinentry-tt|Tornar a frase-secreta visível" -#, fuzzy -#| msgid "invalid passphrase" msgid "|pinentry-tt|Hide passphrase" -msgstr "frase-secreta inválida" +msgstr "|pinentry-tt|Esconder frase-secreta" msgid "Caps Lock is on" -msgstr "" +msgstr "Caps Lock está ativado" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for generating a passphrase. msgid "Suggest" -msgstr "" +msgstr "Sugerir" #. TRANSLATORS: This string is a tooltip, shown by pinentry when #. hovering over the generate button. Please use an appropriate @@ -73,25 +125,24 @@ msgstr "" #. will be used. The strcmp thingy is there to detect a #. non-translated string. msgid "pinentry.genpin.tooltip" -msgstr "" +msgstr "Sugerir uma frase-secreta aleatória." #. TRANSLATORS: This is a text shown by pinentry if the option #. for formatted passphrase is enabled. The length is #. limited to about 900 characters. msgid "Note: The blanks are not part of the passphrase." -msgstr "" +msgstr "Nota: Os espaços em branco não fazem parte da frase-secreta." #. TRANSLATORS: This is a text shown by pinentry as title of a dialog #. telling the user that the entered new passphrase does not satisfy #. the passphrase constraints. Please keep it short. -#, fuzzy msgid "Passphrase Not Allowed" -msgstr "frase secreta demasiado longa\n" +msgstr "Frase-secreta Não Permitida" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for the quality bar. msgid "Quality:" -msgstr "" +msgstr "Qualidade:" #. TRANSLATORS: This string is a tooltip, shown by pinentry when #. hovering over the quality bar. Please use an appropriate @@ -101,528 +152,510 @@ msgstr "" #. will be used. msgid "pinentry.qualitybar.tooltip" msgstr "" +"A qualidade do texto inserido acima.\n" +"Peça ao administrador detalhes sobre\n" +"os critérios." msgid "" "Please enter your PIN, so that the secret key can be unlocked for this " "session" msgstr "" +"Introduza o seu PIN, para que a chave secreta possa ser desbloqueada para " +"esta sessão" -#, fuzzy msgid "" "Please enter your passphrase, so that the secret key can be unlocked for " "this session" -msgstr "Por favor digite a frase secreta \n" +msgstr "" +"Introduza a sua frase-secreta, para que a chave secreta possa ser " +"desbloqueada para esta sessão" msgid "PIN:" -msgstr "" +msgstr "PIN:" -#, fuzzy msgid "Passphrase:" -msgstr "frase secreta incorrecta" +msgstr "Frase-secreta:" msgid "does not match - try again" -msgstr "" +msgstr "não corresponde - tente novamente" -#, fuzzy msgid "Passphrases match." -msgstr "frase secreta incorrecta" +msgstr "Frase-secretas correspondem." #. TRANSLATORS: The string is appended to an error message in #. the pinentry. The %s is the actual error message, the #. two %d give the current and maximum number of tries. #, c-format msgid "SETERROR %s (try %d of %d)" -msgstr "" +msgstr "SETERROR %s (tentativa %d de %d)" msgid "Repeat:" -msgstr "" +msgstr "Repetir:" -#, fuzzy msgid "PIN too long" -msgstr "frase secreta demasiado longa\n" +msgstr "PIN muito longo" -#, fuzzy msgid "Passphrase too long" -msgstr "frase secreta demasiado longa\n" +msgstr "Frase-secreta muito longa" -#, fuzzy msgid "Invalid characters in PIN" -msgstr "Caracter inválido no nome\n" +msgstr "Caracteres inválidos no PIN" msgid "PIN too short" -msgstr "" +msgstr "PIN muito curto" -#, fuzzy msgid "Bad PIN" -msgstr "MPI incorreto" +msgstr "PIN inválido" -#, fuzzy msgid "Bad Passphrase" -msgstr "frase secreta incorrecta" +msgstr "Frase-secreta inválida" msgid "Note: Request from the web browser." -msgstr "" +msgstr "Nota: Pedido do navegador da Web." msgid "Note: Request from a remote site." -msgstr "" +msgstr "Nota: Pedido de um site remoto." -#, fuzzy, c-format +#, c-format msgid "error getting serial number of card: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter o número de série do cartão: %s\n" -#, fuzzy msgid "Please re-enter this passphrase" -msgstr "muda a frase secreta" +msgstr "Re-introduza esta frase-secreta" -#, fuzzy, c-format +#, c-format msgid "" "Please enter the passphrase to protect the imported object within the %s " "system." -msgstr "Por favor digite a frase secreta \n" +msgstr "" +"Introduza a frase-secreta para proteger o objeto importado dentro do sistema " +"%s." msgid "" "This key (or subkey) is not protected with a passphrase. Please enter a new " "passphrase to export it." msgstr "" +"Esta chave (ou subchave) não está protegida com uma frase-secreta. " +"Introduza uma nova frase-secreta para exportá-la." -#, fuzzy, c-format +#, c-format msgid "ssh keys greater than %d bits are not supported\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "chaves ssh maiores que %d bits não são suportadas\n" -#, fuzzy, c-format -#| msgid "can't create `%s': %s\n" +#, c-format msgid "can't create '%s': %s\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível criar '%s': %s\n" -#, fuzzy, c-format -#| msgid "can't open `%s': %s\n" +#, c-format msgid "can't open '%s': %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "não é possível abrir '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "no suitable card key found: %s\n" -msgstr "nenhum porta-chaves secreto com permissões de escrita encontrado: %s\n" +msgstr "nenhuma chave de cartão adequada encontrada: %s\n" -#, fuzzy, c-format +#, c-format msgid "error getting list of cards: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter a lista de cartões: %s\n" #, c-format msgid "" "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want to " "allow this?" msgstr "" +"Um processo ssh pediu o uso da chave%%0A %s%%0A (%s)%%0ADeseja permitir " +"isto?" msgid "Allow" -msgstr "" +msgstr "Permitir" msgid "Deny" -msgstr "" +msgstr "Negar" -#, fuzzy, c-format +#, c-format msgid "Please enter the passphrase for the ssh key%%0A %F%%0A (%c)" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta da chave ssh%%0A %F%%0A (%c)" -#, fuzzy, c-format +#, c-format msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" -msgstr "Por favor digite a frase secreta \n" +msgstr "" +"Introduza uma frase-secreta para proteger a chave secreta recebida%%0A " +"%s%%0A %s%%0Adentro do armazenamento de chaves do gpg-agent" -#, fuzzy, c-format +#, c-format msgid "failed to create stream from socket: %s\n" -msgstr "%s: falha ao criar tabela de dispersão: %s\n" +msgstr "falha ao criar fluxo de socket: %s\n" msgid "Admin PIN" -msgstr "" +msgstr "PIN do Admin" #. TRANSLATORS: A PUK is the Personal Unblocking Code #. used to unblock a PIN. msgid "PUK" -msgstr "" +msgstr "PUK" msgid "Reset Code" -msgstr "" +msgstr "Código de Reset" msgid "Push ACK button on card/token." -msgstr "" +msgstr "Pressione o botão ACK no cartão/token." msgid "Use the reader's pinpad for input." -msgstr "" +msgstr "Usar o pinpad do leitor para entrada." -#, fuzzy msgid "Repeat this Reset Code" -msgstr "Repita a frase secreta: " +msgstr "Repetir este Código de Reset" -#, fuzzy msgid "Repeat this PUK" -msgstr "Repita a frase secreta: " +msgstr "Repetir este PUK" -#, fuzzy msgid "Repeat this PIN" -msgstr "Repita a frase secreta: " +msgstr "Repetir este PIN" -#, fuzzy msgid "Reset Code not correctly repeated; try again" -msgstr "a frase secreta não foi repetida corretamente; tente outra vez" +msgstr "Código de Reset incorretamente repetido; tente novamente" -#, fuzzy msgid "PUK not correctly repeated; try again" -msgstr "a frase secreta não foi repetida corretamente; tente outra vez" +msgstr "PUK incorretamente repetido; tente novamente" -#, fuzzy msgid "PIN not correctly repeated; try again" -msgstr "a frase secreta não foi repetida corretamente; tente outra vez" +msgstr "PIN incorretamente repetido; tente novamente" #, c-format msgid "Please enter the PIN%s%s%s to unlock the card" -msgstr "" +msgstr "Introduza o PIN%s%s%s para desbloquear o cartão" -#, fuzzy, c-format +#, c-format msgid "error writing to pipe: %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao escrever no pipe: %s\n" -#, fuzzy msgid "Enter new passphrase" -msgstr "Insira a frase secreta\n" +msgstr "Introduzir nova frase-secreta" #, c-format msgid "" "You have not entered a passphrase!%0AAn empty passphrase is not allowed." msgstr "" +"Você não introduziu uma frase-secreta!%0AUma frase-secreta vazia não é " +"permitida." #, c-format msgid "" "You have not entered a passphrase - this is in general a bad idea!%0APlease " "confirm that you do not want to have any protection on your key." msgstr "" +"Você não introduziu uma frase-secreta - isto, geralmente, é uma má ideia!" +"%0AConfirme que você quer ter nenhuma proteção em sua chave." msgid "Yes, protection is not needed" -msgstr "" +msgstr "Sim, a proteção não é necessária" -#, fuzzy, c-format -#| msgid "Name must be at least 5 characters long\n" +#, c-format msgid "A passphrase should be at least %u character long." msgid_plural "A passphrase should be at least %u characters long." -msgstr[0] "O nome deve ter pelo menos 5 caracteres\n" -msgstr[1] "O nome deve ter pelo menos 5 caracteres\n" +msgstr[0] "Uma frase-secreta deve ter pelo menos %u caracter." +msgstr[1] "Uma frase-secreta deve ter pelo menos %u caracteres." #, c-format msgid "A passphrase should contain at least %u digit or%%0Aspecial character." msgid_plural "" "A passphrase should contain at least %u digits or%%0Aspecial characters." msgstr[0] "" +"Uma frase-secreta deve conter pelo menos %u dígito ou%%0Acaracter especial." msgstr[1] "" +"Uma frase-secreta deve conter pelo menos %u dígitos ou%%0Acaracteres " +"especiais." #, c-format msgid "A passphrase may not be a known term or match%%0Acertain pattern." msgstr "" +"Uma frase-secreta não pode ser um termo conhecido ou corresponder%%0Aa um " +"determinado padrão." msgid "Warning: You have entered an insecure passphrase." -msgstr "" +msgstr "Aviso: Você introduziu uma frase-secreta insegura." -#, fuzzy msgid "Take this one anyway" -msgstr "Usar esta chave de qualquer modo? " +msgstr "Mesmo assim, leve esta" -#, fuzzy, c-format +#, c-format msgid "Please enter the passphrase to%0Aprotect your new key" -msgstr "" -"Você precisa de uma frase secreta para proteger a sua chave.\n" -"\n" +msgstr "Introduza a frase-secreta para%0Aproteger a sua nova chave" -#, fuzzy msgid "Please enter the new passphrase" -msgstr "muda a frase secreta" +msgstr "Introduza a nova frase-secreta" msgid "Options used for startup" -msgstr "" +msgstr "Opções usadas para inicialização" msgid "run in daemon mode (background)" -msgstr "" +msgstr "executar no modo daemon (em segundo plano)" msgid "run in server mode (foreground)" -msgstr "" +msgstr "executar no modo de servidor (primeiro plano)" msgid "do not detach from the console" -msgstr "" +msgstr "não desanexar da consola" msgid "sh-style command output" -msgstr "" +msgstr "saída de comando tipo-sh" msgid "csh-style command output" -msgstr "" +msgstr "saída de comando tipo-csh" -#, fuzzy msgid "|FILE|read options from FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|ler opções de FILE" msgid "Options controlling the diagnostic output" -msgstr "" +msgstr "Opções que controlam a saída do diagnóstico" msgid "verbose" -msgstr "detalhado" +msgstr "verboso" msgid "be somewhat more quiet" msgstr "ser mais silencioso" msgid "|FILE|write server mode logs to FILE" -msgstr "" +msgstr "|FILE|escrever logs do modo de servidor no FILE" msgid "Options controlling the configuration" -msgstr "" +msgstr "Opções que controlam a configuração" -#, fuzzy msgid "do not use the SCdaemon" -msgstr "actualizar a base de dados de confiança" +msgstr "não usar o SCdaemon" msgid "|PGM|use PGM as the SCdaemon program" -msgstr "" +msgstr "|PGM|usar PGM como o programa SCdaemon" msgid "|PGM|use PGM as the tpm2daemon program" -msgstr "" +msgstr "|PGM|usar PGM como o programa tpm2daemon" -#, fuzzy -#| msgid "|NAME|set terminal charset to NAME" msgid "|NAME|accept some commands via NAME" -msgstr "" -"|NOME|definir mapa de caracteres do terminal como\n" -"NOME" +msgstr "|NAME|aceitar alguns comandos via NAME" msgid "ignore requests to change the TTY" -msgstr "" +msgstr "ignorar pedidos para alterar o TTY" msgid "ignore requests to change the X display" -msgstr "" +msgstr "ignorar pedidos para alterar a exibição X" -#, fuzzy -#| msgid "not supported" msgid "enable ssh support" -msgstr "não suportado" +msgstr "habilitar suporte a ssh" msgid "|ALGO|use ALGO to show ssh fingerprints" -msgstr "" +msgstr "|ALGO|usar ALGO para mostrar impressões digitais ssh" -#, fuzzy -#| msgid "not supported" msgid "enable putty support" -msgstr "não suportado" +msgstr "habilitar suporte a putty" -#, fuzzy -#| msgid "not supported" msgid "enable Win32-OpenSSH support" -msgstr "não suportado" +msgstr "habilitar o suporte a Win32-OpenSSH" msgid "Options controlling the security" -msgstr "" +msgstr "Opções que controlam a segurança" msgid "|N|expire cached PINs after N seconds" -msgstr "" +msgstr "|N|expirar PINs armazenados em cache após N segundos" msgid "|N|expire SSH keys after N seconds" -msgstr "" +msgstr "|N|expirar chaves SSH após N segundos" msgid "|N|set maximum PIN cache lifetime to N seconds" -msgstr "" +msgstr "|N|definir o tempo de vida máximo da cache do PIN para N segundos" msgid "|N|set maximum SSH key lifetime to N seconds" -msgstr "" +msgstr "|N|definir o tempo de vida máximo da chave SSH para N segundos" msgid "do not use the PIN cache when signing" -msgstr "" +msgstr "não usar a cache de PIN ao assinar" -#, fuzzy msgid "disallow the use of an external password cache" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "não permitir o uso de uma cache de senhas externa" msgid "disallow clients to mark keys as \"trusted\"" -msgstr "" +msgstr "não permitir que os clientes marquem chaves como \"confiável\"" -#, fuzzy msgid "allow presetting passphrase" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "permitir pré-definir frase-secreta" msgid "Options enforcing a passphrase policy" -msgstr "" +msgstr "Opções que impõem uma política de frase-secreta" msgid "do not allow bypassing the passphrase policy" -msgstr "" +msgstr "não permitir ignorar a política de frase-secreta" msgid "|N|set minimal required length for new passphrases to N" msgstr "" +"|N|definir o comprimento mínimo necessário de N para novas frases-secretas" msgid "|N|require at least N non-alpha characters for a new passphrase" msgstr "" +"|N|exigir pelo menos N caracteres não-alfabéticos para uma nova frase-secreta" msgid "|FILE|check new passphrases against pattern in FILE" -msgstr "" +msgstr "|FILE|verificar novas frases-secretas em relação ao padrão no FILE" -#, fuzzy msgid "|N|expire the passphrase after N days" -msgstr "|N|usar mode de frase secreta N" +msgstr "|N|expirar a frase-secreta após N dias" -#, fuzzy msgid "do not allow the reuse of old passphrases" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "não permitir a reutilização de frase-secretas antigas" msgid "Options controlling the PIN-Entry" -msgstr "" +msgstr "Opções que controlam o PIN-Entry" -#, fuzzy -#| msgid "use the gpg-agent" msgid "never use the PIN-entry" -msgstr "utilizar o gpg-agent" +msgstr "nunca usar o PIN-entry" msgid "disallow caller to override the pinentry" -msgstr "" +msgstr "não permitir que o chamador sobreponha o pinentry" msgid "let PIN-Entry grab keyboard and mouse" -msgstr "" +msgstr "deixar o PIN-Entry agarrar o teclado e o rato" msgid "|PGM|use PGM as the PIN-Entry program" -msgstr "" +msgstr "|PGM|usar PGM como o programa PIN-Entry" msgid "|N|set the Pinentry timeout to N seconds" -msgstr "" +msgstr "|N|definir o tempo limite do Pinentry para N segundos" msgid "allow passphrase to be prompted through Emacs" -msgstr "" +msgstr "permitir que a frase-secreta seja perguntada pelo Emacs" #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug #. reporting address. This is so that we can change the #. reporting address without breaking the translations. -#, fuzzy msgid "Please report bugs to <@EMAIL@>.\n" -msgstr "Por favor comunique bugs para .\n" +msgstr "Reporte bugs para <@EMAIL@>.\n" -#, fuzzy msgid "Usage: @GPG_AGENT@ [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPG_AGENT@ [opções] (-h para ajuda)" msgid "" "Syntax: @GPG_AGENT@ [options] [command [args]]\n" "Secret key management for @GNUPG@\n" msgstr "" +"Sintaxe: @GPG_AGENT@ [opções] [comando [args]]\n" +"Gerir as chaves secretas para @GNUPG@\n" #, c-format msgid "invalid debug-level '%s' given\n" -msgstr "" +msgstr "fornecido debug-level inválido '%s'\n" #, c-format msgid "selected digest algorithm is invalid\n" -msgstr "o algoritmo de \"digest\" selecionado é inválido\n" +msgstr "o algoritmo de digest selecionado é inválido\n" -#, fuzzy, c-format -#| msgid "reading options from `%s'\n" +#, c-format msgid "reading options from '%s'\n" -msgstr "a ler opções de `%s'\n" +msgstr "lendo opções de '%s'\n" -#, fuzzy, c-format -#| msgid "WARNING: \"%s\" is a deprecated option\n" +#, c-format msgid "Note: '%s' is not considered an option\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "Nota: '%s' não é considerada uma opção\n" #, c-format msgid "WARNING: \"%s\" is a deprecated option\n" msgstr "AVISO: \"%s\" é uma opção depreciada\n" -#, fuzzy, c-format +#, c-format msgid "can't create socket: %s\n" -msgstr "impossível criar %s: %s\n" +msgstr "não é possível criar socket: %s\n" #, c-format msgid "socket name '%s' is too long\n" -msgstr "" +msgstr "o nome do socket '%s' é muito longo\n" #, c-format msgid "trying to steal socket from running %s\n" -msgstr "" +msgstr "tentando roubar o socket de executar %s\n" -#, fuzzy, c-format +#, c-format msgid "a gpg-agent is already running - not starting a new one\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "um gpg-agent já está em execução - não iniciando um novo\n" -#, fuzzy, c-format +#, c-format msgid "error getting nonce for the socket\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter nonce para o socket\n" -#, fuzzy, c-format +#, c-format msgid "error binding socket to '%s': %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao vincular socket a '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "can't set permissions of '%s': %s\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "não é possível definir permissões de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "listening on socket '%s'\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "ouvindo no socket '%s'\n" -#, fuzzy, c-format +#, c-format msgid "can't create directory '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "não é possível criar a pasta '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "directory '%s' created\n" -msgstr "%s: directoria criada\n" +msgstr "pasta '%s' criada\n" -#, fuzzy, c-format +#, c-format msgid "stat() failed for '%s': %s\n" -msgstr "base de dados de confiança: leitura falhou (n=%d): %s\n" +msgstr "stat() falhou para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "can't use '%s' as home directory\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "não é possível usar '%s' como pasta home\n" -#, fuzzy, c-format +#, c-format msgid "error reading nonce on fd %d: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler nonce em fd %d: %s\n" #, c-format msgid "handler 0x%lx for fd %d started\n" -msgstr "" +msgstr "handler 0x%lx para fd %d iniciado\n" #, c-format msgid "handler 0x%lx for fd %d terminated\n" -msgstr "" +msgstr "handler 0x%lx para fd %d terminado\n" #, c-format msgid "ssh handler 0x%lx for fd %d started\n" -msgstr "" +msgstr "handler ssh 0x%lx para fd %d iniciado\n" #, c-format msgid "ssh handler 0x%lx for fd %d terminated\n" -msgstr "" +msgstr "handler ssh 0x%lx para fd %d terminado\n" -#, fuzzy, c-format +#, c-format msgid "npth_pselect failed: %s - waiting 1s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "npth_pselect falhou: %s - aguardando 1s\n" -#, fuzzy, c-format +#, c-format msgid "%s %s stopped\n" -msgstr "%s: ignorado: %s\n" +msgstr "%s %s interrompido\n" -#, fuzzy, c-format +#, c-format msgid "no gpg-agent running in this session\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "nenhum gpg-agent em execução nesta sessão\n" -#, fuzzy msgid "" "@Options:\n" " " msgstr "" -"@\n" -"Opções:\n" +"@Opções:\n" " " -#, fuzzy msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: gpg-preset-passphrase [opções] KEYGRIP (-h para ajuda)\n" msgid "" "Syntax: gpg-preset-passphrase [options] KEYGRIP\n" "Password cache maintenance\n" msgstr "" +"Sintaxe: gpg-preset-passphrase [opções] KEYGRIP\n" +"Manutenção da cache de senhas\n" msgid "" "@Commands:\n" @@ -640,73 +673,75 @@ msgstr "" "Opções:\n" " " -#, fuzzy msgid "Usage: gpg-protect-tool [options] (-h for help)\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: gpg-protect-tool [opções] (-h para ajuda)\n" msgid "" "Syntax: gpg-protect-tool [options] [args]\n" "Secret key maintenance tool\n" msgstr "" +"Sintaxe: gpg-protect-tool [opções] [args]\n" +"Ferramenta de manutenção de chave secreta\n" -#, fuzzy msgid "Please enter the passphrase to unprotect the PKCS#12 object." -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para desproteger o objeto PKCS#12." -#, fuzzy msgid "Please enter the passphrase to protect the new PKCS#12 object." -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para proteger o novo objeto PKCS#12." msgid "" "Please enter the passphrase to protect the imported object within the GnuPG " "system." msgstr "" +"Introduza a frase-secreta para proteger o objeto importado dentro do sistema " +"GnuPG." -#, fuzzy msgid "" "Please enter the passphrase or the PIN\n" "needed to complete this operation." -msgstr "Por favor digite a frase secreta \n" +msgstr "" +"Introduza a frase-secreta ou o PIN\n" +"necessário para concluir esta operação." -#, fuzzy, c-format +#, c-format msgid "cancelled\n" -msgstr "cancelado pelo utilizador\n" +msgstr "cancelado\n" -#, fuzzy, c-format +#, c-format msgid "error while asking for the passphrase: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao perguntar pela frase-secreta: %s\n" -#, fuzzy, c-format +#, c-format msgid "error opening '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao abrir '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "file '%s', line %d: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "ficheiro '%s', linha %d: %s\n" -#, fuzzy, c-format +#, c-format msgid "statement \"%s\" ignored in '%s', line %d\n" -msgstr "armadura: %s\n" +msgstr "instrução \"%s\" ignorada em '%s', linha %d\n" -#, fuzzy, c-format +#, c-format msgid "system trustlist '%s' not available\n" -msgstr "partes da chave secreta não disponíveis\n" +msgstr "lista da confiança do sistema '%s' não disponível\n" -#, fuzzy, c-format +#, c-format msgid "bad fingerprint in '%s', line %d\n" -msgstr "armadura: %s\n" +msgstr "impressão digital inválida em '%s', linha %d\n" -#, fuzzy, c-format +#, c-format msgid "invalid keyflag in '%s', line %d\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "keyflag inválida em '%s', linha %d\n" -#, fuzzy, c-format +#, c-format msgid "error reading '%s', line %d: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler '%s', linha %d: %s\n" #, c-format msgid "error reading list of trusted root certificates\n" -msgstr "" +msgstr "erro ao ler lista de certificados raiz confiáveis\n" #. TRANSLATORS: This prompt is shown by the Pinentry #. and has one special property: A "%%0A" is used by @@ -721,13 +756,14 @@ msgid "" "Do you ultimately trust%%0A \"%s\"%%0Ato correctly certify user " "certificates?" msgstr "" +"Você confia plenamente em%%0A \"%s\"%%0Apara certificar corretamente " +"certificados de utilizador?" -#, fuzzy msgid "Yes" -msgstr "sim" +msgstr "Sim" msgid "No" -msgstr "" +msgstr "Não" #. TRANSLATORS: This prompt is shown by the Pinentry and has #. one special property: A "%%0A" is used by Pinentry to @@ -742,157 +778,141 @@ msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " "fingerprint:%%0A %s" msgstr "" +"Verifique que o certificado identificado como:%%0A \"%s\"%%0Atem a " +"impressão digital:%%0A %s" #. TRANSLATORS: "Correct" is the label of a button and intended #. to be hit if the fingerprint matches the one of the CA. The #. other button is "the default "Cancel" of the Pinentry. msgid "Correct" -msgstr "" +msgstr "Correta" msgid "Wrong" -msgstr "" +msgstr "Errada" #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." -msgstr "" +msgstr "Nota: Esta frase-secreta nunca foi alterada.%0AAltere-a agora." #, c-format msgid "" "This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s. Please change " "it now." msgstr "" +"Esta frase-secreta não foi alterada%%0Adesde %.4s-%.2s-%.2s. Altere-a agora." -#, fuzzy msgid "Change passphrase" -msgstr "muda a frase secreta" +msgstr "Alterar frase-secreta" msgid "I'll change it later" -msgstr "" +msgstr "Vou alterá-la mais tarde" msgid "Please insert the card with serial number" -msgstr "" +msgstr "Insira o cartão com o número de série" #, c-format msgid "Requested the use of key%%0A %s%%0A %s%%0ADo you want to allow this?" -msgstr "" +msgstr "Pediu o uso da chave%%0A %s%%0A %s%%0ADeseja permitir isso?" -#, fuzzy, c-format +#, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" -msgstr "Você quer realmente remover as chaves selecionadas? " +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" +msgstr "" +"De certeza que você deseja apagar a chave identificada por keygrip%%0A " +"%s%%0A %%C%%0A?" -#, fuzzy msgid "Delete key" -msgstr "activa uma chave" +msgstr "Apagar chave" msgid "" "Warning: This key is also listed for use with SSH!\n" "Deleting the key might remove your ability to access remote machines." msgstr "" +"Aviso: Esta chave também está listada para uso com SSH!\n" +"Apagar esta chave pode remover sua capacidade de aceder máquinas remotas." #, c-format msgid "DSA requires the hash length to be a multiple of 8 bits\n" -msgstr "" +msgstr "o DSA requer que o comprimento da hash seja um múltiplo de 8 bits\n" #, c-format msgid "%s key uses an unsafe (%u bit) hash\n" -msgstr "" +msgstr "a chave %s usa um hash inseguro (%u bit)\n" #, c-format msgid "a %zu bit hash is not valid for a %u bit %s key\n" -msgstr "" +msgstr "um hash de %zu bit não é válido para os %u bit de uma chave %s\n" #, c-format msgid "checking created signature failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "a verificação da assinatura criada falhou: %s\n" #, c-format msgid "secret key parts are not available\n" msgstr "partes da chave secreta não disponíveis\n" -#, fuzzy, c-format -#| msgid "protection algorithm %d%s is not supported\n" +#, c-format msgid "public key algorithm %d (%s) is not supported\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "o algoritmo de chave pública %d (%s) não é suportado\n" -#, fuzzy, c-format -#| msgid "protection algorithm %d%s is not supported\n" +#, c-format msgid "protection algorithm %d (%s) is not supported\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "o algoritmo de proteção %d (%s) não é suportado\n" -#, fuzzy, c-format -#| msgid "protection algorithm %d%s is not supported\n" +#, c-format msgid "protection hash algorithm %d (%s) is not supported\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "o algoritmo de proteção de hash %d (%s) não é suportado\n" -#, fuzzy, c-format +#, c-format msgid "error creating a pipe: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar um pipe: %s\n" -#, fuzzy, c-format +#, c-format msgid "error creating a stream for a pipe: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar um fluxo para um pipe: %s\n" -#, fuzzy, c-format +#, c-format msgid "error forking process: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fazer fork de processo: %s\n" #, c-format msgid "waiting for process %d to terminate failed: %s\n" -msgstr "" +msgstr "falha ao aguardar pelo encerramento do processo %d: %s\n" -#, fuzzy, c-format -msgid "error running '%s': probably not installed\n" -msgstr "erro na leitura de `%s': %s\n" +#, c-format +msgid "waiting for process to terminate failed: ec=%d\n" +msgstr "falha ao esperar que o processo terminasse: ec=%d\n" -#, fuzzy, c-format -msgid "error running '%s': exit status %d\n" -msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy, c-format -msgid "error running '%s': terminated\n" -msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy, c-format -msgid "waiting for processes to terminate failed: %s\n" -msgstr "actualização falhou: %s\n" - -#, fuzzy, c-format -msgid "error getting exit code of process %d: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" - -#, fuzzy, c-format -#| msgid "can't connect to `%s': %s\n" +#, c-format msgid "can't connect to '%s': %s\n" -msgstr "impossível ligar a `%s': %s\n" +msgstr "não é possível conectar-se a '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "problem setting the gpg-agent options\n" -msgstr "problema com o agente: o agente returnou 0x%lx\n" +msgstr "problema ao definir as opções do gpg-agent\n" #, c-format msgid "can't disable core dumps: %s\n" -msgstr "impossível desactivar core dumps: %s\n" +msgstr "não é possível desabilitar core dumps: %s\n" -#, fuzzy, c-format +#, c-format msgid "Warning: unsafe ownership on %s \"%s\"\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "Aviso: ownership não seguro em %s \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "Warning: unsafe permissions on %s \"%s\"\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "Aviso: permissões não seguras em %s \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "waiting for file '%s' to become accessible ...\n" -msgstr "actualização falhou: %s\n" +msgstr "aguardando que o ficheiro '%s' se torne acessível...\n" -#, fuzzy, c-format +#, c-format msgid "renaming '%s' to '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha ao renomear '%s' para '%s': %s\n" #. TRANSLATORS: See doc/TRANSLATE about this string. -#, fuzzy msgid "yes" msgstr "sim" @@ -915,398 +935,369 @@ msgstr "qQ" #. TRANSLATORS: See doc/TRANSLATE about this string. msgid "okay|okay" -msgstr "" +msgstr "okay|ok" #. TRANSLATORS: See doc/TRANSLATE about this string. msgid "cancel|cancel" -msgstr "" +msgstr "cancelar" msgid "oO" -msgstr "" +msgstr "oO" -#, fuzzy msgid "cC" -msgstr "c" +msgstr "cC" #, c-format msgid "out of core in secure memory while allocating %lu bytes" -msgstr "" +msgstr "fora do core na memória segura ao alocar %lu bytes" #, c-format msgid "out of core while allocating %lu bytes" -msgstr "" +msgstr "fora do core ao alocar %lu bytes" -#, fuzzy, c-format +#, c-format msgid "error allocating enough memory: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro tentando alocar memória suficiente: %s\n" #, c-format msgid "%s:%u: obsolete option \"%s\" - it has no effect\n" -msgstr "" +msgstr "%s:%u: opção obsoleta \"%s\" - não tem efeito\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "AVISO: \"%s%s\" é uma opção obsoleta - não tem efeito\n" #, c-format msgid "unknown debug flag '%s' ignored\n" -msgstr "" +msgstr "debug flag desconhecida '%s' ignorada\n" -#, fuzzy, c-format +#, c-format msgid "waiting for the dirmngr to come up ... (%ds)\n" -msgstr "actualização falhou: %s\n" +msgstr "a esperar que o dirmngr apareça... (%ds)\n" -#, fuzzy, c-format +#, c-format msgid "waiting for the keyboxd to come up ... (%ds)\n" -msgstr "actualização falhou: %s\n" +msgstr "a esperar que o keyboxd apareça... (%ds)\n" -#, fuzzy, c-format +#, c-format msgid "waiting for the agent to come up ... (%ds)\n" -msgstr "actualização falhou: %s\n" +msgstr "a esperar que o agent apareça... (%ds)\n" -#, fuzzy, c-format +#, c-format msgid "connection to the dirmngr established\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "conexão com o dirmngr estabelecida\n" -#, fuzzy, c-format +#, c-format msgid "connection to the keyboxd established\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "conexão com o keyboxd estabelecida\n" -#, fuzzy, c-format +#, c-format msgid "connection to the agent established\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "conexão com o agent estabelecida\n" -#, fuzzy, c-format +#, c-format msgid "no running %s - starting '%s'\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "sem execução de %s - iniciando '%s'\n" -#, fuzzy, c-format +#, c-format msgid "connection to the agent is in restricted mode\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "conexão com o agent está no modo restrito\n" -#, fuzzy, c-format -#| msgid "error creating keyring `%s': %s\n" +#, c-format msgid "error getting version from '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao obter a versão de '%s': %s\n" #, c-format msgid "server '%s' is older than us (%s < %s)" -msgstr "" +msgstr "o servidor '%s' é mais antigo que nós (%s < %s)" -#, fuzzy, c-format -#| msgid "WARNING: %s overrides %s\n" +#, c-format msgid "WARNING: %s\n" -msgstr "AVISO: %s sobrepõe %s\n" +msgstr "AVISO: %s\n" #, c-format msgid "Note: Outdated servers may lack important security fixes.\n" msgstr "" +"Nota: Servidores desatualizados podem não ter correções de segurança " +"importantes.\n" -#, fuzzy, c-format -#| msgid "Please use the command \"toggle\" first.\n" +#, c-format msgid "Note: Use the command \"%s\" to restart them.\n" -msgstr "Por favor utilize o comando \"toggle\" primeiro.\n" +msgstr "Nota: Usar o comando \"%s\" para reiniciá-los.\n" #. TRANSLATORS: Copy the prefix between the vertical bars #. verbatim. It will not be printed. msgid "|audit-log-result|Good" -msgstr "" +msgstr "|audit-log-result|Válido" msgid "|audit-log-result|Bad" -msgstr "" +msgstr "|audit-log-result|Inválido" msgid "|audit-log-result|Not supported" -msgstr "" +msgstr "|audit-log-result|Não suportado" -#, fuzzy msgid "|audit-log-result|No certificate" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Sem certificado" -#, fuzzy msgid "|audit-log-result|Not enabled" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Não habilitado" msgid "|audit-log-result|Error" -msgstr "" +msgstr "|audit-log-result|Erro" -#, fuzzy msgid "|audit-log-result|Not used" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Não utilizado" -#, fuzzy msgid "|audit-log-result|Okay" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Okay" -#, fuzzy msgid "|audit-log-result|Skipped" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Ignorado" -#, fuzzy msgid "|audit-log-result|Some" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Algum" -#, fuzzy msgid "Certificate chain available" -msgstr "certificado incorrecto" +msgstr "Corrente de certificados disponível" -#, fuzzy msgid "root certificate missing" -msgstr "certificado incorrecto" +msgstr "certificado raiz ausente" msgid "Data encryption succeeded" -msgstr "" +msgstr "Cifração de dados bem-sucedida" -#, fuzzy msgid "Data available" -msgstr "Nenhuma ajuda disponível" +msgstr "Dados disponíveis" -#, fuzzy msgid "Session key created" -msgstr "%s: porta-chaves criado\n" +msgstr "Chave de sessão criada" -#, fuzzy, c-format +#, c-format msgid "algorithm: %s" -msgstr "armadura: %s\n" +msgstr "algoritmo: %s" -#, fuzzy, c-format +#, c-format msgid "unsupported algorithm: %s" -msgstr "" -"\n" -"Algoritmos suportados:\n" +msgstr "algoritmo não suportado: %s" -#, fuzzy msgid "seems to be not encrypted" -msgstr "não cifrado" +msgstr "parece não estar cifrado" msgid "Number of recipients" -msgstr "" +msgstr "Número de destinatários" #, c-format msgid "Recipient %d" -msgstr "" +msgstr "Destinatário %d" msgid "Data signing succeeded" -msgstr "" +msgstr "Assinatura de dados bem-sucedida" -#, fuzzy, c-format +#, c-format msgid "data hash algorithm: %s" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash de dados: %s" -#, fuzzy, c-format +#, c-format msgid "Signer %d" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Signatário %d" -#, fuzzy, c-format +#, c-format msgid "attr hash algorithm: %s" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash attr: %s" msgid "Data decryption succeeded" -msgstr "" +msgstr "Decifração de dados bem-sucedida" -#, fuzzy msgid "Encryption algorithm supported" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "Algoritmo de cifração suportado" -#, fuzzy msgid "Data verification succeeded" -msgstr "verificação de assinatura suprimida\n" +msgstr "Verificação de dados bem-sucedida" -#, fuzzy msgid "Signature available" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Assinatura disponível" -#, fuzzy msgid "Parsing data succeeded" -msgstr "Assinatura correcta de \"" +msgstr "Processamento de dados foi bem-sucedido" -#, fuzzy, c-format +#, c-format msgid "bad data hash algorithm: %s" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash de dados inválido: %s" -#, fuzzy, c-format +#, c-format msgid "Signature %d" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Assinatura %d" -#, fuzzy msgid "Certificate chain valid" -msgstr "Esta chave expirou!" +msgstr "Corrente de certificados válida" -#, fuzzy msgid "Root certificate trustworthy" -msgstr "certificado incorrecto" +msgstr "Certificado raiz confiável" -#, fuzzy msgid "no CRL found for certificate" -msgstr "certificado incorrecto" +msgstr "nenhuma CRL encontrada para o certificado" -#, fuzzy msgid "the available CRL is too old" -msgstr "Nenhuma ajuda disponível" +msgstr "a CRL disponível é muito antiga" -#, fuzzy msgid "CRL/OCSP check of certificates" -msgstr "certificado incorrecto" +msgstr "verificação CRL/OCSP de certificados" -#, fuzzy msgid "Included certificates" -msgstr "certificado incorrecto" +msgstr "Certificados incluídos" msgid "No audit log entries." -msgstr "" +msgstr "Nenhuma entrada de log de auditoria." -#, fuzzy msgid "Unknown operation" -msgstr "versão desconhecida" +msgstr "Operação desconhecida" msgid "Gpg-Agent usable" -msgstr "" +msgstr "Gpg-Agent utilizável" msgid "Dirmngr usable" -msgstr "" +msgstr "Dirmngr utilizável" -#, fuzzy, c-format +#, c-format msgid "No help available for '%s'." -msgstr "Nenhuma ajuda disponível para `%s'" +msgstr "Nenhuma ajuda disponível para '%s'." -#, fuzzy msgid "ignoring garbage line" -msgstr "erro na última linha\n" +msgstr "ignorando linha de lixo" -#, fuzzy msgid "[none]" -msgstr "versão desconhecida" +msgstr "[nenhum]" -#, fuzzy, c-format +#, c-format msgid "invalid radix64 character %02x skipped\n" -msgstr "caracter radix64 inválido %02x ignorado\n" +msgstr "caractere radix64 inválido %02x ignorado\n" #, c-format msgid "Sorry, we are in batchmode - can't get input\n" -msgstr "" +msgstr "Desculpe, estamos em modo batch - não é possível obter a entrada\n" #, c-format msgid "Sorry, no terminal at all requested - can't get input\n" -msgstr "" +msgstr "Desculpe, nenhum terminal pedido - não é possível obter a entrada\n" #, c-format msgid "too many errors; giving up\n" -msgstr "" +msgstr "muitos erros; desistindo\n" #, c-format msgid "Control-D detected\n" -msgstr "" +msgstr "Control-D detetado\n" -#, fuzzy, c-format +#, c-format msgid "conversion from '%s' to '%s' not available\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "conversão de '%s' para '%s' não disponível\n" -#, fuzzy, c-format +#, c-format msgid "iconv_open failed: %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "iconv_open falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "conversion from '%s' to '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha na conversão de '%s' para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to create temporary file '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "falha ao criar o ficheiro temporário '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error writing to '%s': %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao escrever em '%s': %s\n" #, c-format msgid "removing stale lockfile (created by %d)\n" -msgstr "" +msgstr "removendo ficheiro de bloqueio obsoleto (criado por %d)\n" -#, fuzzy, c-format +#, c-format msgid "waiting for lock (held by %d%s) %s...\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "aguardando bloqueio (mantido por %d%s) %s...\n" msgid "(deadlock?) " -msgstr "" +msgstr "(deadlock?) " -#, fuzzy, c-format +#, c-format msgid "lock '%s' not made: %s\n" -msgstr "chave pública %08lX não encontrada: %s\n" +msgstr "bloqueio '%s' não feito: %s\n" -#, fuzzy, c-format +#, c-format msgid "waiting for lock %s...\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "aguardando bloqueio %s...\n" #, c-format msgid "%s is too old (need %s, have %s)\n" -msgstr "" +msgstr "%s é muito antigo (precisa de %s, tem %s)\n" -#, fuzzy, c-format -#| msgid "error creating `%s': %s\n" +#, c-format msgid "error creating '%s': %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "erro ao criar '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error closing '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fechar '%s': %s\n" #, c-format msgid "armor: %s\n" -msgstr "armadura: %s\n" +msgstr "blindagem: %s\n" #, c-format msgid "invalid armor header: " -msgstr "cabeçalho de armadura inválido: " +msgstr "cabeçalho da blindagem inválido: " #, c-format msgid "armor header: " -msgstr "cabeçalho de armadura: " +msgstr "cabeçalho da blindagem: " #, c-format msgid "invalid clearsig header\n" -msgstr "cabeçalho de assinatura em texto puro inválido\n" +msgstr "cabeçalho clearsig inválido\n" -#, fuzzy, c-format +#, c-format msgid "unknown armor header: " -msgstr "cabeçalho de armadura: " +msgstr "cabeçalho da blindagem desconhecido: " #, c-format msgid "nested clear text signatures\n" -msgstr "assinaturas em texto puro aninhadas\n" +msgstr "assinaturas de texto claro aninhadas\n" -#, fuzzy, c-format +#, c-format msgid "unexpected armor: " -msgstr "armadura inesperada:" +msgstr "blindagem inesperada: " #, c-format msgid "invalid dash escaped line: " -msgstr "linha com hífen inválida: " +msgstr "traço inválido escapou linha: " -#, fuzzy, c-format +#, c-format msgid "invalid radix64 character %02X skipped\n" -msgstr "caracter radix64 inválido %02x ignorado\n" +msgstr "caractere radix64 inválido %02X ignorado\n" #, c-format msgid "premature eof (no CRC)\n" -msgstr "fim de ficheiro prematuro (sem CRC)\n" +msgstr "EOF prematuro (sem CRC)\n" #, c-format msgid "premature eof (in CRC)\n" -msgstr "fim de ficheiro prematuro (no CRC)\n" +msgstr "EOF prematuro (no CRC)\n" #, c-format msgid "malformed CRC\n" msgstr "CRC malformado\n" -#, fuzzy, c-format +#, c-format msgid "CRC error; %06lX - %06lX\n" -msgstr "erro de CRC; %06lx - %06lx\n" +msgstr "erro de CRC; %06lX - %06lX\n" -#, fuzzy, c-format +#, c-format msgid "premature eof (in trailer)\n" -msgstr "fim de ficheiro prematuro (no \"Trailer\")\n" +msgstr "EOF prematuro (em rodapé)\n" #, c-format msgid "error in trailer line\n" -msgstr "erro na última linha\n" +msgstr "erro na linha de rodapé\n" #, c-format msgid "no valid OpenPGP data found.\n" @@ -1314,19 +1305,18 @@ msgstr "nenhum dado OpenPGP válido encontrado.\n" #, c-format msgid "invalid armor: line longer than %d characters\n" -msgstr "armadura inválida: linha maior que %d caracteres\n" +msgstr "blindagem inválida: linha maior que %d caracteres\n" #, c-format msgid "" "quoted printable character in armor - probably a buggy MTA has been used\n" msgstr "" -"caracter \"quoted printable\" na armadura - provavelmente um MTA com bugs " -"foi usado\n" +"caractere imprimível citado na blindagem - provavelmente uma MTA bugada foi " +"usada\n" -#, fuzzy, c-format -#| msgid "not human readable" +#, c-format msgid "[ not human readable (%zu bytes: %s%s) ]" -msgstr "não legível por humanos" +msgstr "[ não legível para humanos (%zu bytes: %s%s) ]" #, c-format msgid "" @@ -1338,28 +1328,23 @@ msgstr "" #, c-format msgid "a user notation name must contain the '@' character\n" -msgstr "um valor de notação de utilizador não deve conter o caracter '@'\n" +msgstr "um nome de notação de utilizador deve conter o caractere '@'\n" -#, fuzzy, c-format +#, c-format msgid "a notation name must not contain more than one '@' character\n" -msgstr "um valor de notação de utilizador não deve conter o caracter '@'\n" +msgstr "um nome de notação não deve conter mais de um caractere '@'\n" #, c-format msgid "a notation value must not use any control characters\n" msgstr "um valor de notação não deve usar caracteres de controle\n" -#, fuzzy, c-format +#, c-format msgid "a notation name may not contain an '=' character\n" -msgstr "um valor de notação de utilizador não deve conter o caracter '@'\n" +msgstr "um nome de notação pode não conter um caractere '='\n" -#, fuzzy, c-format -#| msgid "" -#| "a notation name must have only printable characters or spaces, and end " -#| "with an '='\n" +#, c-format msgid "a notation name must have only printable characters or spaces\n" -msgstr "" -"um nome de notação deve ter apenas caracteres imprimíveis ou espaços, e " -"terminar com um '='\n" +msgstr "um nome de notação deve ter apenas caracteres imprimíveis ou espaços\n" #, c-format msgid "WARNING: invalid notation data found\n" @@ -1367,184 +1352,173 @@ msgstr "AVISO: dados de notação inválidos encontrados\n" #, c-format msgid "failed to proxy %s inquiry to client\n" -msgstr "" +msgstr "falha ao reencaminhar inquérito %s para o cliente\n" msgid "Enter passphrase: " -msgstr "Digite a frase secreta: " +msgstr "Introduzir a frase-secreta: " -#, fuzzy, c-format +#, c-format msgid "%s is not compliant with %s mode\n" -msgstr "%s não faz sentido com %s!\n" +msgstr "%s não é compatível com o modo %s\n" -#, fuzzy, c-format +#, c-format msgid "error from TPM: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro do TPM: %s\n" -#, fuzzy, c-format +#, c-format msgid "problem with the agent: %s\n" -msgstr "problema com o agente: o agente returnou 0x%lx\n" +msgstr "problema com o agent: %s\n" -#, fuzzy, c-format +#, c-format msgid "no dirmngr running in this session\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "nenhum dirmngr em execução nesta sessão\n" -#, fuzzy, c-format -#| msgid "you may not use %s while in %s mode\n" +#, c-format msgid "keyserver option \"honor-keyserver-url\" may not be used in Tor mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "" +"opção de servidor de chaves \"honor-keyserver-url\" não pode ser usada no " +"modo Tor\n" msgid "WKD uses a cached result" -msgstr "" +msgstr "WKD usa um resultado armazenado em cache" msgid "Tor is not running" -msgstr "" +msgstr "Tor não está em execução" -#, fuzzy msgid "Tor is not properly configured" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "Tor não está configurado corretamente" -#, fuzzy msgid "DNS is not properly configured" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "DNS não está configurado corretamente" msgid "unacceptable HTTP redirect from server" -msgstr "" +msgstr "redirecionamento HTTP inaceitável do servidor" msgid "unacceptable HTTP redirect from server was cleaned up" -msgstr "" +msgstr "redirecionamento HTTP inaceitável do servidor foi limpo" -#, fuzzy -#| msgid "generate a revocation certificate" msgid "server uses an invalid certificate" -msgstr "gerar um certificado de revogação" +msgstr "servidor usa um certificado inválido" -#, fuzzy, c-format -#| msgid "armor: %s\n" +#, c-format msgid "Note: %s\n" -msgstr "armadura: %s\n" +msgstr "Nota: %s\n" -#, fuzzy, c-format +#, c-format msgid "OpenPGP card not available: %s\n" -msgstr "chave secreta não disponível" +msgstr "cartão OpenPGP não disponível: %s\n" #, c-format msgid "OpenPGP card no. %s detected\n" -msgstr "" +msgstr "cartão OpenPGP nº %s detetado\n" -#, fuzzy, c-format +#, c-format msgid "can't do this in batch mode\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "não é possível fazer isso no modo batch\n" -#, fuzzy, c-format +#, c-format msgid "This command is only available for version 2 cards\n" -msgstr "Este comando não é permitido no modo %s.\n" +msgstr "Este comando só está disponível para cartões da versão 2\n" -#, fuzzy, c-format +#, c-format msgid "Reset Code not or not anymore available\n" -msgstr "partes da chave secreta não disponíveis\n" +msgstr "Código de Reset não disponível ou não está mais disponível\n" msgid "Your selection? " -msgstr "Opção? " +msgstr "Sua opção? " msgid "[not set]" -msgstr "" +msgstr "[não definido]" msgid "Mr." -msgstr "" +msgstr "Sr." msgid "Ms." -msgstr "" +msgstr "Sra." -#, fuzzy msgid "not forced" -msgstr "não processado" +msgstr "não forçado" msgid "forced" -msgstr "" +msgstr "forçado" #, c-format msgid "Please try command \"%s\" if the listing does not look correct\n" -msgstr "" +msgstr "Tente o comando \"%s\" se a listagem não parecer correta\n" msgid "Error: Only plain ASCII is currently allowed.\n" -msgstr "" +msgstr "Erro: Só ASCII simples é permitido de momento.\n" msgid "Error: The \"<\" character may not be used.\n" -msgstr "" +msgstr "Erro: O caractere \"<\" não pode ser usado.\n" msgid "Error: Double spaces are not allowed.\n" -msgstr "" +msgstr "Erro: Espaços duplos não são permitidos.\n" msgid "Cardholder's surname: " -msgstr "" +msgstr "Nome de família do titular do cartão: " msgid "Cardholder's given name: " -msgstr "" +msgstr "Nome próprio do titular do cartão: " #, c-format msgid "Error: Combined name too long (limit is %d characters).\n" -msgstr "" +msgstr "Erro: Nome combinado muito longo (limite é %d caracteres).\n" -#, fuzzy msgid "URL to retrieve public key: " -msgstr "a escrever chave pública para `%s'\n" +msgstr "URL para buscar a chave pública: " -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" +#, c-format msgid "error reading '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error writing '%s': %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao escrever '%s': %s\n" msgid "Login data (account name): " -msgstr "" +msgstr "Dados de login (nome da conta): " msgid "Private DO data: " -msgstr "" +msgstr "Dados DO privados: " -#, fuzzy msgid "Language preferences: " -msgstr "preferências actualizadas" +msgstr "Preferências de idioma: " -#, fuzzy, c-format +#, c-format msgid "Error: invalid length of preference string.\n" -msgstr "caracter inválido na cadeia de caractéres da preferência\n" +msgstr "Erro: comprimento inválido da string de preferência.\n" -#, fuzzy, c-format +#, c-format msgid "Error: invalid characters in preference string.\n" -msgstr "caracter inválido na cadeia de caractéres da preferência\n" +msgstr "Erro: caracteres inválidos na string de preferência.\n" msgid "Salutation (M = Mr., F = Ms., or space): " -msgstr "" +msgstr "Saudação (M = Sr., F = Sra., ou espaço): " -#, fuzzy msgid "Error: invalid response.\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "Erro: resposta inválida.\n" -#, fuzzy msgid "CA fingerprint: " -msgstr "mostra impressão digital" +msgstr "Impressão digital da CA: " -#, fuzzy, c-format +#, c-format msgid "Error: invalid formatted fingerprint.\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "Erro: impressão digital formatada inválida.\n" -#, fuzzy, c-format +#, c-format msgid "key operation not possible: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "operação de chave não é possível: %s\n" -#, fuzzy msgid "not an OpenPGP card" -msgstr "nenhum dado OpenPGP válido encontrado.\n" +msgstr "não é um cartão OpenPGP" -#, fuzzy, c-format +#, c-format msgid "error getting current key info: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao obter informações de chave atual: %s\n" msgid "Replace existing key? (y/N) " -msgstr "" +msgstr "Substituir chave existente? (s/N) " msgid "" "Note: There is no guarantee that the card supports the requested\n" @@ -1552,10 +1526,14 @@ msgid "" " please check the documentation of your card to see which\n" " key types and sizes are supported.\n" msgstr "" +"Nota: Não há garantia de que o cartão suporte o tipo ou tamanho de\n" +" chave pedida. Se a geração de chaves não for bem-sucedida,\n" +" verifique a documentação do seu cartão para ver quais são os\n" +" tipos e tamanhos de chaves suportados.\n" -#, fuzzy, c-format +#, c-format msgid "What keysize do you want? (%u) " -msgstr "Qual o tamanho de chave desejado? (1024) " +msgstr "Qual tamanho de chave você quer? (%u) " #, c-format msgid "rounded up to %u bits\n" @@ -1563,66 +1541,63 @@ msgstr "arredondado para %u bits\n" #, c-format msgid "%s keysizes must be in the range %u-%u\n" -msgstr "" +msgstr "%s tamanhos de chaves devem estar no intervalo %u-%u\n" msgid "Changing card key attribute for: " -msgstr "" +msgstr "Alterando o atributo de chave do cartão para: " -#, fuzzy msgid "Signature key\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Chave de assinatura\n" -#, fuzzy msgid "Encryption key\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr "Chave de cifração\n" msgid "Authentication key\n" -msgstr "" +msgstr "Chave de autenticação\n" msgid "Please select what kind of key you want:\n" -msgstr "Por favor selecione o tipo de chave desejado:\n" +msgstr "Selecione o tipo de chave desejado:\n" -#, fuzzy, c-format +#, c-format msgid " (%d) RSA\n" -msgstr " (%d) RSA (apenas assinatura)\n" +msgstr " (%d) RSA\n" -#, fuzzy, c-format +#, c-format msgid " (%d) ECC\n" -msgstr " (%d) DSA e ElGamal (por omissão)\n" +msgstr " (%d) ECC\n" msgid "Invalid selection.\n" -msgstr "Opção inválida.\n" +msgstr "Seleção inválida.\n" #, c-format msgid "The card will now be re-configured to generate a key of %u bits\n" -msgstr "" +msgstr "O cartão agora será reconfigurado para gerar uma chave de %u bits\n" #, c-format msgid "The card will now be re-configured to generate a key of type: %s\n" -msgstr "" +msgstr "O cartão agora será reconfigurado para gerar uma chave do tipo: %s\n" -#, fuzzy, c-format +#, c-format msgid "error changing key attribute for key %d: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao alterar o atributo de chave para a chave %d: %s\n" -#, fuzzy, c-format +#, c-format msgid "error getting card info: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao obter informações do cartão: %s\n" -#, fuzzy, c-format -#| msgid "This command is not allowed while in %s mode.\n" +#, c-format msgid "This command is not supported by this card\n" -msgstr "Este comando não é permitido no modo %s.\n" +msgstr "Este comando não é suportado por este cartão\n" msgid "Make off-card backup of encryption key? (Y/n) " -msgstr "" +msgstr "Fazer backup fora-do-cartão da chave de cifração? (S/n) " -#, fuzzy, c-format +#, c-format msgid "Note: keys are already stored on the card!\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "Nota: as chaves já estão armazenadas no cartão!\n" msgid "Replace existing keys? (y/N) " -msgstr "" +msgstr "Substituir chaves existentes? (s/N) " #, c-format msgid "" @@ -1630,138 +1605,121 @@ msgid "" " PIN = '%s' Admin PIN = '%s'\n" "You should change them using the command --change-pin\n" msgstr "" +"Observe que as configurações de fábrica dos PINs são\n" +" PIN = '%s' PIN do Admin = '%s'\n" +"Você deve alterá-los usando o comando --change-pin\n" -#, fuzzy msgid "Please select the type of key to generate:\n" -msgstr "Por favor selecione o tipo de chave desejado:\n" +msgstr "Selecione o tipo de chave a ser gerada:\n" -#, fuzzy msgid " (1) Signature key\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr " (1) Chave de assinatura\n" -#, fuzzy msgid " (2) Encryption key\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (2) Chave de cifração\n" msgid " (3) Authentication key\n" -msgstr "" +msgstr " (3) Chave de autenticação\n" -#, fuzzy msgid "Please select where to store the key:\n" -msgstr "motivo da revocação: " +msgstr "Selecione onde armazenar a chave:\n" -#, fuzzy, c-format +#, c-format msgid "KEYTOCARD failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "Falha no KEYTOCARD: %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: This command destroys all keys stored on the card!\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "Nota: Este comando destrói todas as chaves armazenadas no cartão!\n" -#, fuzzy msgid "Continue? (y/N) " -msgstr "Realmente assinar? " +msgstr "Continuar? (s/N) " msgid "Really do a factory reset? (enter \"yes\") " -msgstr "" +msgstr "De certeza que deseja fazer um reset de fábrica? (introduzir \"sim\") " -#, fuzzy, c-format +#, c-format msgid "error for setup KDF: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro para a configuração KDF: %s\n" -#, fuzzy, c-format +#, c-format msgid "error for setup UIF: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro para a configuração UIF: %s\n" msgid "quit this menu" msgstr "sair deste menu" -#, fuzzy msgid "show admin commands" -msgstr "comandos em conflito\n" +msgstr "mostrar comandos de admin" msgid "show this help" msgstr "mostra esta ajuda" -#, fuzzy msgid "list all available data" -msgstr "Nenhuma ajuda disponível" +msgstr "listar todos os dados disponíveis" msgid "change card holder's name" -msgstr "" +msgstr "alterar o nome do titular do cartão" msgid "change URL to retrieve key" -msgstr "" +msgstr "alterar URL para buscar a chave" msgid "fetch the key specified in the card URL" -msgstr "" +msgstr "buscar a chave especificada na URL do cartão" -#, fuzzy msgid "change the login name" -msgstr "muda a data de validade" +msgstr "alterar o nome de login" -#, fuzzy msgid "change the language preferences" -msgstr "muda os valores de confiança" +msgstr "alterar as preferências de idioma" msgid "change card holder's salutation" -msgstr "" +msgstr "alterar a saudação do titular do cartão" -#, fuzzy msgid "change a CA fingerprint" -msgstr "mostra impressão digital" +msgstr "alterar uma impressão digital da CA" msgid "toggle the signature force PIN flag" -msgstr "" +msgstr "alternar a flag de PIN forçado de assinatura" -#, fuzzy msgid "generate new keys" -msgstr "gerar um novo par de chaves" +msgstr "gerar novas chaves" msgid "menu to change or unblock the PIN" -msgstr "" +msgstr "menu para alterar ou desbloquear o PIN" msgid "verify the PIN and list all data" -msgstr "" +msgstr "verificar o PIN e listar todos os dados" msgid "unblock the PIN using a Reset Code" -msgstr "" +msgstr "desbloquear o PIN usando um Código de Reset" msgid "destroy all keys and data" -msgstr "" +msgstr "destruir todas as chaves e dados" -#, fuzzy -#| msgid "|NAME|use NAME as default recipient" msgid "setup KDF for PIN authentication (on/single/off)" -msgstr "|NOME|usar NOME como destinatário por omissão" +msgstr "configurar o KDF para autenticação por PIN (on/single/off)" -#, fuzzy -#| msgid "change the ownertrust" msgid "change the key attribute" -msgstr "muda os valores de confiança" +msgstr "alterar o atributo da chave" -#, fuzzy -#| msgid "change the ownertrust" msgid "change the User Interaction Flag" -msgstr "muda os valores de confiança" +msgstr "alterar a Flag User Interaction" msgid "switch to the OpenPGP app" -msgstr "" +msgstr "mudar para a app OpenPGP" msgid "gpg/card> " -msgstr "" +msgstr "gpg/cartão> " -#, fuzzy msgid "Admin-only command\n" -msgstr "comandos em conflito\n" +msgstr "Comando só-de-Admin\n" -#, fuzzy msgid "Admin commands are allowed\n" -msgstr "comandos em conflito\n" +msgstr "Comandos de Admin são permitidos\n" -#, fuzzy msgid "Admin commands are not allowed\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "Comandos de Admin não são permitidos\n" #, c-format msgid "Invalid command (try \"help\")\n" @@ -1771,74 +1729,70 @@ msgstr "Comando inválido (tente \"help\")\n" msgid "--output doesn't work for this command\n" msgstr "--output não funciona para este comando\n" -#, fuzzy, c-format -#| msgid "can't open `%s'\n" +#, c-format msgid "can't open '%s'\n" -msgstr "impossível abrir `%s'\n" +msgstr "não é possível abrir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "key \"%s\" not found: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave \"%s\" não encontrada: %s\n" #, c-format msgid "error reading keyblock: %s\n" -msgstr "erro na leitura do bloco de chave: %s\n" +msgstr "erro ao ler keyblock: %s\n" -#, fuzzy, c-format +#, c-format msgid "key \"%s\" not found\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave \"%s\" não encontrada\n" -#, fuzzy, c-format +#, c-format msgid "can't do this in batch mode without \"--yes\"\n" -msgstr "impossível fazer isso em modo não-interactivo sem utilizar \"--yes\"\n" +msgstr "não é possível fazer isso no modo batch sem \"--yes\"\n" #, c-format msgid "(unless you specify the key by fingerprint)\n" -msgstr "(a não ser que escolha a chave pela sua impressão digital)\n" +msgstr "(a menos que você especifique a chave por impressão digital)\n" msgid "Note: The public primary key and all its subkeys will be deleted.\n" msgstr "" +"Nota: A chave pública principal e todas as suas subchaves serão apagadas.\n" msgid "Note: Only the shown public subkey will be deleted.\n" -msgstr "" +msgstr "Nota: Só a subchave pública mostrada será apagada.\n" msgid "Note: Only the secret part of the shown primary key will be deleted.\n" -msgstr "" +msgstr "Nota: Só a parte secreta da chave principal mostrada será apagada.\n" msgid "Note: Only the secret part of the shown subkey will be deleted.\n" -msgstr "" +msgstr "Nota: Só a parte secreta da subchave mostrada será apagada.\n" -#, fuzzy msgid "Delete this key from the keyring? (y/N) " -msgstr "Remover esta chave do porta-chaves?" +msgstr "Apagar esta chave do porta-chaves? (s/N) " -#, fuzzy msgid "This is a secret key! - really delete? (y/N) " -msgstr "Esta chave é secreta! - apagar de qualquer modo? " +msgstr "Esta é uma chave secreta! - de certeza que deseja apagar? (s/N) " -#, fuzzy, c-format +#, c-format msgid "deleting secret %s failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao apagar %s secreta: %s\n" msgid "key" -msgstr "key" +msgstr "chave" -#, fuzzy -#| msgid "Pubkey: " msgid "subkey" -msgstr "Chave pública: " +msgstr "subchave" #, c-format msgid "update failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "falha ao atualizar: %s\n" #, c-format msgid "deleting keyblock failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao excluir o keyblock: %s\n" #, c-format msgid "ownertrust information cleared\n" -msgstr "informações de 'ownertrust' limpas\n" +msgstr "informação de ownertrust limpa\n" #, c-format msgid "there is a secret key for public key \"%s\"!\n" @@ -1846,84 +1800,78 @@ msgstr "há uma chave secreta para a chave pública \"%s\"!\n" #, c-format msgid "use option \"--delete-secret-keys\" to delete it first.\n" -msgstr "utilize a opção \"--delete-secret-keys\" para a apagar primeiro.\n" +msgstr "usar a opção \"--delete-secret-keys\" para apagá-la primeiro.\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n" msgstr "" -"ao forçar a cifra simétrica %s (%d) viola as preferências do destinatário\n" +"AVISO: forçar a cifra simétrica %s (%d) viola as preferências do " +"destinatário\n" -#, fuzzy, c-format +#, c-format msgid "cipher algorithm '%s' may not be used for encryption\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "o algoritmo de cifra '%s' não pode ser usado para a cifração\n" #, c-format msgid "(use option \"%s\" to override)\n" -msgstr "" +msgstr "(use a opção \"%s\" sobrepor)\n" -#, fuzzy, c-format +#, c-format msgid "cipher algorithm '%s' may not be used in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "o algoritmo de cifra '%s' não pode ser usado no modo %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: key %s is not suitable for encryption in %s mode\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "AVISO: a chave %s não é adequada para a cifração no modo %s\n" #, c-format msgid "error creating passphrase: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar frase-secreta: %s\n" -#, fuzzy, c-format -#| msgid "can't use a symmetric ESK packet due to the S2K mode\n" +#, c-format msgid "can't use a SKESK packet due to the S2K mode\n" -msgstr "não é possível utilizar o pacote ESK simétrico devido ao modo S2K\n" +msgstr "não é possível usar um pacote SKESK devido ao modo S2K\n" -#, fuzzy, c-format +#, c-format msgid "using cipher %s.%s\n" -msgstr "assinatura falhou: %s\n" +msgstr "usando a cifra %s.%s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "%s' já comprimido\n" - -#, fuzzy, c-format -#| msgid "WARNING: `%s' is an empty file\n" +#, c-format msgid "WARNING: '%s' is an empty file\n" -msgstr "AVISO: `%s' é um ficheiro vazio\n" +msgstr "AVISO: '%s' é um ficheiro vazio\n" -#, fuzzy, c-format +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' já compresso\n" + +#, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "o algoritmo de digest '%s' não pode ser usado no modo %s\n" -#, fuzzy, c-format -#| msgid "reading from `%s'\n" +#, c-format msgid "reading from '%s'\n" -msgstr "lendo de `%s'\n" +msgstr "lendo de '%s'\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: forcing compression algorithm %s (%d) violates recipient " "preferences\n" msgstr "" -"ao forçar o algoritmo de compressão %s (%d) viola as preferências do " +"AVISO: forçar o algoritmo de compressão %s (%d) viola as preferências do " "destinatário\n" -#, fuzzy, c-format -#| msgid "%s/%s encrypted for: \"%s\"\n" +#, c-format msgid "%s/%s.%s encrypted for: \"%s\"\n" -msgstr "%s/%s cifrado para: \"%s\"\n" +msgstr "%s/%s.%s cifrado para: \"%s\"\n" -#, fuzzy, c-format -#| msgid "you may not use %s while in %s mode\n" +#, c-format msgid "option '%s' may not be used in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "a opção '%s' não pode ser usada no modo %s\n" -#, fuzzy, c-format -#| msgid "%s encrypted data\n" +#, c-format msgid "%s encrypted data\n" -msgstr "dados cifrados com %s\n" +msgstr "%s dados cifrados\n" #, c-format msgid "encrypted with unknown algorithm %d\n" @@ -1933,142 +1881,126 @@ msgstr "cifrado com algoritmo desconhecido %d\n" msgid "" "WARNING: message was encrypted with a weak key in the symmetric cipher.\n" msgstr "" -"AVISO: A mensagem foi cifrada com uma chave fraca na cifragem simétrica.\n" +"AVISO: A mensagem foi cifrada com uma chave fraca na cifra simétrica.\n" #, c-format msgid "problem handling encrypted packet\n" -msgstr "problema ao tratar pacote cifrado\n" +msgstr "problema ao lidar com pacote cifrado\n" -#, fuzzy msgid "export signatures that are marked as local-only" -msgstr "" -"\n" -"A assinatura será marcada como não-revocável.\n" +msgstr "exportar assinaturas marcadas como local-only" msgid "export attribute user IDs (generally photo IDs)" -msgstr "" +msgstr "exportar IDs de utilizador de atributo (geralmente IDs fotográficas)" msgid "export revocation keys marked as \"sensitive\"" -msgstr "" +msgstr "exportar chaves de revogação marcadas como \"sensitivo\"" -#, fuzzy msgid "remove unusable parts from key during export" -msgstr "chave secreta não utilizável" +msgstr "remover partes inutilizáveis da chave durante a exportação" msgid "remove as much as possible from key during export" -msgstr "" +msgstr "remover o máximo possível da chave durante a exportação" -#, fuzzy -#| msgid "generate a revocation certificate" msgid "export only revocation certificates" -msgstr "gerar um certificado de revogação" +msgstr "exportar apenas certificados de revogação" msgid "use the GnuPG key backup format" -msgstr "" +msgstr "usar o formato de backup de chave GnuPG" -#, fuzzy msgid "export secret keys using the GnuPG format" -msgstr "a escrever chave privada para `%s'\n" +msgstr "exportar chaves secretas usando o formato GnuPG" -#, fuzzy -#| msgid "%s: skipped: %s\n" msgid " - skipped" -msgstr "%s: ignorado: %s\n" +msgstr " - ignorada" -#, fuzzy, c-format -#| msgid "writing to `%s'\n" +#, c-format msgid "writing to '%s'\n" -msgstr "a escrever para `%s'\n" +msgstr "escrevendo em '%s'\n" -#, fuzzy, c-format +#, c-format msgid "key %s: key material on-card - skipped\n" -msgstr "chave %08lX: assintura da subchave no local errado - ignorado\n" +msgstr "chave %s: material da chave no cartão - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "exporting secret keys not allowed\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "exportação de chaves secretas não permitida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: PGP 2.x style key - skipped\n" -msgstr "chave %08lX: tipo PGP 2.x - ignorada\n" +msgstr "chave %s: chave tipo PGP 2.x - ignorada\n" #, c-format msgid "WARNING: nothing exported\n" msgstr "AVISO: nada exportado\n" -#, fuzzy msgid "[User ID not found]" -msgstr "[Utilizador não encontrado]" +msgstr "[ID de utilizador não encontrada]" -#, fuzzy, c-format +#, c-format msgid "automatically retrieved '%s' via %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "'%s' obtido automaticamente via %s\n" -#, fuzzy, c-format +#, c-format msgid "error retrieving '%s' via %s: %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "erro ao obter '%s' via %s: %s\n" -#, fuzzy msgid "No fingerprint" -msgstr "mostra impressão digital" +msgstr "Sem impressão digital" #, c-format msgid "checking for a fresh copy of an expired key via %s\n" -msgstr "" +msgstr "verificando se há uma nova cópia de uma chave expirada via %s\n" -#, fuzzy, c-format +#, c-format msgid "secret key \"%s\" not found: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave secreta \"%s\" não encontrada: %s\n" -#, fuzzy, c-format +#, c-format msgid "(check argument of option '%s')\n" -msgstr "opções de importação inválidas\n" +msgstr "(verifica argumento da opção '%s')\n" -#, fuzzy, c-format -#| msgid "|NAME|use NAME as default secret key" +#, c-format msgid "Warning: not using '%s' as default key: %s\n" -msgstr "|NOME|usar NOME como chave secreta por omissão" +msgstr "Aviso: a não usar '%s' como chave pré-definida: %s\n" -#, fuzzy, c-format -#| msgid "|NAME|use NAME as default secret key" +#, c-format msgid "using \"%s\" as default secret key for signing\n" -msgstr "|NOME|usar NOME como chave secreta por omissão" +msgstr "a usar \"%s\" como chave secreta pré-definida para assinatura\n" #, c-format msgid "all values passed to '%s' ignored\n" -msgstr "" +msgstr "todos os valores passados para '%s' ignorados\n" -#, fuzzy, c-format +#, c-format msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n" -msgstr "Chave inválida %08lX tornada válida por --allow-non-selfsigned-uid\n" +msgstr "Chave inválida %s tornada válida por --allow-non-selfsigned-uid\n" -#, fuzzy, c-format +#, c-format msgid "using subkey %s instead of primary key %s\n" -msgstr "usando chave secundária %08lX ao invés de chave primária %08lX\n" +msgstr "usando a subchave %s em vez da chave principal %s\n" -#, fuzzy, c-format +#, c-format msgid "valid values for option '%s':\n" -msgstr "opções de importação inválidas\n" +msgstr "valores válidos para a opção '%s':\n" -#, fuzzy msgid "make a signature" -msgstr "fazer uma assinatura separada" +msgstr "fazer uma assinatura" -#, fuzzy msgid "make a clear text signature" -msgstr "|[ficheiro]|fazer uma assinatura em texto puro" +msgstr "fazer uma assinatura de texto claro" msgid "make a detached signature" -msgstr "fazer uma assinatura separada" +msgstr "fazer uma assinatura desanexada" msgid "encrypt data" msgstr "cifrar dados" msgid "encryption only with symmetric cipher" -msgstr "cifrar apenas com cifra simétrica" +msgstr "cifração apenas com a cifra simétrica" msgid "decrypt data (default)" -msgstr "decifrar dados (acção por omissão)" +msgstr "decifrar dados (ação pré-definida)" msgid "verify a signature" msgstr "verificar uma assinatura" @@ -2079,9 +2011,8 @@ msgstr "listar as chaves" msgid "list keys and signatures" msgstr "listar as chaves e as assinaturas" -#, fuzzy msgid "list and check key signatures" -msgstr "verificar as assinaturas das chaves" +msgstr "listar e verificar assinaturas de chave" msgid "list keys and fingerprints" msgstr "listar as chaves e as impressões digitais" @@ -2092,28 +2023,20 @@ msgstr "listar as chaves secretas" msgid "generate a new key pair" msgstr "gerar um novo par de chaves" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly generate a new key pair" -msgstr "gerar um novo par de chaves" +msgstr "gerar rapidamente um novo par de chaves" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly add a new user-id" -msgstr "gerar um novo par de chaves" +msgstr "adicionar rapidamente um novo user-id" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly revoke a user-id" -msgstr "gerar um novo par de chaves" +msgstr "revogar rapidamente um user-id" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly set a new expiration date" -msgstr "gerar um novo par de chaves" +msgstr "definir rapidamente uma nova data de expiração" msgid "full featured key pair generation" -msgstr "" +msgstr "geração completa de pares de chaves" msgid "generate a revocation certificate" msgstr "gerar um certificado de revogação" @@ -2124,20 +2047,14 @@ msgstr "remover chaves do porta-chaves público" msgid "remove keys from the secret keyring" msgstr "remover chaves do porta-chaves secreto" -#, fuzzy -#| msgid "sign a key" msgid "quickly sign a key" -msgstr "assinar uma chave" +msgstr "assinar rapidamente uma chave" -#, fuzzy -#| msgid "sign a key locally" msgid "quickly sign a key locally" -msgstr "assinar uma chave localmente" +msgstr "assinar rapidamente uma chave localmente" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly revoke a key signature" -msgstr "gerar um novo par de chaves" +msgstr "revogar rapidamente uma assinatura de chave" msgid "sign a key" msgstr "assinar uma chave" @@ -2148,9 +2065,8 @@ msgstr "assinar uma chave localmente" msgid "sign or edit a key" msgstr "assinar ou editar uma chave" -#, fuzzy msgid "change a passphrase" -msgstr "muda a frase secreta" +msgstr "alterar uma frase-secreta" msgid "export keys" msgstr "exportar chaves" @@ -2162,118 +2078,104 @@ msgid "import keys from a keyserver" msgstr "importar chaves de um servidor de chaves" msgid "search for keys on a keyserver" -msgstr "procurar chaves num servidor de chaves" +msgstr "pesquisar chaves num servidor de chaves" msgid "update all keys from a keyserver" -msgstr "actualizar todas as chaves a partir de um servidor de chaves" +msgstr "atualizar todas as chaves de um servidor de chaves" msgid "import/merge keys" msgstr "importar/fundir chaves" msgid "print the card status" -msgstr "" +msgstr "mostrar o status do cartão" msgid "change data on a card" -msgstr "" +msgstr "alterar dados de um cartão" msgid "change a card's PIN" -msgstr "" +msgstr "alterar o PIN de um cartão" msgid "update the trust database" -msgstr "actualizar a base de dados de confiança" +msgstr "atualizar a base de dados da confiança" -#, fuzzy msgid "print message digests" -msgstr "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr "mostrar digests de mensagens" msgid "run in server mode" -msgstr "" +msgstr "executar no modo de servidor" msgid "|VALUE|set the TOFU policy for a key" -msgstr "" +msgstr "|VALUE|definir a política de TOFU para uma chave" msgid "|NAME|use NAME as default secret key" -msgstr "|NOME|usar NOME como chave secreta por omissão" +msgstr "|NAME|usar NAME como chave secreta pré-definida" -#, fuzzy msgid "|NAME|encrypt to user ID NAME as well" -msgstr "|NOME|cifrar para NOME" +msgstr "|NAME|cifrar também para ID de utilizador NAME" msgid "|SPEC|set up email aliases" -msgstr "" +msgstr "|SPEC|configurar aliases de email" msgid "use strict OpenPGP behavior" -msgstr "" +msgstr "usar estritamente comportamento OpenPGP" msgid "do not make any changes" -msgstr "não fazer alterações" +msgstr "não fazer quaisquer alterações" msgid "prompt before overwriting" -msgstr "perguntar antes de sobrepôr" +msgstr "perguntar antes de sobrescrever" msgid "Options controlling the input" -msgstr "" +msgstr "Opções que controlam a entrada" msgid "Options controlling the output" -msgstr "" +msgstr "Opções que controlam a saída" msgid "create ascii armored output" -msgstr "criar saída com armadura ascii" +msgstr "criar saída blindada ASCII" -#, fuzzy msgid "|FILE|write output to FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|escrever saída em FILE" msgid "use canonical text mode" -msgstr "usar modo de texto canônico" +msgstr "usar modo de texto canónico" -#, fuzzy msgid "|N|set compress level to N (0 disables)" -msgstr "" -"|N|estabelecer nível de compressão N\n" -"(0 desactiva)" +msgstr "|N|definir nível de compressão para N (0 desabilita)" msgid "Options controlling key import and export" -msgstr "" +msgstr "Opções que controlam a importação e exportação de chaves" msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address" msgstr "" +"|MECHANISMS|usar MECHANISMS para localizar chaves por endereço de email" -#, fuzzy -#| msgid "import keys from a keyserver" msgid "import missing key from a signature" -msgstr "importar chaves de um servidor de chaves" +msgstr "importar chave ausente a partir de uma assinatura" -#, fuzzy msgid "include the public key in signatures" -msgstr "verificar as assinaturas das chaves" +msgstr "incluir a chave pública nas assinaturas" msgid "disable all access to the dirmngr" -msgstr "" +msgstr "desabilitar todo o acesso ao dirmngr" msgid "Options controlling key listings" -msgstr "" +msgstr "Opções que controlam as listagens de chaves" -#, fuzzy -#| msgid "list secret keys" msgid "Options to specify keys" -msgstr "listar as chaves secretas" +msgstr "Opções para especificar chaves" -#, fuzzy msgid "|USER-ID|encrypt for USER-ID" -msgstr "|NOME|cifrar para NOME" +msgstr "|USER-ID|cifrar para USER-ID" -#, fuzzy msgid "|USER-ID|use USER-ID to sign or decrypt" -msgstr "" -"usar este identificador de utilizador para\n" -"assinar ou decifrar" +msgstr "|USER-ID|usar USER-ID para assinar ou decifrar" msgid "Options for unattended use" -msgstr "" +msgstr "Opções para uso autónomo" msgid "Other options" -msgstr "" +msgstr "Outras opções" msgid "" "@\n" @@ -2282,16 +2184,6 @@ msgstr "" "@\n" "(Veja a página man para uma lista completa de comandos e opções)\n" -#, fuzzy -#| msgid "" -#| "@\n" -#| "Examples:\n" -#| "\n" -#| " -se -r Bob [file] sign and encrypt for user Bob\n" -#| " --clear-sign [file] make a clear text signature\n" -#| " --detach-sign [file] make a detached signature\n" -#| " --list-keys [names] show keys\n" -#| " --fingerprint [names] show fingerprints\n" msgid "" "@\n" "Examples:\n" @@ -2306,29 +2198,22 @@ msgstr "" "Exemplos:\n" "\n" " -se -r Bob [ficheiro] assinar e cifrar para o utilizador Bob\n" -" --clear-sign [ficheiro] criar uma assinatura em texto puro\n" -" --detach-sign [ficheiro] criar uma assinatura separada\n" +" --clear-sign [ficheiro] fazer uma assinatura de texto claro\n" +" --detach-sign [ficheiro] fazer uma assinatura desanexada\n" " --list-keys [nomes] mostrar chaves\n" " --fingerprint [nomes] mostrar impressões digitais\n" -#, fuzzy -#| msgid "Usage: gpg [options] [files] (-h for help)" msgid "Usage: @GPG@ [options] [files] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPG@ [opções] [ficheiros] (-h para ajuda)" -#, fuzzy -#| msgid "" -#| "Syntax: gpg [options] [files]\n" -#| "sign, check, encrypt or decrypt\n" -#| "default operation depends on the input data\n" msgid "" "Syntax: @GPG@ [options] [files]\n" "Sign, check, encrypt or decrypt\n" "Default operation depends on the input data\n" msgstr "" -"Sintaxe: gpg [opções] [ficheiros]\n" -"assina, verifica, cifra ou decifra\n" -"a operação por omissão depende dos dados de entrada\n" +"Sintaxe: @GPG@ [opções] [ficheiros]\n" +"Assinar, verificar, cifrar, ou decifrar\n" +"A operação pré-definida depende dos dados de entrada\n" msgid "" "\n" @@ -2344,175 +2229,175 @@ msgid "Cipher: " msgstr "Cifra: " msgid "Hash: " -msgstr "Dispersão: " +msgstr "Hash: " msgid "Compression: " msgstr "Compressão: " -#, fuzzy, c-format +#, c-format msgid "usage: %s [options] %s\n" -msgstr "uso: gpg [opções] " +msgstr "uso: %s [opções] %s\n" #, c-format msgid "conflicting commands\n" msgstr "comandos em conflito\n" -#, fuzzy, c-format +#, c-format msgid "no = sign found in group definition '%s'\n" -msgstr "nenhum sinal = encontrada na definição de grupo \"%s\"\n" +msgstr "nenhum sinal '=' encontrado na definição de grupo '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe ownership on homedir '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro na homedir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe ownership on configuration file '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro no ficheiro de configuração '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe ownership on extension '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro na extensão '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe permissions on homedir '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras na homedir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe permissions on configuration file '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras no ficheiro de configuração '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe permissions on extension '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras na extensão '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro da pasta envolvente a homedir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: unsafe enclosing directory ownership on configuration file '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "" +"AVISO: ownership inseguro da pasta envolvente ao ficheiro de configuração " +"'%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro da pasta envolvente à extensão '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras da pasta envolvente a homedir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "" +"AVISO: permissões inseguras da pasta envolvente ao ficheiro de configuração " +"'%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras da pasta envolvente à extensão '%s'\n" -#, fuzzy, c-format +#, c-format msgid "unknown configuration item '%s'\n" -msgstr "criado um novo ficheiro de configuração `%s'\n" +msgstr "item de configuração '%s' desconhecido\n" msgid "display photo IDs during key listings" -msgstr "" +msgstr "exibir IDs fotográficas durante as listagens de chaves" -#, fuzzy msgid "show key usage information during key listings" -msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" +msgstr "" +"mostrar informação de utilização da chave durante as listagens de chaves" msgid "show policy URLs during signature listings" -msgstr "" +msgstr "mostrar URLs de política durante listagens de assinaturas" -#, fuzzy msgid "show all notations during signature listings" -msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" +msgstr "mostrar todas as anotações durante as listagens de assinaturas" msgid "show IETF standard notations during signature listings" -msgstr "" +msgstr "mostrar notações da norma IETF durante listagens de assinaturas" msgid "show user-supplied notations during signature listings" -msgstr "" +msgstr "mostrar anotações user-supplied durante as listagens de assinaturas" -#, fuzzy msgid "show preferred keyserver URLs during signature listings" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "" +"mostrar URLs de servidor de chaves preferenciais durante listagens de " +"assinaturas" msgid "show user ID validity during key listings" -msgstr "" +msgstr "mostrar a validade da ID de utilizador durante as listagens de chaves" msgid "show revoked and expired user IDs in key listings" -msgstr "" +msgstr "mostrar IDs de utilizador revogadas e expiradas em listagens de chaves" msgid "show revoked and expired subkeys in key listings" -msgstr "" +msgstr "mostrar subchaves revogadas e expiradas em listagens de chaves" -#, fuzzy msgid "show signatures with invalid algorithms during signature listings" -msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" +msgstr "" +"mostrar assinaturas com algoritmos inválidos durante as listagens de " +"assinaturas" -#, fuzzy msgid "show the keyring name in key listings" -msgstr "mostrar em que porta-chave a chave está" +msgstr "mostrar o nome do porta-chaves nas listagens de chaves" -#, fuzzy msgid "show expiration dates during signature listings" -msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" +msgstr "mostrar datas de expiração durante as listagens de assinaturas" -#, fuzzy -#| msgid "set preference list" msgid "show preferences" -msgstr "configurar lista de preferências" +msgstr "mostrar preferências" -#, fuzzy, c-format +#, c-format msgid "unknown TOFU policy '%s'\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "política TOFU desconhecida '%s'\n" #, c-format msgid "(use \"help\" to list choices)\n" -msgstr "" +msgstr "(usar \"help\" para listar opções)\n" #, c-format msgid "This command is not allowed while in %s mode.\n" msgstr "Este comando não é permitido no modo %s.\n" -#, fuzzy, c-format -#| msgid "NOTE: %s is not for normal use!\n" +#, c-format msgid "Note: %s is not for normal use!\n" -msgstr "NOTA: %s não é para uso normal!\n" +msgstr "Nota: %s não é para o uso normal!\n" -#, fuzzy, c-format +#, c-format msgid "'%s' is not a valid signature expiration\n" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "'%s' não é uma expiração de assinatura válida\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" is not a proper mail address\n" -msgstr "Endereço eletrónico inválido\n" +msgstr "\"%s\" não é um endereço de email correto\n" -#, fuzzy, c-format +#, c-format msgid "invalid pinentry mode '%s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "modo de pinentry inválido '%s'\n" -#, fuzzy, c-format +#, c-format msgid "invalid request origin '%s'\n" -msgstr "opções de importação inválidas\n" +msgstr "origem de pedido inválida '%s'\n" -#, fuzzy, c-format +#, c-format msgid "'%s' is not a valid character set\n" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "'%s' não é um set de caracteres válido\n" -#, fuzzy, c-format +#, c-format msgid "could not parse keyserver URL\n" -msgstr "não consegui processar a URI do servidor de chaves\n" +msgstr "não foi possível processar a URL do servidor de chaves\n" -#, fuzzy, c-format +#, c-format msgid "%s:%d: invalid keyserver options\n" -msgstr "%s:%d: opções de exportação inválidas\n" +msgstr "%s:%d: opções inválidas do servidor de chaves\n" -#, fuzzy, c-format +#, c-format msgid "invalid keyserver options\n" -msgstr "opções de exportação inválidas\n" +msgstr "Opções inválidas do servidor de chaves\n" #, c-format msgid "%s:%d: invalid import options\n" @@ -2522,9 +2407,9 @@ msgstr "%s:%d: opções de importação inválidas\n" msgid "invalid import options\n" msgstr "opções de importação inválidas\n" -#, fuzzy, c-format +#, c-format msgid "invalid filter option: %s\n" -msgstr "opções de importação inválidas\n" +msgstr "opção de filtro inválida: %s\n" #, c-format msgid "%s:%d: invalid export options\n" @@ -2534,72 +2419,73 @@ msgstr "%s:%d: opções de exportação inválidas\n" msgid "invalid export options\n" msgstr "opções de exportação inválidas\n" -#, fuzzy, c-format +#, c-format msgid "%s:%d: invalid list options\n" -msgstr "%s:%d: opções de importação inválidas\n" +msgstr "%s:%d: opções de listagem inválidas\n" -#, fuzzy, c-format +#, c-format msgid "invalid list options\n" -msgstr "opções de importação inválidas\n" +msgstr "opções de lista inválidas\n" msgid "display photo IDs during signature verification" -msgstr "" +msgstr "exibir IDs fotográficas durante a verificação da assinatura" msgid "show policy URLs during signature verification" -msgstr "" +msgstr "mostrar URLs de política durante a verificação da assinatura" -#, fuzzy msgid "show all notations during signature verification" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "mostrar todas as anotações durante a verificação da assinatura" msgid "show IETF standard notations during signature verification" -msgstr "" +msgstr "mostrar notações da norma IETF durante a verificação da assinatura" msgid "show user-supplied notations during signature verification" -msgstr "" +msgstr "mostrar anotações user-supplied durante a verificação da assinatura" -#, fuzzy msgid "show preferred keyserver URLs during signature verification" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "" +"mostrar URLs preferenciais do servidor de chaves durante a verificação da " +"assinatura" -#, fuzzy msgid "show user ID validity during signature verification" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "" +"mostrar a validade da ID de utilizador durante a verificação da assinatura" msgid "show revoked and expired user IDs in signature verification" msgstr "" +"mostrar IDs de utilizador revogadas e expiradas na verificação da assinatura" -#, fuzzy msgid "show only the primary user ID in signature verification" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "" +"mostrar apenas a ID de utilizador principal na verificação da assinatura" -#, fuzzy, c-format +#, c-format msgid "%s:%d: invalid verify options\n" -msgstr "%s:%d: opções de exportação inválidas\n" +msgstr "%s:%d: opções de verificação inválidas\n" -#, fuzzy, c-format +#, c-format msgid "invalid verify options\n" -msgstr "opções de exportação inválidas\n" +msgstr "opções de verificação inválidas\n" #, c-format msgid "unable to set exec-path to %s\n" -msgstr "não foi possível alterar o exec-path para %s\n" +msgstr "incapaz de definir exec-path para %s\n" -#, fuzzy, c-format +#, c-format msgid "%s:%d: invalid auto-key-locate list\n" -msgstr "%s:%d: opções de exportação inválidas\n" +msgstr "%s:%d: lista auto-key-locate inválida\n" #, c-format msgid "invalid auto-key-locate list\n" -msgstr "" +msgstr "lista auto-key-locate inválida\n" -#, fuzzy, c-format +#, c-format msgid "invalid argument for option \"%.50s\"\n" -msgstr "opções de importação inválidas\n" +msgstr "argumento inválido para a opção \"%.50s\"\n" #, c-format msgid "WARNING: program may create a core file!\n" -msgstr "AVISO: O programa pode criar um ficheiro core!\n" +msgstr "AVISO: o programa poderá criar um ficheiro core!\n" #, c-format msgid "WARNING: %s overrides %s\n" @@ -2615,23 +2501,23 @@ msgstr "%s não faz sentido com %s!\n" #, c-format msgid "WARNING: running with faked system time: " -msgstr "" +msgstr "AVISO: a correr com tempo de sistema falsificado: " -#, fuzzy, c-format +#, c-format msgid "will not run with insecure memory due to %s\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "não correrei com memória insegura devido a %s\n" #, c-format msgid "selected cipher algorithm is invalid\n" -msgstr "o algoritmo de cifragem selecionado é inválido\n" +msgstr "o algoritmo de cifra selecionado é inválido\n" -#, fuzzy, c-format +#, c-format msgid "selected compression algorithm is invalid\n" -msgstr "o algoritmo de cifragem selecionado é inválido\n" +msgstr "o algoritmo de compressão selecionado é inválido\n" #, c-format msgid "selected certification digest algorithm is invalid\n" -msgstr "o algoritmo de \"digest\" de certificação selecionado é inválido\n" +msgstr "o algoritmo selecionado de digest da certificação é inválido\n" #, c-format msgid "completes-needed must be greater than 0\n" @@ -2641,289 +2527,276 @@ msgstr "completes-needed deve ser maior que 0\n" msgid "marginals-needed must be greater than 1\n" msgstr "marginals-needed deve ser maior que 1\n" -#, fuzzy, c-format +#, c-format msgid "max-cert-depth must be in the range from 1 to 255\n" -msgstr "max-cert-depth deve estar na entre 1 e 255\n" +msgstr "max-cert-depth deve estar na faixa entre 1 a 255\n" -#, fuzzy, c-format +#, c-format msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n" -msgstr "nível de verificação por omissão inválido: deve ser 0, 1, 2 ou 3\n" +msgstr "default-cert-level inválido; deve ser 0, 1, 2, ou 3\n" -#, fuzzy, c-format +#, c-format msgid "invalid min-cert-level; must be 1, 2, or 3\n" -msgstr "nível de verificação por omissão inválido: deve ser 0, 1, 2 ou 3\n" +msgstr "min-cert-level inválido; deve ser 1, 2, ou 3\n" -#, fuzzy, c-format -#| msgid "NOTE: simple S2K mode (0) is strongly discouraged\n" +#, c-format msgid "Note: simple S2K mode (0) is strongly discouraged\n" -msgstr "NOTA: o modo S2K simples (0) não é recomendável\n" +msgstr "Nota: o modo S2K simples (0) é fortemente desencorajado\n" #, c-format msgid "invalid S2K mode; must be 0, 1 or 3\n" -msgstr "modo S2K inválido: deve ser 0, 1 ou 3\n" +msgstr "modo S2K inválido: deve ser 0, 1, ou 3\n" #, c-format msgid "invalid default preferences\n" -msgstr "preferências por omissão inválidas\n" +msgstr "preferências pré-definidas inválidas\n" #, c-format msgid "invalid personal cipher preferences\n" -msgstr "preferências pessoais de cifra inválidas\n" +msgstr "preferências pessoais da cifra inválidas\n" #, c-format msgid "invalid personal digest preferences\n" -msgstr "preferências pessoais de 'digest' inválidas\n" +msgstr "preferências pessoais de digest inválidas\n" #, c-format msgid "invalid personal compress preferences\n" -msgstr "preferências pessoais de compressão inválidas\n" +msgstr "preferências pessoais da compressão inválidas\n" -#, fuzzy, c-format -#| msgid "keysize invalid; using %u bits\n" +#, c-format msgid "chunk size invalid - using %d\n" -msgstr "tamanho de chave inválido; a utilizar %u bits\n" +msgstr "tamanho do chunk inválido - usando %d\n" -#, fuzzy, c-format +#, c-format msgid "%s does not yet work with %s\n" -msgstr "%s não faz sentido com %s!\n" +msgstr "%s ainda não funciona com %s\n" -#, fuzzy, c-format +#, c-format msgid "compression algorithm '%s' may not be used in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "o algoritmo de compressão '%s' não pode ser usado no modo %s\n" #, c-format msgid "failed to initialize the TrustDB: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao inicializar a TrustDB: %s\n" #, c-format msgid "WARNING: recipients (-r) given without using public key encryption\n" msgstr "" -"AVISO: destinatários (-r) dados sem utilizar uma cifra de chave pública\n" +"AVISO: destinatários (-r) fornecidos sem usar cifração de chave pública\n" -#, fuzzy, c-format +#, c-format msgid "symmetric encryption of '%s' failed: %s\n" -msgstr "decifragem falhou: %s\n" +msgstr "falha na cifração simétrica de '%s': %s\n" #, c-format msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n" -msgstr "" +msgstr "você não pode usar --symmetric --encrypt com --s2k-mode 0\n" -#, fuzzy, c-format +#, c-format msgid "you cannot use --symmetric --encrypt in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "você não pode usar --symmetric --encrypt no modo %s\n" #, c-format msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n" -msgstr "" +msgstr "você não pode usar --symmetric --sign --encrypt com --s2k-mode 0\n" -#, fuzzy, c-format +#, c-format msgid "you cannot use --symmetric --sign --encrypt in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "você não pode usar --symmetric --sign --encrypt no modo %s\n" -#, fuzzy, c-format +#, c-format msgid "keyserver send failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou o envio ao servidor de chaves: %s\n" -#, fuzzy, c-format +#, c-format msgid "keyserver receive failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou o receber do servidor de chaves: %s\n" -#, fuzzy, c-format +#, c-format msgid "key export failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou a exportação de chaves: %s\n" -#, fuzzy, c-format +#, c-format msgid "export as ssh key failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou a exportação como chave ssh: %s\n" -#, fuzzy, c-format +#, c-format msgid "keyserver search failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou a pesquisa no servidor de chaves: %s\n" -#, fuzzy, c-format +#, c-format msgid "keyserver refresh failed: %s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "falhou a atualização do servidor de chaves: %s\n" #, c-format msgid "dearmoring failed: %s\n" -msgstr "retirada de armadura falhou: %s\n" +msgstr "falhou ao desblindar: %s\n" #, c-format msgid "enarmoring failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falhou ao blindar: %s\n" -#, fuzzy, c-format -#| msgid "invalid hash algorithm `%s'\n" +#, c-format msgid "invalid hash algorithm '%s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash inválido '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error parsing key specification '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao processar a especificação de chave '%s': %s\n" #, c-format msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n" msgstr "" +"'%s' não parece ser uma ID de chave, impressão digital, ou keygrip, válidas\n" #, c-format msgid "WARNING: no command supplied. Trying to guess what you mean ...\n" msgstr "" +"AVISO: nenhum comando fornecido. A tentar adivinhar o que você quer " +"dizer...\n" #, c-format msgid "Go ahead and type your message ...\n" -msgstr "Digite a sua mensagem ...\n" +msgstr "Esteja à vontade para digitar a sua mensagem ...\n" #, c-format msgid "the given certification policy URL is invalid\n" -msgstr "a URL de política de certificação dada é inválida\n" +msgstr "a URL da política de certificação fornecida é inválida\n" #, c-format msgid "the given signature policy URL is invalid\n" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "a URL de política de assinatura fornecida é inválida\n" -#, fuzzy, c-format +#, c-format msgid "the given preferred keyserver URL is invalid\n" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "a URL fornecida do servidor de chaves preferencial é inválida\n" -#, fuzzy msgid "|FILE|take the keys from the keyring FILE" -msgstr "Remover esta chave do porta-chaves?" +msgstr "|FILE|tome as chaves do porta-chaves FILE" -#, fuzzy msgid "make timestamp conflicts only a warning" -msgstr "conflito de \"timestamp\"" +msgstr "tornar os conflitos de timestamp apenas um aviso" msgid "|FD|write status info to this FD" -msgstr "" -"|DF|escrever informações de estado para o\n" -"descritor de ficheiro DF" +msgstr "|FD|escrever informações de status para este FD" msgid "|ALGO|reject signatures made with ALGO" -msgstr "" +msgstr "|ALGO|rejeitar assinaturas feitas com ALGO" -#, fuzzy msgid "Usage: gpgv [options] [files] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: gpgv [opções] [ficheiros] (-h para ajuda)" msgid "" "Syntax: gpgv [options] [files]\n" "Check signatures against known trusted keys\n" msgstr "" +"Sintaxe: gpgv [opções] [ficheiros]\n" +"Verificar assinaturas em relação a chaves confiáveis conhecidas\n" msgid "No help available" msgstr "Nenhuma ajuda disponível" -#, fuzzy, c-format -#| msgid "No help available for `%s'" +#, c-format msgid "No help available for '%s'" -msgstr "Nenhuma ajuda disponível para `%s'" +msgstr "Nenhuma ajuda disponível para '%s'" msgid "import signatures that are marked as local-only" -msgstr "" +msgstr "importar assinaturas marcadas como local-only" msgid "repair damage from the pks keyserver during import" -msgstr "" +msgstr "reparar os danos do servidor de chaves pks durante a importação" -#, fuzzy msgid "do not clear the ownertrust values during import" -msgstr "actualizar a base de dados de confiança" +msgstr "não limpar os valores de ownertrust durante a importação" -#, fuzzy msgid "do not update the trustdb after import" -msgstr "actualizar a base de dados de confiança" +msgstr "não atualizar a trustdb após a importação" -#, fuzzy -#| msgid "not supported" msgid "enable bulk import mode" -msgstr "não suportado" +msgstr "habilitar o modo de importação em massa" -#, fuzzy msgid "show key during import" -msgstr "mostra impressão digital" +msgstr "mostrar chave durante a importação" -#, fuzzy msgid "show key but do not actually import" -msgstr "mostra impressão digital" +msgstr "mostrar chave, mas não chegar a importar" msgid "only accept updates to existing keys" -msgstr "" +msgstr "aceitar apenas atualizações para chaves existentes" -#, fuzzy msgid "remove unusable parts from key after import" -msgstr "chave secreta não utilizável" +msgstr "remover partes inutilizáveis da chave após a importação" msgid "remove as much as possible from key after import" -msgstr "" +msgstr "remover da chave o máximo possível após a importação" msgid "ignore key-signatures which are not self-signatures" -msgstr "" +msgstr "ignorar assinaturas de chave que não são auto-assinaturas" msgid "run import filters and export key immediately" -msgstr "" +msgstr "executar filtros de importação e exportar chave imediatamente" msgid "assume the GnuPG key backup format" -msgstr "" +msgstr "assumir o formato de backup de chave GnuPG" -#, fuzzy msgid "repair keys on import" -msgstr "mostra impressão digital" +msgstr "reparar chaves ao importar" #, c-format msgid "skipping block of type %d\n" msgstr "ignorando bloco do tipo %d\n" -#, fuzzy, c-format +#, c-format msgid "%lu keys processed so far\n" msgstr "%lu chaves processadas até agora\n" #, c-format msgid "Total number processed: %lu\n" -msgstr "Número total processado: %lu\n" +msgstr " Número total processado: %lu\n" -#, fuzzy, c-format -#| msgid " skipped new keys: %lu\n" +#, c-format msgid " skipped PGP-2 keys: %lu\n" -msgstr " ignorei novas chaves: %lu\n" +msgstr " chaves PGP-2 ignoradas: %lu\n" #, c-format msgid " skipped new keys: %lu\n" -msgstr " ignorei novas chaves: %lu\n" +msgstr " novas chaves ignoradas: %lu\n" #, c-format msgid " w/o user IDs: %lu\n" -msgstr " sem IDs de utilizadores: %lu\n" +msgstr " sem IDs de utilizadores: %lu\n" #, c-format msgid " imported: %lu" -msgstr " importados: %lu" +msgstr " importadas: %lu" #, c-format msgid " unchanged: %lu\n" -msgstr " não modificados: %lu\n" +msgstr " não modificadas: %lu\n" #, c-format msgid " new user IDs: %lu\n" -msgstr " novos IDs de utilizadores: %lu\n" +msgstr " novas IDs de utilizadores: %lu\n" #, c-format msgid " new subkeys: %lu\n" -msgstr " novas subchaves: %lu\n" +msgstr " novas subchaves: %lu\n" #, c-format msgid " new signatures: %lu\n" -msgstr " novas assinaturas: %lu\n" +msgstr " novas assinaturas: %lu\n" #, c-format msgid " new key revocations: %lu\n" -msgstr " novas revogações de chaves: %lu\n" +msgstr " novas revogações de chaves: %lu\n" #, c-format msgid " secret keys read: %lu\n" -msgstr " chaves secretas lidas: %lu\n" +msgstr " chaves secretas lidas: %lu\n" #, c-format msgid " secret keys imported: %lu\n" -msgstr " chaves secretas importadas: %lu\n" +msgstr " chaves secretas importadas: %lu\n" #, c-format msgid " secret keys unchanged: %lu\n" @@ -2931,162 +2804,165 @@ msgstr " chaves secretas não modificadas: %lu\n" #, c-format msgid " not imported: %lu\n" -msgstr " não importadas: %lu\n" +msgstr " não importadas: %lu\n" -#, fuzzy, c-format +#, c-format msgid " signatures cleaned: %lu\n" -msgstr " novas assinaturas: %lu\n" +msgstr " assinaturas limpas: %lu\n" -#, fuzzy, c-format +#, c-format msgid " user IDs cleaned: %lu\n" -msgstr " chaves secretas lidas: %lu\n" +msgstr " IDs de utilizador limpas: %lu\n" #, c-format msgid "" "WARNING: key %s contains preferences for unavailable\n" "algorithms on these user IDs:\n" msgstr "" +"AVISO: a chave %s contém preferências para algoritmos\n" +"indisponíveis nestas IDs de utilizador:\n" #, c-format msgid " \"%s\": preference for cipher algorithm %s\n" -msgstr "" +msgstr " \"%s\": preferência para algoritmo da cifra %s\n" -#, fuzzy, c-format +#, c-format msgid " \"%s\": preference for AEAD algorithm %s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr " \"%s\": preferência para algoritmo AEAD %s\n" -#, fuzzy, c-format +#, c-format msgid " \"%s\": preference for digest algorithm %s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr " \"%s\": preferência para algoritmo digest %s\n" #, c-format msgid " \"%s\": preference for compression algorithm %s\n" -msgstr "" +msgstr " \"%s\": preferência para algoritmo de compressão %s\n" #, c-format msgid "it is strongly suggested that you update your preferences and\n" -msgstr "" +msgstr "é altamente recomendável que você atualize suas preferências e\n" #, c-format msgid "re-distribute this key to avoid potential algorithm mismatch problems\n" msgstr "" +"redistribua esta chave para evitar possíveis problemas de incompatibilidade " +"de algoritmos\n" #, c-format msgid "you can update your preferences with: gpg --edit-key %s updpref save\n" msgstr "" +"você pode atualizar suas preferências com: gpg --edit-key %s updpref save\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no user ID\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "chave %s: sem ID de utilizador\n" -#, fuzzy, c-format +#, c-format msgid "key %s: %s\n" -msgstr "ignorado `%s': %s\n" +msgstr "chave %s: %s\n" msgid "rejected by import screener" -msgstr "" +msgstr "rejeitado pelo rastreador de importação" -#, fuzzy, c-format +#, c-format msgid "key %s: PKS subkey corruption repaired\n" -msgstr "chave %08lX: subchave HKP corrompida foi reparada\n" +msgstr "chave %s: corrupção de subchave PKS reparada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: accepted non self-signed user ID \"%s\"\n" -msgstr "chave %08lX: aceite ID de utilizador sem auto-assinatura '%s'\n" +msgstr "chave %s: foi aceite ID de utilizador não auto-assinada \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no valid user IDs\n" -msgstr "chave %08lX: sem IDs de utilizadores válidos\n" +msgstr "chave %s: sem IDs de utilizador válidas\n" #, c-format msgid "this may be caused by a missing self-signature\n" -msgstr "isto pode ser causado por falta de auto-assinatura\n" +msgstr "isto pode ser causado pela ausência de auto-assinatura\n" -#, fuzzy, c-format +#, c-format msgid "key %s: public key not found: %s\n" -msgstr "chave %08lX: chave pública não encontrada: %s\n" +msgstr "chave %s: chave pública não encontrada: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s: new key - skipped\n" -msgstr "chave %08lX: chave nova - ignorada\n" +msgstr "chave %s: nova chave - ignorada\n" #, c-format msgid "no writable keyring found: %s\n" -msgstr "não foi encontrada nenhum porta-chaves onde escrever: %s\n" +msgstr "nenhum porta-chaves com permissão de escrita encontrado: %s\n" -#, fuzzy, c-format -#| msgid "error writing keyring `%s': %s\n" +#, c-format msgid "error writing keyring '%s': %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao escrever porta-chaves '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s: public key \"%s\" imported\n" -msgstr "chave %08lX: chave pública \"%s\" importada\n" +msgstr "chave %s: chave pública \"%s\" importada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: doesn't match our copy\n" -msgstr "chave %08lX: não corresponde à nossa cópia\n" +msgstr "chave %s: não corresponde à nossa cópia\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" 1 new user ID\n" -msgstr "chave %8lX: \"%s\" 1 novo ID de utilizador\n" +msgstr "chave %s: \"%s\" 1 nova ID de utilizador\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d new user IDs\n" -msgstr "chave %08lX: \"%s\" %d novos IDs de utilizadores\n" +msgstr "chave %s: \"%s\" %d novas IDs de utilizador\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" 1 new signature\n" -msgstr "chave %08lX: \"%s\" 1 nova assinatura\n" +msgstr "chave %s: \"%s\" 1 nova assinatura\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d new signatures\n" -msgstr "chave %08lX: \"%s\" %d novas assinaturas\n" +msgstr "chave %s: \"%s\" %d novas assinaturas\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" 1 new subkey\n" -msgstr "chave %08lX: \"%s\" 1 nova subchave\n" +msgstr "chave %s: \"%s\" 1 nova subchave\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d new subkeys\n" -msgstr "chave %08lX: \"%s\" %d novas subchaves\n" +msgstr "chave %s: \"%s\" %d novas subchaves\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d signature cleaned\n" -msgstr "chave %08lX: \"%s\" %d novas assinaturas\n" +msgstr "chave %s: \"%s\" %d assinatura limpa\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d signatures cleaned\n" -msgstr "chave %08lX: \"%s\" %d novas assinaturas\n" +msgstr "chave %s: \"%s\" %d assinaturas limpas\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d user ID cleaned\n" -msgstr "chave %08lX: \"%s\" %d novos IDs de utilizadores\n" +msgstr "chave %s: \"%s\" %d ID de utilizador limpa\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d user IDs cleaned\n" -msgstr "chave %08lX: \"%s\" %d novos IDs de utilizadores\n" +msgstr "chave %s: \"%s\" %d IDs de utilizador limpas\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" not changed\n" -msgstr "chave %08lX: \"%s\" não modificada\n" +msgstr "chave %s: \"%s\" não alterada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: secret key imported\n" -msgstr "chave %08lX: chave secreta importada\n" +msgstr "chave %s: chave secreta importada\n" -#, fuzzy, c-format -#| msgid "skipped: secret key already present\n" +#, c-format msgid "key %s: secret key already exists\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "chave %s: chave secreta já existe\n" -#, fuzzy, c-format +#, c-format msgid "key %s: error sending to agent: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "chave %s: erro ao enviar para o agent: %s\n" #, c-format msgid "key %s: card reference is overridden by key material\n" -msgstr "" +msgstr "chave %s: a referência do cartão é sobreposta pelo material da chave\n" #. TRANSLATORS: For a smartcard, each private key on host has a #. * reference (stub) to a smartcard and actual private key data @@ -3098,25 +2974,25 @@ msgstr "" #. * again. #, c-format msgid "To migrate '%s', with each smartcard, run: %s\n" -msgstr "" +msgstr "Para migrar '%s', com cada smartcard, execute: %s\n" -#, fuzzy, c-format +#, c-format msgid "secret key %s: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave secreta %s: %s\n" -#, fuzzy, c-format +#, c-format msgid "importing secret keys not allowed\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "importação de chaves secretas não permitida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: secret key with invalid cipher %d - skipped\n" -msgstr "chave %08lX: chave secreta com cifra inválida %d - ignorada\n" +msgstr "chave %s: chave secreta com a cifra %d inválida - ignorada\n" msgid "No reason specified" msgstr "Nenhum motivo especificado" msgid "Key is superseded" -msgstr "A chave foi substituída" +msgstr "A chave foi suplantada" msgid "Key has been compromised" msgstr "A chave foi comprometida" @@ -3125,217 +3001,218 @@ msgid "Key is no longer used" msgstr "A chave já não é utilizada" msgid "User ID is no longer valid" -msgstr "O identificador do utilizador já não é válido" +msgstr "A ID de utilizador já não é válida" #, c-format msgid "reason for revocation: " -msgstr "motivo da revocação: " +msgstr "motivo da revogação: " #, c-format msgid "revocation comment: " -msgstr "comentário da revocação: " +msgstr "comentário da revogação: " -#, fuzzy, c-format +#, c-format msgid "key %s: no public key - can't apply revocation certificate\n" msgstr "" -"chave %08lX: sem chave pública - impossível aplicar certificado\n" -"de revogação\n" +"chave %s: nenhuma chave pública - não é possível aplicar certificado de " +"revogação\n" -#, fuzzy, c-format +#, c-format msgid "key %s: can't locate original keyblock: %s\n" -msgstr "chave %08lX: impossível localizar bloco de chaves original: %s\n" +msgstr "chave %s: não é possível localizar o keyblock original: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s: can't read original keyblock: %s\n" -msgstr "chave %08lX: impossível ler bloco de chaves original: %s\n" +msgstr "chave %s: não é possível ler o keyblock original: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid revocation certificate: %s - rejected\n" -msgstr "chave %08lX: certificado de revogação inválido: %s - rejeitado\n" +msgstr "chave %s: certificado de revogação inválido: %s - rejeitado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" revocation certificate imported\n" -msgstr "chave %08lX: \"%s\" certificado de revogação importado\n" +msgstr "chave %s: certificado de revogação \"%s\" importado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no user ID for signature\n" -msgstr "chave %08lX: nenhum ID de utilizador para assinatura\n" +msgstr "chave %s: nenhuma ID de utilizador para assinatura\n" -#, fuzzy, c-format +#, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"chave %08lX: algoritmo de chave pública não suportado no utilizador \"%s\"\n" +"chave %s: sem suporte a algoritmo de chave pública na ID de utilizador " +"\"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" -msgstr "chave %08lX: auto-assinatura inválida do utilizador \"%s\"\n" +msgstr "chave %s: auto-assinatura inválida na ID de utilizador \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "key %s: unsupported public key algorithm\n" -msgstr "chave %08lX: algoritmo de chave pública não suportado\n" +msgstr "chave %s: sem suporte ao algoritmo de chave pública\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid direct key signature\n" -msgstr "chave %08lX: assinatura directa de chave adicionada\n" +msgstr "chave %s: assinatura de chave direta inválida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no subkey for key binding\n" -msgstr "chave %08lX: sem subchave para ligação de chaves\n" +msgstr "chave %s: nenhuma subchave para vinculação de chave\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid subkey binding\n" -msgstr "chave %08lX: ligação de subchave inválida\n" +msgstr "chave %s: vinculação de subchave inválida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: removed multiple subkey binding\n" -msgstr "chave %08lX: apagada ligação múltipla de subchave \n" +msgstr "chave %s: vinculação de várias subchaves removida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no subkey for key revocation\n" -msgstr "chave %08lX: sem subchave para revocação de chave\n" +msgstr "chave %s: nenhuma subchave para revogação de chave\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid subkey revocation\n" -msgstr "chave %08lX: revocação de subchave inválida\n" +msgstr "chave %s: revogação de subchave inválida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: removed multiple subkey revocation\n" -msgstr "chave %08lX: removida revogação múltiplace de subchaves\n" +msgstr "chave %s: revogação de várias subchaves removida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: skipped user ID \"%s\"\n" -msgstr "chave %08lX: ignorado ID de utilizador '" +msgstr "chave %s: ID de utilizador \"%s\" ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: skipped subkey\n" -msgstr "chave %08lX: subchave ignorada\n" +msgstr "chave %s: subchave ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: non exportable signature (class 0x%02X) - skipped\n" -msgstr "chave %08lX: assinatura não exportável (classe %02x) - ignorada\n" +msgstr "chave %s: assinatura não exportável (classe 0x%02X) - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: revocation certificate at wrong place - skipped\n" -msgstr "chave %08lX: certificado de revogação no local errado - ignorado\n" +msgstr "chave %s: certificado de revogação no local errado - ignorado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid revocation certificate: %s - skipped\n" -msgstr "chave %08lX: certificado de revogação inválido: %s - ignorado\n" +msgstr "Chave %s: certificado de revogação inválido: %s - ignorado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: subkey signature in wrong place - skipped\n" -msgstr "chave %08lX: assintura da subchave no local errado - ignorado\n" +msgstr "Tecla %s: assinatura de subchave no lugar errado - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: unexpected signature class (0x%02X) - skipped\n" -msgstr "chave %08lX: classe de assinatura inesperada (%02x) - ignorada\n" +msgstr "chave %s: classe de assinatura inesperada (0x%02X) - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: duplicated user ID detected - merged\n" -msgstr "chave %08lX: detectado ID de utilizador duplicado - fundido\n" +msgstr "chave %s: detetada ID de utilizador duplicada - fundida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: duplicated subkeys detected - merged\n" -msgstr "chave %08lX: detectado ID de utilizador duplicado - fundido\n" +msgstr "chave %s: detetadas subchaves duplicadas - fundidas\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: key %s may be revoked: fetching revocation key %s\n" msgstr "" -"AVISO: a chave %08lX pode estar revocada: a transferir a chave de revocação " -"%08lX\n" +"AVISO: a chave %s pode ser revogada: buscando a chave de revogação %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: key %s may be revoked: revocation key %s not present.\n" msgstr "" -"AVISO: a chave %08lX pode estar revocada: chave de revocação %08lX não " +"AVISO: a chave %s pode ser revogada: a chave de revogação %s não está " "presente.\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" revocation certificate added\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "chave %s: certificado de revogação \"%s\" adicionado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: direct key signature added\n" -msgstr "chave %08lX: assinatura directa de chave adicionada\n" +msgstr "chave %s: assinatura de chave direta adicionada\n" -#, fuzzy, c-format +#, c-format msgid "error allocating memory: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao alocar memória: %s\n" -#, fuzzy, c-format +#, c-format msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n" -msgstr "chave %08lX: algoritmo de chave pública não suportado\n" +msgstr "" +"não é possível verificar a assinatura com algoritmo de chave pública " +"insuportado (%d): %s.\n" -#, fuzzy, c-format +#, c-format msgid "" "can't check signature with unsupported message-digest algorithm %d: %s.\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "" +"não é possível verificar a assinatura com o algoritmo de digest de mensagens " +"insuportado %d: %s.\n" -#, fuzzy msgid " (reordered signatures follow)" -msgstr "Assinatura correcta de \"" +msgstr " (seguem-se as assinaturas reordenadas)" -#, fuzzy, c-format +#, c-format msgid "key %s:\n" -msgstr "ignorado `%s': %s\n" +msgstr "chave %s:\n" -#, fuzzy, c-format +#, c-format msgid "%d duplicate signature removed\n" msgid_plural "%d duplicate signatures removed\n" -msgstr[0] "Utilizador \"%s\" está revocado." -msgstr[1] "Utilizador \"%s\" está revocado." +msgstr[0] "%d assinatura duplicada removida\n" +msgstr[1] "%d assinaturas duplicadas removidas\n" -#, fuzzy, c-format -#| msgid "1 signature not checked due to a missing key\n" +#, c-format msgid "%d signature not checked due to a missing key\n" msgid_plural "%d signatures not checked due to missing keys\n" -msgstr[0] "1 assinatura não verificada por falta de chave\n" -msgstr[1] "1 assinatura não verificada por falta de chave\n" +msgstr[0] "%d assinatura não verificada devido a chave ausente\n" +msgstr[1] "%d assinaturas não verificadas devido a chaves ausentes\n" -#, fuzzy, c-format -#| msgid "%d bad signatures\n" +#, c-format msgid "%d bad signature\n" msgid_plural "%d bad signatures\n" -msgstr[0] "%d assinaturas incorrectas\n" -msgstr[1] "%d assinaturas incorrectas\n" +msgstr[0] "%d assinatura inválida\n" +msgstr[1] "%d assinaturas inválidas\n" -#, fuzzy, c-format +#, c-format msgid "%d signature reordered\n" msgid_plural "%d signatures reordered\n" -msgstr[0] "Assinatura correcta de \"" -msgstr[1] "Assinatura correcta de \"" +msgstr[0] "%d assinatura reordenada\n" +msgstr[1] "%d assinaturas reordenadas\n" #, c-format msgid "" "Warning: errors found and only checked self-signatures, run '%s' to check " "all signatures.\n" msgstr "" +"Aviso: erros encontrados e apenas auto-assinaturas verificadas, execute '%s' " +"para verificar todas as assinaturas.\n" -#, fuzzy, c-format +#, c-format msgid "error creating keybox '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao criar keybox '%s': %s\n" -#, fuzzy, c-format -#| msgid "error creating keyring `%s': %s\n" +#, c-format msgid "error creating keyring '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao criar porta-chaves '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "keybox '%s' created\n" -msgstr "porta-chaves `%s' criado\n" +msgstr "keybox '%s' criada\n" -#, fuzzy, c-format -#| msgid "keyring `%s' created\n" +#, c-format msgid "keyring '%s' created\n" -msgstr "porta-chaves `%s' criado\n" +msgstr "porta-chaves '%s' criado\n" -#, fuzzy, c-format +#, c-format msgid "keyblock resource '%s': %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "recurso keyblock '%s': %s\n" #, c-format msgid "failed to rebuild keyring cache: %s\n" -msgstr "falha ao criar 'cache' do porta-chaves: %s\n" +msgstr "falha ao criar a cache do porta-chaves: %s\n" msgid "[revocation]" msgstr "[revogação]" @@ -3343,87 +3220,89 @@ msgstr "[revogação]" msgid "[self-signature]" msgstr "[auto-assinatura]" -#, fuzzy msgid "" "Please decide how far you trust this user to correctly verify other users' " "keys\n" "(by looking at passports, checking fingerprints from different sources, " "etc.)\n" msgstr "" -"Por favor decida quanto confia neste utilizador para\n" -"verificar correctamente as chaves de outros utilizadores\n" -"(vendo passaportes, verificando impressões digitais...)?\n" -"\n" +"Decida até onde você confia neste utilizador para verificar\n" +"corretamente as chaves dos outros utilizadores\n" +"(olhando para passaportes, verificando impressões digitais de\n" +"diferentes fontes, etc.)\n" -#, fuzzy, c-format +#, c-format msgid " %d = I trust marginally\n" -msgstr " %d = Confio moderadamente\n" +msgstr " %d = Confio marginalmente\n" -#, fuzzy, c-format +#, c-format msgid " %d = I trust fully\n" -msgstr " %d = Confio plenamente\n" +msgstr " %d = Confio completamente\n" msgid "" "Please enter the depth of this trust signature.\n" "A depth greater than 1 allows the key you are signing to make\n" "trust signatures on your behalf.\n" msgstr "" +"Introduza a profundidade desta assinatura da confiança. Uma\n" +"profundidade maior que 1 permite que a chave que você está a assinar\n" +"faça assinaturas da confiança em seu nome.\n" msgid "Please enter a domain to restrict this signature, or enter for none.\n" msgstr "" +"Introduza um domínio para restringir essa assinatura, ou introduzir nada " +"para nenhum.\n" #, c-format msgid "Skipping user ID \"%s\", which is not a text ID.\n" -msgstr "" +msgstr "Ignorando a ID de utilizador \"%s\", que não é uma ID de texto.\n" #, c-format msgid "User ID \"%s\" is revoked." -msgstr "Utilizador \"%s\" está revocado." +msgstr "ID de utilizador \"%s\" está revogada." msgid "Are you sure you still want to sign it? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem certeza de que ainda deseja assiná-la? (s/N) " msgid " Unable to sign.\n" -msgstr " Não foi possível assinar.\n" +msgstr " Não é possível assinar.\n" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\" is expired." -msgstr "Utilizador \"%s\" está revocado." +msgstr "A ID de utilizador \"%s\" expirou." -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\" is not self-signed." -msgstr "AVISO: o ID do utilizador \"%s\" não é auto-assinado.\n" +msgstr "A ID de utilizador \"%s\" não é auto-assinada." -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\" is signable. " -msgstr "AVISO: o ID do utilizador \"%s\" não é auto-assinado.\n" +msgstr "A ID de utilizador \"%s\" é assinável. " -#, fuzzy msgid "Sign it? (y/N) " -msgstr "Realmente assinar? " +msgstr "Assiná-la? (s/N) " #, c-format msgid "" "The self-signature on \"%s\"\n" "is a PGP 2.x-style signature.\n" msgstr "" -"A sua auto-assinatura em \"%s\"\n" +"A auto-assinatura em \"%s\"\n" "é uma assinatura do tipo PGP 2.x.\n" msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) " msgstr "Quer promovê-la a uma auto-assinatura OpenPGP? (s/N) " -#, fuzzy, c-format +#, c-format msgid "" "Your current signature on \"%s\"\n" "has expired.\n" msgstr "" -"A sua assinatura actual em \"%s\"\n" -"é uma assinatura local.\n" +"A sua assinatura atual em \"%s\"\n" +"expirou.\n" -#, fuzzy msgid "Do you want to issue a new signature to replace the expired one? (y/N) " -msgstr "Quer que a sua assinatura expire na mesma altura? (S/n) " +msgstr "Deseja emitir uma nova assinatura para substituir a expirada? (s/N) " #, c-format msgid "" @@ -3434,23 +3313,22 @@ msgstr "" "é uma assinatura local.\n" msgid "Do you want to promote it to a full exportable signature? (y/N) " -msgstr "Quer promovê-la a uma assinatura exportável? (s/N)" +msgstr "Quer promovê-la a uma assinatura exportável? (s/N) " -#, fuzzy, c-format +#, c-format msgid "\"%s\" was already locally signed by key %s\n" -msgstr "\"%s\" já foi assinado localmente pela chave %08lX\n" +msgstr "\"%s\" já estava assinado localmente pela chave %s\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" was already signed by key %s\n" -msgstr "\"%s\" já foi assinado pela chave %08lX\n" +msgstr "\"%s\" já estava assinado pela chave %s\n" -#, fuzzy msgid "Do you want to sign it again anyway? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Mesmo assim, quer voltar a assinar de novo? (s/N) " -#, fuzzy, c-format +#, c-format msgid "Nothing to sign with key %s\n" -msgstr "Nada para assinar com a chave %08lX\n" +msgstr "Nada a assinar com a chave %s\n" msgid "This key has expired!" msgstr "Esta chave expirou!" @@ -3467,13 +3345,13 @@ msgid "" "belongs\n" "to the person named above? If you don't know what to answer, enter \"0\".\n" msgstr "" -"Com que cuidado é que verificou que chave que está prestes a assinar " -"pertence\n" -"à pessoa correcta? Se não sabe o que responder, escolha \"0\".\n" +"Com que cuidado é que verificou que chave que está prestes a assinar\n" +"pertence à pessoa correta? Se não souber o que responder, introduzir\n" +"\"0\".\n" #, c-format msgid " (0) I will not answer.%s\n" -msgstr " (0) Não vou responder.%s\n" +msgstr " (0) Não irei responder.%s\n" #, c-format msgid " (1) I have not checked at all.%s\n" @@ -3487,240 +3365,198 @@ msgstr " (2) Verifiquei por alto.%s\n" msgid " (3) I have done very careful checking.%s\n" msgstr " (3) Verifiquei com bastante cuidado.%s\n" -#, fuzzy msgid "Your selection? (enter '?' for more information): " -msgstr " i = mostrar mais informações\n" +msgstr "A sua seleção? (introduzir '?' para mais informações): " -#, fuzzy, c-format +#, c-format msgid "" "Are you sure that you want to sign this key with your\n" "key \"%s\" (%s)\n" msgstr "" -"Você tem certeza de que quer assinar esta chave com\n" -"a sua chave: \"" +"Tem certeza de que deseja assinar esta chave com a sua\n" +"chave \"%s\" (%s)\n" -#, fuzzy msgid "This will be a self-signature.\n" -msgstr "" -"\n" -"Isto será uma auto-assinatura.\n" +msgstr "Isto será uma auto-assinatura.\n" -#, fuzzy msgid "WARNING: the signature will not be marked as non-exportable.\n" -msgstr "" -"\n" -"AVISO: a assinatura não será marcada como não-exportável.\n" +msgstr "AVISO: a assinatura não será marcada como não-exportável.\n" -#, fuzzy msgid "WARNING: the signature will not be marked as non-revocable.\n" -msgstr "" -"\n" -"AVISO: a assinatura não será marcada como não-revocável.\n" +msgstr "AVISO: a assinatura não será marcada como não-revogável.\n" -#, fuzzy msgid "The signature will be marked as non-exportable.\n" -msgstr "" -"\n" -"A assinatura será marcada como não-exportável.\n" +msgstr "A assinatura será marcada como não-exportável.\n" -#, fuzzy msgid "The signature will be marked as non-revocable.\n" -msgstr "" -"\n" -"A assinatura será marcada como não-revocável.\n" +msgstr "A assinatura será marcada como não-revogável.\n" -#, fuzzy msgid "I have not checked this key at all.\n" -msgstr "" -"\n" -"Não verifiquei esta chave.\n" +msgstr "Eu não cheguei a verificar esta chave.\n" -#, fuzzy msgid "I have checked this key casually.\n" -msgstr "" -"\n" -"Verifiquei por alto esta chave.\n" +msgstr "Eu verifiquei esta chave por alto.\n" -#, fuzzy msgid "I have checked this key very carefully.\n" -msgstr "" -"\n" -"Verifiquei esta chave com muito cuidado.\n" +msgstr "Eu verifiquei esta chave com muito cuidado.\n" -#, fuzzy msgid "Really sign? (y/N) " -msgstr "Realmente assinar? " +msgstr "De certeza que deseja assinar? (s/N) " #, c-format msgid "signing failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "falha ao assinar: %s\n" msgid "Key has only stub or on-card key items - no passphrase to change.\n" msgstr "" +"A chave apenas tem os itens de chave stub ou dentro-do-cartão -\n" +"nenhuma frase-secreta para alterar.\n" -#, fuzzy, c-format -#| msgid "error creating passphrase: %s\n" +#, c-format msgid "key %s: error changing passphrase: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "chave %s: erro ao alterar a frase-secreta: %s\n" msgid "save and quit" msgstr "gravar e sair" -#, fuzzy msgid "show key fingerprint" -msgstr "mostra impressão digital" +msgstr "mostrar impressão digital da chave" -#, fuzzy msgid "show the keygrip" -msgstr "Notação de assinatura: " +msgstr "mostrar o keygrip" msgid "list key and user IDs" -msgstr "lista chave e identificadores de utilizadores" +msgstr "listar chave e IDs de utilizador" msgid "select user ID N" -msgstr "seleciona ID de utilizador N" +msgstr "selecionar ID de utilizador N" -#, fuzzy msgid "select subkey N" -msgstr "seleciona ID de utilizador N" +msgstr "selecionar subchave N" -#, fuzzy msgid "check signatures" -msgstr "revoga assinaturas" +msgstr "verificar assinaturas" msgid "sign selected user IDs [* see below for related commands]" msgstr "" +"assinar IDs de utilizador selecionadas [* veja abaixo os comandos " +"relacionados]" -#, fuzzy msgid "sign selected user IDs locally" -msgstr "assina a chave localmente" +msgstr "assinar localmente IDs de utilizador selecionadas" -#, fuzzy msgid "sign selected user IDs with a trust signature" -msgstr "Sugestão: Selecione os IDs de utilizador para assinar\n" +msgstr "assinar IDs de utilizador selecionadas com uma assinatura da confiança" msgid "sign selected user IDs with a non-revocable signature" msgstr "" +"assinar IDs de utilizador selecionadas com uma assinatura não-revogável" msgid "add a user ID" -msgstr "adiciona um novo ID de utilizador" +msgstr "adicionar uma ID de utilizador" msgid "add a photo ID" -msgstr "adiciona um identificador fotográfico" +msgstr "adicionar uma ID fotográfica" -#, fuzzy msgid "delete selected user IDs" -msgstr "remove ID de utilizador" +msgstr "apagar IDs de utilizador selecionadas" -#, fuzzy msgid "add a subkey" -msgstr "addkey" +msgstr "adicionar uma subchave" msgid "add a key to a smartcard" -msgstr "" +msgstr "adicionar uma chave a um smartcard" msgid "move a key to a smartcard" -msgstr "" +msgstr "mover uma chave para um smartcard" msgid "convert a key to TPM form using the local TPM" -msgstr "" +msgstr "converter uma chave para a forma TPM usando o TPM local" msgid "move a backup key to a smartcard" -msgstr "" +msgstr "mover uma chave de backup para um smartcard" -#, fuzzy msgid "delete selected subkeys" -msgstr "remove uma chave secundária" +msgstr "apagar subchaves selecionadas" msgid "add a revocation key" -msgstr "adiciona uma chave de revocação" +msgstr "adicionar uma chave de revogação" msgid "add an additional decryption subkey" -msgstr "" +msgstr "adicionar uma subchave adicional de decifração" -#, fuzzy msgid "delete signatures from the selected user IDs" -msgstr "" -"Realmente actualizar as preferências para os utilizadores seleccionados?" +msgstr "apagar assinaturas das IDs de utilizador selecionadas" -#, fuzzy msgid "change the expiration date for the key or selected subkeys" -msgstr "Você não pode modificar a data de validade de uma chave v3\n" +msgstr "alterar a data de expiração da chave ou das subchaves selecionadas" -#, fuzzy msgid "flag the selected user ID as primary" -msgstr "seleccionar o identificador do utilizador como primário" +msgstr "marcar a ID de utilizador selecionada como principal" msgid "list preferences (expert)" -msgstr "lista preferências (perito)" +msgstr "listar preferências (perito)" msgid "list preferences (verbose)" -msgstr "lista preferências (detalhadamente)" +msgstr "listar preferências (verboso)" -#, fuzzy msgid "set preference list for the selected user IDs" -msgstr "" -"Realmente actualizar as preferências para os utilizadores seleccionados?" +msgstr "definir lista de preferências para as IDs de utilizador selecionadas" -#, fuzzy msgid "set the preferred keyserver URL for the selected user IDs" -msgstr "não consegui processar a URI do servidor de chaves\n" - -#, fuzzy -msgid "set a notation for the selected user IDs" msgstr "" -"Realmente actualizar as preferências para os utilizadores seleccionados?" +"definir a URL preferencial do servidor de chaves para as IDs de utilizador " +"selecionadas" + +msgid "set a notation for the selected user IDs" +msgstr "definir uma notação para as IDs de utilizador selecionadas" msgid "change the passphrase" -msgstr "muda a frase secreta" +msgstr "alterar a frase-secreta" msgid "change the ownertrust" -msgstr "muda os valores de confiança" +msgstr "alterar o ownertrust" -#, fuzzy msgid "revoke signatures on the selected user IDs" -msgstr "Realmente revocar todos os IDs de utilizador seleccionados? " +msgstr "revogar assinaturas nas IDs de utilizador selecionadas" -#, fuzzy msgid "revoke selected user IDs" -msgstr "revocar um ID de utilizador" +msgstr "revogar IDs de utilizador selecionadas" -#, fuzzy msgid "revoke key or selected subkeys" -msgstr "revoga uma chave secundária" +msgstr "revogar chave ou subchaves selecionadas" -#, fuzzy msgid "enable key" -msgstr "activa uma chave" +msgstr "habilitar chave" -#, fuzzy msgid "disable key" -msgstr "desactiva uma chave" +msgstr "desabilitar chave" -#, fuzzy msgid "show selected photo IDs" -msgstr "mostrar identificador fotográfico" +msgstr "mostrar IDs fotográficas selecionadas" msgid "compact unusable user IDs and remove unusable signatures from key" msgstr "" +"compactar IDs de utilizador inutilizáveis e remover assinaturas " +"inutilizáveis da chave" msgid "compact unusable user IDs and remove all signatures from key" msgstr "" +"compactar IDs de utilizador inutilizáveis e remover todas as assinaturas da " +"chave" msgid "Secret key is available.\n" -msgstr "Chave secreta disponível.\n" +msgstr "Chave secreta está disponível.\n" -#, fuzzy -#| msgid "Secret key is available.\n" msgid "Secret subkeys are available.\n" -msgstr "Chave secreta disponível.\n" +msgstr "Subchaves secretas estão disponíveis.\n" msgid "" "Note: the local copy of the secret key will only be deleted with \"save\".\n" -msgstr "" +msgstr "Nota: a cópia local da chave secreta só será apagada com \"save\".\n" msgid "Need the secret key to do this.\n" -msgstr "A chave secreta é necessária para fazer isto.\n" +msgstr "É preciso a chave secreta para fazer isto.\n" msgid "" "* The 'sign' command may be prefixed with an 'l' for local signatures " @@ -3728,290 +3564,273 @@ msgid "" " a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures\n" " (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n" msgstr "" +"* O comando 'sign' pode ter como prefixo com um 'l' para assinaturas\n" +" locais (lsign), um 't' para assinaturas da confiança (tsign), um\n" +" 'nr' para assinaturas não-revogáveis (nrsign), ou qualquer\n" +" combinação destes (ltsign, tnrsign, etc.).\n" msgid "Key is revoked." msgstr "A chave está revogada." -#, fuzzy msgid "Really sign all text user IDs? (y/N) " -msgstr "Realmente assinar todos os IDs de utilizador? " +msgstr "" +"De certeza que deseja assinar todas as IDs de utilizador de texto? (s/N) " -#, fuzzy msgid "Really sign all user IDs? (y/N) " -msgstr "Realmente assinar todos os IDs de utilizador? " +msgstr "De certeza que deseja assinar todas as IDs de utilizador? (s/N) " msgid "Hint: Select the user IDs to sign\n" -msgstr "Sugestão: Selecione os IDs de utilizador para assinar\n" +msgstr "Dica: Selecione as IDs de utilizador para assinar\n" -#, fuzzy, c-format +#, c-format msgid "Unknown signature type '%s'\n" -msgstr "classe de assinatura desconhecida" +msgstr "Tipo de assinatura desconhecido '%s'\n" msgid "You must select at least one user ID.\n" -msgstr "Você precisa selecionar pelo menos um ID de utilizador.\n" +msgstr "Você precisa selecionar pelo menos uma ID de utilizador.\n" #, c-format msgid "(Use the '%s' command.)\n" -msgstr "" +msgstr "(Usar o comando '%s'.)\n" msgid "You can't delete the last user ID!\n" -msgstr "Você não pode remover o último ID de utilizador!\n" +msgstr "Você não pode apagar a última ID de utilizador!\n" -#, fuzzy msgid "Really remove all selected user IDs? (y/N) " -msgstr "Realmente remover todos os IDs de utilizador seleccionados? " +msgstr "" +"De certeza que deseja remover todas as IDs de utilizador selecionadas? (s/N) " -#, fuzzy msgid "Really remove this user ID? (y/N) " -msgstr "Realmente remover este ID de utilizador? " +msgstr "De certeza que deseja remover esta ID de utilizador? (s/N) " #. TRANSLATORS: Please take care: This is about #. moving the key and not about removing it. -#, fuzzy msgid "Really move the primary key? (y/N) " -msgstr "Realmente remover este ID de utilizador? " +msgstr "De certeza que deseja mover a chave principal? (s/N) " -#, fuzzy msgid "You must select exactly one key.\n" -msgstr "Você deve selecionar pelo menos uma chave.\n" +msgstr "Você deve selecionar exatamente uma chave.\n" msgid "Command expects a filename argument\n" -msgstr "" +msgstr "Comando espera como argumento um nome de ficheiro\n" -#, fuzzy, c-format +#, c-format msgid "Can't open '%s': %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "Não é possível abrir '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "Error reading backup key from '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "Erro ao ler a chave de backup a partir de '%s': %s\n" msgid "You must select at least one key.\n" msgstr "Você deve selecionar pelo menos uma chave.\n" -#, fuzzy msgid "Do you really want to delete the selected keys? (y/N) " -msgstr "Você quer realmente remover as chaves selecionadas? " +msgstr "De certeza que você deseja apagar as chaves selecionadas? (s/N) " -#, fuzzy msgid "Do you really want to delete this key? (y/N) " -msgstr "Você quer realmente remover esta chave? " +msgstr "De certeza que você deseja apagar esta chave? (s/N) " -#, fuzzy msgid "Really revoke all selected user IDs? (y/N) " -msgstr "Realmente revocar todos os IDs de utilizador seleccionados? " +msgstr "" +"De certeza que deseja revogar todas as IDs de utilizador selecionadas? (s/N) " -#, fuzzy msgid "Really revoke this user ID? (y/N) " -msgstr "Realmente revocar este ID de utilizador? " +msgstr "De certeza que deseja revogar esta ID de utilizador? (s/N) " -#, fuzzy msgid "Do you really want to revoke the entire key? (y/N) " -msgstr "Você quer realmente revogar esta chave? " +msgstr "De certeza que você deseja revogar a chave inteira? (s/N) " -#, fuzzy msgid "Do you really want to revoke the selected subkeys? (y/N) " -msgstr "Você quer realmente revogar as chaves selecionadas? " +msgstr "De certeza que você deseja revogar as subchaves selecionadas? (s/N) " -#, fuzzy msgid "Do you really want to revoke this subkey? (y/N) " -msgstr "Você quer realmente revogar esta chave? " +msgstr "De certeza que você deseja revogar esta subchave? (s/N) " msgid "Owner trust may not be set while using a user provided trust database\n" msgstr "" +"Owner trust não pode ser definida ao usar uma base de dados da\n" +"confiança fornecido pelo utilizador\n" -#, fuzzy msgid "Set preference list to:\n" -msgstr "configurar lista de preferências" +msgstr "Defina a lista de preferências para:\n" -#, fuzzy msgid "Really update the preferences for the selected user IDs? (y/N) " msgstr "" -"Realmente actualizar as preferências para os utilizadores seleccionados?" +"De certeza que deseja atualizar as preferências para as IDs de utilizador " +"selecionadas? (s/N) " -#, fuzzy msgid "Really update the preferences? (y/N) " -msgstr "Realmente actualizar as preferências?" +msgstr "De certeza que deseja atualizar as preferências? (s/N) " -#, fuzzy msgid "Save changes? (y/N) " -msgstr "Gravar alterações? " +msgstr "Gravar alterações? (s/N) " -#, fuzzy msgid "Quit without saving? (y/N) " -msgstr "Sair sem gravar? " +msgstr "Sair sem gravar? (s/N) " -#, fuzzy, c-format +#, c-format msgid "deleting copy of secret key failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao apagar cópia da chave secreta: %s\n" #, c-format msgid "Key not changed so no update needed.\n" -msgstr "Chave não alterada, nenhuma actualização é necessária.\n" +msgstr "Chave não alterada, por isso, é necessária nenhuma atualização.\n" -#, fuzzy, c-format -#| msgid "You can't delete the last user ID!\n" +#, c-format msgid "cannot revoke the last valid user ID.\n" -msgstr "Você não pode remover o último ID de utilizador!\n" +msgstr "não é possível revogar a última ID de utilizador válida.\n" -#, fuzzy, c-format +#, c-format msgid "revoking the user ID failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao revogar a ID de utilizador: %s\n" -#, fuzzy, c-format +#, c-format msgid "setting the primary user ID failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao definir a ID de utilizador principal: %s\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" is not a fingerprint\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "\"%s\" não é uma impressão digital\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" is not the primary fingerprint\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "\"%s\" não é a impressão digital principal\n" -#, fuzzy, c-format -#| msgid "invalid value\n" +#, c-format msgid "Invalid user ID '%s': %s\n" -msgstr "valor inválido\n" +msgstr "ID de utilizador '%s' inválida: %s\n" -#, fuzzy -#| msgid "No such user ID.\n" msgid "No matching user IDs." -msgstr "Identificador de utilizador inexistente.\n" +msgstr "Não há IDs de utilizador correspondentes." -#, fuzzy msgid "Nothing to sign.\n" -msgstr "Nada para assinar com a chave %08lX\n" +msgstr "Nada a assinar.\n" -#, fuzzy, c-format +#, c-format msgid "Not signed by you.\n" -msgstr " assinado por %08lX em %s%s\n" +msgstr "Não assinado por você.\n" -#, fuzzy, c-format -#| msgid "checking created signature failed: %s\n" +#, c-format msgid "revoking the key signature failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao revogar a assinatura da chave: %s\n" -#, fuzzy, c-format +#, c-format msgid "'%s' is not a valid expiration time\n" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "'%s' não é um tempo de expiração válido\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" is not a proper fingerprint\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "\"%s\" não é propriamente uma impressão digital\n" -#, fuzzy, c-format +#, c-format msgid "subkey \"%s\" not found\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "subchave \"%s\" não encontrada\n" msgid "Preferred keyserver: " -msgstr "" +msgstr "Servidor de chaves preferido: " -#, fuzzy msgid "Notations: " -msgstr "Notação: " +msgstr "Notações: " msgid "There are no preferences on a PGP 2.x-style user ID.\n" -msgstr "Não há preferências no ID de utilizador tipo PGP 2.x.\n" +msgstr "Não há preferências numa ID de utilizador tipo PGP 2.x.\n" -#, fuzzy, c-format +#, c-format msgid "The following key was revoked on %s by %s key %s\n" -msgstr "Esta chave pode ser revogada pela chave %s " +msgstr "A chave seguinte foi revogada em %s pela chave %s de %s\n" -#, fuzzy, c-format +#, c-format msgid "This key may be revoked by %s key %s" -msgstr "Esta chave pode ser revogada pela chave %s " +msgstr "Esta chave pode ser revogada pela chave %s de %s" -#, fuzzy msgid "(sensitive)" -msgstr " (sensível)" +msgstr "(sensitivo)" -#, fuzzy, c-format +#, c-format msgid "created: %s" -msgstr "impossível criar %s: %s\n" +msgstr "criada: %s" -#, fuzzy, c-format +#, c-format msgid "revoked: %s" -msgstr "revkey" +msgstr "revogada: %s" -#, fuzzy, c-format +#, c-format msgid "expired: %s" -msgstr "[expira: %s]" +msgstr "expirada: %s" -#, fuzzy, c-format +#, c-format msgid "expires: %s" -msgstr "[expira: %s]" +msgstr "expira: %s" -#, fuzzy, c-format +#, c-format msgid "usage: %s" -msgstr " confiança: %c/%c" +msgstr "uso: %s" msgid "card-no: " -msgstr "" +msgstr "nº do cartão: " -#, fuzzy, c-format +#, c-format msgid "trust: %s" -msgstr " confiança: %c/%c" +msgstr "confiança: %s" #, c-format msgid "validity: %s" -msgstr "" +msgstr "validade: %s" msgid "This key has been disabled" -msgstr "Esta chave foi desactivada" +msgstr "Esta chave foi desabilitada" msgid "" "Please note that the shown key validity is not necessarily correct\n" "unless you restart the program.\n" msgstr "" -"Não se esqueça que a validade de chave mostrada não é necessáriamente a\n" -"correcta a não ser que reinicie o programa.\n" +"Note que a validade da chave mostrada não é necessariamente a\n" +"correta a menos que reinicie o programa.\n" -#, fuzzy msgid "revoked" -msgstr "revkey" +msgstr "revogada" -#, fuzzy msgid "expired" -msgstr "expire" +msgstr "expirada" #, c-format msgid "" "WARNING: no user ID has been marked as primary. This command may\n" " cause a different user ID to become the assumed primary.\n" msgstr "" +"AVISO: nenhuma ID de utilizador foi marcada como principal. Este\n" +" comando pode fazer com que uma ID de utilizador diferente\n" +" se torne como a presumida principal.\n" #, c-format msgid "WARNING: Your encryption subkey expires soon.\n" -msgstr "" +msgstr "AVISO: Sua subchave de cifração expira em breve.\n" -#, fuzzy, c-format -#| msgid "You can't change the expiration date of a v3 key\n" +#, c-format msgid "You may want to change its expiration date too.\n" -msgstr "Você não pode modificar a data de validade de uma chave v3\n" +msgstr "Você pode também querer alterar sua data de expiração.\n" #, c-format msgid "WARNING: No valid encryption subkey left over.\n" -msgstr "" +msgstr "AVISO: Sobrou nenhuma subchave de cifração válida.\n" msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" " of PGP to reject this key.\n" msgstr "" -"AVISO: Esta chave é do tipo PGP2. Se adicionar um identificador fotográfico\n" -" algumas versão do PGP podem rejeitá-la.\n" +"AVISO: Esta chave é do tipo PGP2. Se adicionar uma ID fotográfica\n" +" algumas versão do PGP podem rejeitar a chave.\n" msgid "Are you sure you still want to add it? (y/N) " -msgstr "Tem a certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem a certeza de que ainda deseja adicioná-la? (s/N) " msgid "You may not add a photo ID to a PGP2-style key.\n" -msgstr "" -"Não pode adicionar um identificador fotográfico a uma chave tipo PGP2.\n" +msgstr "Não pode adicionar uma ID fotográfica a uma chave tipo PGP2.\n" msgid "Such a user ID already exists on this key!" -msgstr "" +msgstr "Esse ID de utilizador já existe nesta chave!" msgid "Delete this good signature? (y/N/q)" msgstr "Apagar esta assinatura válida? (s/N/q)" @@ -4023,201 +3842,195 @@ msgid "Delete this unknown signature? (y/N/q)" msgstr "Apagar esta assinatura desconhecida? (s/N/q)" msgid "Really delete this self-signature? (y/N)" -msgstr "Realmente remover esta auto-assinatura? (s/N)" +msgstr "De certeza que deseja apagar esta auto-assinatura? (s/N)" -#, fuzzy, c-format -#| msgid "Deleted %d signature.\n" +#, c-format msgid "Deleted %d signature.\n" msgid_plural "Deleted %d signatures.\n" -msgstr[0] "%d assinatura removida.\n" -msgstr[1] "%d assinatura removida.\n" +msgstr[0] "%d assinatura apagada.\n" +msgstr[1] "%d assinaturas apagadas.\n" msgid "Nothing deleted.\n" -msgstr "Nada removido.\n" +msgstr "Nada apagada.\n" -#, fuzzy msgid "invalid" -msgstr "armadura inválida" +msgstr "inválida" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\" compacted: %s\n" -msgstr "Utilizador \"%s\" está revocado." +msgstr "ID de utilizador \"%s\" compactada: %s\n" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\": %d signature removed\n" msgid_plural "User ID \"%s\": %d signatures removed\n" -msgstr[0] "Utilizador \"%s\" está revocado." -msgstr[1] "Utilizador \"%s\" está revocado." +msgstr[0] "ID do utilizador \"%s\": %d assinatura removida\n" +msgstr[1] "ID do utilizador \"%s\": %d assinaturas removidas\n" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\": already minimized\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "ID de utilizador \"%s\": já estava minimizada\n" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\": already clean\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "ID de utilizador \"%s\": já estava limpa\n" msgid "" "WARNING: This is a PGP 2.x-style key. Adding a designated revoker may " "cause\n" " some versions of PGP to reject this key.\n" msgstr "" -"AVISO: Esta chave é do tipo PGP 2.x. Se adicionar um revogador designado\n" -" algumas versão do PGP podem rejeitá-la.\n" +"AVISO: Esta chave é do tipo PGP 2.x. Se adicionar uma revogadora designada\n" +" algumas versão do PGP podem rejeitar esta chave.\n" msgid "You may not add a designated revoker to a PGP 2.x-style key.\n" -msgstr "Não pode adicionar um revogador designado a uma chave tipo PGP 2.x.\n" +msgstr "" +"Não pode adicionar uma revogadora designada a uma chave tipo PGP 2.x.\n" msgid "Enter the user ID of the designated revoker: " -msgstr "Insira o ID de utilizador do revogador escolhido: " +msgstr "Introduzir a ID de utilizador da revogadora designada: " #, c-format msgid "cannot appoint a PGP 2.x style key as a designated revoker\n" -msgstr "não pode escolher uma chave do tipo PGP 2.x como revogadora\n" +msgstr "não pode nomear uma chave do tipo PGP 2.x como revogadora designada\n" #, c-format msgid "you cannot appoint a key as its own designated revoker\n" -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "não pode nomear uma chave como revogadora designada de si própria\n" -#, fuzzy, c-format +#, c-format msgid "this key has already been designated as a revoker\n" -msgstr "AVISO: Esta chave foi revogada pelo seu dono!\n" +msgstr "esta chave já foi designada como revogadora\n" -#, fuzzy msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n" -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "" +"ATENÇÃO: a nomeação de uma chave como revogadora designada não pode ser " +"desfeita!\n" -#, fuzzy msgid "" "Are you sure you want to appoint this key as a designated revoker? (y/N) " -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "" +"Tem certeza de que deseja nomear esta chave como uma revogadora designada? " +"(s/N) " msgid "Enter the fingerprint of the additional decryption subkey: " -msgstr "" +msgstr "Introduzir a impressão digital da subchave de decifração adicional: " -#, fuzzy, c-format -#| msgid "(unless you specify the key by fingerprint)\n" +#, c-format msgid "Did you specify the fingerprint of a subkey?\n" -msgstr "(a não ser que escolha a chave pela sua impressão digital)\n" +msgstr "Especificou a impressão digital de uma subchave?\n" -#, fuzzy, c-format +#, c-format msgid "key \"%s\" is already on this keyblock\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "A chave \"%s\" já está neste keyblock\n" -#, fuzzy msgid "" "Are you sure you want to change the expiration time for multiple subkeys? (y/" "N) " -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "" +"Tem certeza de que deseja alterar o tempo de expiração de várias subchaves? " +"(s/N) " -#, fuzzy msgid "Changing expiration time for a subkey.\n" -msgstr "A modificar a data de validade para uma chave secundária.\n" +msgstr "Alterando o tempo de expiração de uma subchave.\n" msgid "Changing expiration time for the primary key.\n" -msgstr "Modificar a data de validade para uma chave primária.\n" +msgstr "Modificando a data de expiração para a chave principal.\n" #, c-format msgid "You can't change the expiration date of a v3 key\n" -msgstr "Você não pode modificar a data de validade de uma chave v3\n" +msgstr "Você não pode modificar a data de expiração de uma chave v3\n" -#, fuzzy msgid "Changing usage of a subkey.\n" -msgstr "A modificar a data de validade para uma chave secundária.\n" +msgstr "Alterando a utilização de uma subchave.\n" -#, fuzzy -#| msgid "Changing expiration time for the primary key.\n" msgid "Changing usage of the primary key.\n" -msgstr "Modificar a data de validade para uma chave primária.\n" +msgstr "Alterando a utilização da chave principal.\n" -#, fuzzy, c-format +#, c-format msgid "signing subkey %s is already cross-certified\n" -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "a subchave de assinatura %s já é cruzadamente certificada\n" #, c-format msgid "subkey %s does not sign and so does not need to be cross-certified\n" msgstr "" +"a subchave %s não assina e, por isso, não precisa ser cruzadamente " +"certificada\n" msgid "Please select exactly one user ID.\n" -msgstr "Seleccione exactamente um identificador de utilizador.\n" +msgstr "Selecione exatamente uma ID de utilizador.\n" -#, fuzzy, c-format +#, c-format msgid "skipping v3 self-signature on user ID \"%s\"\n" -msgstr "a ignorar auto-assinatura v3 no utilizar com o id \"%s\"\n" +msgstr "ignorando a auto-assinatura v3 na ID de utilizador \"%s\"\n" msgid "Enter your preferred keyserver URL: " -msgstr "" +msgstr "Introduzir a URL do servidor de chaves preferido: " -#, fuzzy msgid "Are you sure you want to replace it? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem certeza de que deseja substituí-la? (s/N) " -#, fuzzy msgid "Are you sure you want to delete it? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem certeza de que deseja apagá-la? (s/N) " -#, fuzzy msgid "Enter the notation: " -msgstr "Notação de assinatura: " +msgstr "Introduzir a notação: " -#, fuzzy msgid "Proceed? (y/N) " -msgstr "Escrever por cima (s/N)? " +msgstr "Prosseguir? (s/N) " #, c-format msgid "No user ID with index %d\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma ID de utilizador com índice %d\n" -#, fuzzy, c-format +#, c-format msgid "No user ID with hash %s\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma ID de utilizador com hash %s\n" -#, fuzzy, c-format +#, c-format msgid "No subkey with key ID '%s'.\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma subchave com ID de chave '%s'.\n" -#, fuzzy, c-format +#, c-format msgid "No subkey with index %d\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma subchave com índice %d\n" -#, fuzzy, c-format +#, c-format msgid "user ID: \"%s\"\n" -msgstr "ID de utilizador: \"" +msgstr "ID de utilizador: \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "signed by your key %s on %s%s%s\n" -msgstr " assinado por %08lX em %s%s%s\n" +msgstr "assinado pela sua chave %s em %s%s%s\n" msgid " (non-exportable)" -msgstr " (não-exportável)" +msgstr " (não-exportável)" #, c-format msgid "This signature expired on %s.\n" msgstr "Esta assinatura expirou em %s.\n" msgid "Are you sure you still want to revoke it? (y/N) " -msgstr "Tem a certeza de que quer revogá-la de qualquer forma? (s/N) " +msgstr "Tem a certeza de que ainda deseja revogá-la? (s/N) " msgid "Create a revocation certificate for this signature? (y/N) " -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Criar um certificado de revogação para esta assinatura? (s/N) " -#, fuzzy, c-format +#, c-format msgid "You have signed these user IDs on key %s:\n" -msgstr "Assinou estes identificadores de utilizadores:\n" +msgstr "Você assinou estas IDs de utilizador na chave %s:\n" -#, fuzzy msgid " (non-revocable)" -msgstr " (não-exportável)" +msgstr " (não-revogável)" -#, fuzzy, c-format +#, c-format msgid "revoked by your key %s on %s\n" -msgstr " revogado por %08lX em %s\n" +msgstr "revogado pela sua chave %s em %s\n" msgid "You are about to revoke these signatures:\n" msgstr "Está prestes a revogar estas assinaturas:\n" msgid "Really create the revocation certificates? (y/N) " -msgstr "Realmente criar os certificados de revogação? (s/N) " +msgstr "De certeza que deseja criar os certificados de revogação? (s/N) " #, c-format msgid "no secret key\n" @@ -4225,78 +4038,75 @@ msgstr "nenhuma chave secreta\n" #, c-format msgid "tried to revoke a non-user ID: %s\n" -msgstr "" +msgstr "tentou revogar uma ID sem-utilizador: %s\n" #, c-format msgid "user ID \"%s\" is already revoked\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "ID de utilizador \"%s\" já está revogada\n" #, c-format msgid "WARNING: a user ID signature is dated %d seconds in the future\n" -msgstr "" -"AVISO: a assintura do ID do utilizador tem data %d segundos no futuro\n" +msgstr "AVISO: a assinatura da ID do utilizador está a %d segundos no futuro\n" -#, fuzzy, c-format -#| msgid "You can't delete the last user ID!\n" +#, c-format msgid "Cannot revoke the last valid user ID.\n" -msgstr "Você não pode remover o último ID de utilizador!\n" +msgstr "Não é possível revogar a última ID de utilizador válida.\n" -#, fuzzy, c-format +#, c-format msgid "Key %s is already revoked.\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "A chave %s já está revogada.\n" -#, fuzzy, c-format +#, c-format msgid "Subkey %s is already revoked.\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "A subchave %s já está revogada.\n" -#, fuzzy, c-format +#, c-format msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n" -msgstr "" -"A mostrar a fotografia %s com o tamanho %ld da chave 0x%08lX (uid %d)\n" +msgstr "Exibindo ID fotográfica %s de tamanho %ld para a chave %s (uid %d)\n" -#, fuzzy, c-format +#, c-format msgid "invalid value for option '%s'\n" -msgstr "opções de importação inválidas\n" +msgstr "valor inválido para a opção '%s'\n" -#, fuzzy, c-format +#, c-format msgid "preference '%s' duplicated\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "preferência '%s' duplicada\n" -#, fuzzy, c-format +#, c-format msgid "too many cipher preferences\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiadas preferências da cifra\n" -#, fuzzy, c-format +#, c-format msgid "too many digest preferences\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiadas preferências de digest\n" -#, fuzzy, c-format +#, c-format msgid "too many compression preferences\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiadas preferências de compressão\n" -#, fuzzy, c-format +#, c-format msgid "too many AEAD preferences\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiadas preferências AEAD\n" -#, fuzzy, c-format +#, c-format msgid "invalid item '%s' in preference string\n" -msgstr "caracter inválido na cadeia de caractéres da preferência\n" +msgstr "item inválido '%s' na string de preferência\n" #, c-format msgid "writing direct signature\n" -msgstr "a escrever a assinatura directa\n" +msgstr "escrevendo a assinatura direta\n" #, c-format msgid "writing self signature\n" -msgstr "a escrever a auto-assinatura\n" +msgstr "escrevendo a auto-assinatura\n" #, c-format msgid "writing key binding signature\n" -msgstr "a escrever a assinatura ligada a uma chave\n" +msgstr "escrevendo a assinatura ligada a uma chave\n" #, c-format msgid "keysize invalid; using %u bits\n" -msgstr "tamanho de chave inválido; a utilizar %u bits\n" +msgstr "tamanho de chave inválido; usando %u bits\n" #, c-format msgid "keysize rounded up to %u bits\n" @@ -4306,20 +4116,20 @@ msgstr "tamanho da chave arredondado para %u bits\n" msgid "" "WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n" msgstr "" +"AVISO: alguns programas OpenPGP não conseguem lidar com uma chave DSA deste " +"tamanho de digest\n" -#, fuzzy msgid "Sign" -msgstr "sign" +msgstr "Assinar" msgid "Certify" -msgstr "" +msgstr "Certificar" -#, fuzzy msgid "Encrypt" -msgstr "cifrar dados" +msgstr "Cifrar" msgid "Authenticate" -msgstr "" +msgstr "Autenticar" #. TRANSLATORS: Please use only plain ASCII characters for the #. * translation. If this is not possible use single digits. The @@ -4332,143 +4142,129 @@ msgstr "" #. * q = Finish #. msgid "SsEeAaQq" -msgstr "" +msgstr "SsEeAaTt" #, c-format msgid "Possible actions for this %s key: " -msgstr "" +msgstr "Ações possíveis para esta chave %s: " msgid "Current allowed actions: " -msgstr "" +msgstr "Ações permitidas atualmente: " #, c-format msgid " (%c) Toggle the sign capability\n" -msgstr "" +msgstr " (%c) Alternar o capacidade de assinar\n" -#, fuzzy, c-format +#, c-format msgid " (%c) Toggle the encrypt capability\n" -msgstr " (%d) ElGamal (apenas cifragem)\n" +msgstr " (%c) Alternar a capacidade de cifrar\n" #, c-format msgid " (%c) Toggle the authenticate capability\n" -msgstr "" +msgstr " (%c) Alternar a capacidade de autenticação\n" #, c-format msgid " (%c) Finished\n" -msgstr "" +msgstr " (%c) Terminado\n" -#, fuzzy, c-format +#, c-format msgid " (%d) RSA and RSA%s\n" -msgstr " (%d) DSA e ElGamal (por omissão)\n" +msgstr " (%d) RSA e RSA%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) DSA and Elgamal%s\n" -msgstr " (%d) DSA e ElGamal (por omissão)\n" +msgstr " (%d) DSA e Elgamal%s\n" -#, fuzzy, c-format -#| msgid " (%d) DSA (sign only)\n" +#, c-format msgid " (%d) DSA (sign only)%s\n" -msgstr " (%d) DSA (apenas assinatura)\n" +msgstr " (%d) DSA (apenas de assinar)%s\n" -#, fuzzy, c-format -#| msgid " (%d) RSA (sign only)\n" +#, c-format msgid " (%d) RSA (sign only)%s\n" -msgstr " (%d) RSA (apenas assinatura)\n" +msgstr " (%d) RSA (apenas de assinar)%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) Elgamal (encrypt only)%s\n" -msgstr " (%d) ElGamal (apenas cifragem)\n" +msgstr " (%d) Elgamal (apenas de cifrar)%s\n" -#, fuzzy, c-format -#| msgid " (%d) RSA (encrypt only)\n" +#, c-format msgid " (%d) RSA (encrypt only)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) RSA (apenas de cifrar)%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) DSA (set your own capabilities)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) DSA (defina as suas capacidades)%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) RSA (set your own capabilities)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) RSA (defina as suas capacidades)%s\n" -#, fuzzy, c-format -#| msgid " (%d) ElGamal (sign and encrypt)\n" +#, c-format msgid " (%d) ECC (sign and encrypt)%s\n" -msgstr " (%d) ElGamal (assinatura e cifragem)\n" +msgstr " (%d) ECC (de assinar e cifrar)%s\n" -#, fuzzy -#| msgid " (default)" msgid " *default*" -msgstr " (por omissão)" +msgstr " *pré-definição*" -#, fuzzy, c-format -#| msgid " (%d) DSA (sign only)\n" +#, c-format msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (apenas assinatura)\n" +msgstr " (%d) ECC (apenas de assinar)\n" -#, fuzzy, c-format +#, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) ECC (defina as suas capacidades)%s\n" -#, fuzzy, c-format -#| msgid " (%d) RSA (encrypt only)\n" +#, c-format msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) ECC (apenas de cifrar)%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) Chave existente%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) Chave do cartão existente%s\n" -#, fuzzy msgid "Enter the keygrip: " -msgstr "Notação de assinatura: " +msgstr "Introduzir o keygrip: " #, c-format msgid "Not a valid keygrip (expecting 40 hex digits)\n" -msgstr "" +msgstr "Não é um keygrip válido (à espera de 40 dígitos hex)\n" -#, fuzzy msgid "No key with this keygrip\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma chave com este keygrip\n" -#, fuzzy, c-format +#, c-format msgid "error reading the card: %s\n" -msgstr "%s: erro ao ler registo livre: %s\n" +msgstr "erro ao ler o cartão: %s\n" -#, fuzzy, c-format +#, c-format msgid "Serial number of the card: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "Número de série do cartão: %s\n" -#, fuzzy msgid "Available keys:\n" -msgstr "desactiva uma chave" +msgstr "Chaves disponíveis:\n" -#, fuzzy, c-format -#| msgid "rounded up to %u bits\n" +#, c-format msgid "rounded to %u bits\n" msgstr "arredondado para %u bits\n" #, c-format msgid "%s keys may be between %u and %u bits long.\n" -msgstr "" +msgstr "As chaves %s podem estar entre %u e %u bits de comprimento.\n" -#, fuzzy, c-format +#, c-format msgid "What keysize do you want for the subkey? (%u) " -msgstr "Qual o tamanho de chave desejado? (1024) " +msgstr "Qual o tamanho de chave que você deseja para a subchave? (%u) " #, c-format msgid "Requested keysize is %u bits\n" msgstr "O tamanho de chave pedido é %u bits\n" -#, fuzzy -#| msgid "Please select what kind of key you want:\n" msgid "Please select which elliptic curve you want:\n" -msgstr "Por favor selecione o tipo de chave desejado:\n" +msgstr "Selecione qual a curva elíptica que você deseja:\n" msgid "" "Please specify how long the key should be valid.\n" @@ -4478,7 +4274,7 @@ msgid "" " m = key expires in n months\n" " y = key expires in n years\n" msgstr "" -"Por favor especifique por quanto tempo a chave deve ser válida.\n" +"Especifique quando a chave expira.\n" " 0 = chave não expira\n" " = chave expira em n dias\n" " w = chave expira em n semanas\n" @@ -4493,7 +4289,7 @@ msgid "" " m = signature expires in n months\n" " y = signature expires in n years\n" msgstr "" -"Por favor especifique por quanto tempo a assinatura deve ser válida.\n" +"Especifique quando a assinatura expira.\n" " 0 = assinatura não expira\n" " = assinatura expira em n dias\n" " w = assinatura expira em n semanas\n" @@ -4501,53 +4297,52 @@ msgstr "" " y = assinatura expira em n anos\n" msgid "Key is valid for? (0) " -msgstr "A chave é valida por? (0) " +msgstr "Quando a chave expira? (0) " -#, fuzzy, c-format +#, c-format msgid "Signature is valid for? (%s) " -msgstr "A assinatura é valida por? (0) " +msgstr "Quando a assinatura expira? (%s) " msgid "invalid value\n" msgstr "valor inválido\n" -#, fuzzy msgid "Key does not expire at all\n" -msgstr "A %s não expira nunca\n" +msgstr "A chave não expira de forma alguma\n" -#, fuzzy msgid "Signature does not expire at all\n" -msgstr "A %s não expira nunca\n" +msgstr "A assinatura não expira de forma alguma\n" -#, fuzzy, c-format +#, c-format msgid "Key expires at %s\n" -msgstr "%s expira em %s\n" +msgstr "A chave expira em %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature expires at %s\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "A assinatura expira em %s\n" msgid "" "Your system can't display dates beyond 2038.\n" "However, it will be correctly handled up to 2106.\n" msgstr "" "O seu sistema não consegue mostrar datas para além de 2038.\n" -"No entanto, estas vão ser tratadas correctamente até 2106.\n" +"No entanto, será lidado corretamente até 2106.\n" -#, fuzzy msgid "Is this correct? (y/N) " -msgstr "Está correto (s/n)? " +msgstr "Isto está correto? (s/N) " msgid "" "\n" "GnuPG needs to construct a user ID to identify your key.\n" "\n" msgstr "" +"\n" +"O GnuPG precisa construir uma ID de utilizador para identificar sua chave.\n" +"\n" #. TRANSLATORS: This string is in general not anymore used #. but you should keep your existing translation. In case #. the new string is not translated this old string will #. be used. -#, fuzzy msgid "" "\n" "You need a user ID to identify your key; the software constructs the user " @@ -4557,39 +4352,37 @@ msgid "" "\n" msgstr "" "\n" -"Você precisa de um identificador de utilizador para identificar sua chave; " -"o\n" -"programa constrói o identificador a partir do Nome Completo, Comentário e\n" -"Endereço Eletrónico desta forma:\n" +"Você precisa de uma ID de utilizador para identificar sua chave; o\n" +"software constrói a ID de utilizador a partir de o Nome Verdadeiro, o\n" +"Comentário, e o Endereço de email com esta forma:\n" " \"Heinrich Heine (Der Dichter) \"\n" "\n" msgid "Real name: " -msgstr "Nome completo: " +msgstr "Nome verdadeiro: " msgid "Invalid character in name\n" -msgstr "Caracter inválido no nome\n" +msgstr "Caractere inválido no nome\n" #, c-format msgid "The characters '%s' and '%s' may not appear in name\n" -msgstr "" +msgstr "Os caracteres '%s' e '%s' não podem aparecer no nome\n" msgid "Email address: " -msgstr "Endereço de correio eletrónico: " +msgstr "Endereço de email: " msgid "Not a valid email address\n" -msgstr "Endereço eletrónico inválido\n" +msgstr "Endereço de email inválido\n" msgid "Comment: " msgstr "Comentário: " msgid "Invalid character in comment\n" -msgstr "Caracter inválido no comentário\n" +msgstr "Caractere inválido no comentário\n" -#, fuzzy, c-format -#| msgid "You are using the `%s' character set.\n" +#, c-format msgid "You are using the '%s' character set.\n" -msgstr "Você está usando o conjunto de caracteres `%s'.\n" +msgstr "Você está usando o set de caracteres '%s'.\n" #, c-format msgid "" @@ -4597,17 +4390,15 @@ msgid "" " \"%s\"\n" "\n" msgstr "" -"Você selecionou este identificador de utilizador:\n" +"Você selecionou este USER-ID:\n" " \"%s\"\n" "\n" msgid "Please don't put the email address into the real name or the comment\n" -msgstr "" -"Por favor não coloque o endereço de email no nome verdadeiro ou no " -"comentário\n" +msgstr "Não coloque o endereço de email no nome verdadeiro ou no comentário\n" msgid "Such a user ID already exists on this key!\n" -msgstr "" +msgstr "Tal ID de utilizador já existe nesta chave!\n" #. TRANSLATORS: These are the allowed answers in #. lower and uppercase. Below you will find the matching @@ -4624,23 +4415,19 @@ msgid "NnCcEeOoQq" msgstr "NnCcEeOoSs" msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? " -msgstr "Mudar (N)ome, (C)omentário, (E)mail ou (S)air? " +msgstr "Alterar (N)ome, (C)omentário, (E)mail, ou (S)air? " msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? " -msgstr "Mudar (N)ome, (C)omentário, (E)ndereço ou (O)k/(S)air? " +msgstr "Alterar (N)ome, (C)omentário, (E)ndereço, ou (O)k/(S)air? " -#, fuzzy -#| msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? " msgid "Change (N)ame, (E)mail, or (Q)uit? " -msgstr "Mudar (N)ome, (C)omentário, (E)mail ou (S)air? " +msgstr "Alterar (N)ome, (E)mail, ou (S)air? " -#, fuzzy -#| msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? " msgid "Change (N)ame, (E)mail, or (O)kay/(Q)uit? " -msgstr "Mudar (N)ome, (C)omentário, (E)ndereço ou (O)k/(S)air? " +msgstr "Alterar (N)ome, (E)mail, ou (O)k/(S)air? " msgid "Please correct the error first\n" -msgstr "Por favor corrija primeiro o erro\n" +msgstr "Corrija primeiro o erro\n" msgid "" "We need to generate a lot of random bytes. It is a good idea to perform\n" @@ -4649,13 +4436,13 @@ msgid "" "generator a better chance to gain enough entropy.\n" msgstr "" "Precisamos gerar muitos bytes aleatórios. É uma boa ideia realizar outra\n" -"actividade (escrever no teclado, mover o rato, usar os discos) durante a\n" -"geração dos números primos; isso dá ao gerador de números aleatórios\n" +"atividade (escrever no teclado, mover o rato, usar os discos) durante a\n" +"geração dos números primos; isto dá ao gerador de números aleatórios\n" "uma hipótese maior de ganhar entropia suficiente.\n" #, c-format msgid "WARNING: v4 is specified, but overridden by v5.\n" -msgstr "" +msgstr "AVISO: v4 está especificada, mas é sobreposta pela v5.\n" #, c-format msgid "Key generation failed: %s\n" @@ -4667,119 +4454,117 @@ msgid "" " \"%s\"\n" "\n" msgstr "" +"Prestes a criar uma chave para:\n" +" \"%s\"\n" +"\n" msgid "Continue? (Y/n) " -msgstr "" +msgstr "Continuar? (S/n) " -#, fuzzy, c-format +#, c-format msgid "A key for \"%s\" already exists\n" -msgstr "%s' já comprimido\n" +msgstr "Já existe uma chave para \"%s\"\n" -#, fuzzy -#| msgid "Create anyway? " msgid "Create anyway? (y/N) " -msgstr "Criar mesmo assim?" +msgstr "Mesmo assim, criar? (s/N) " -#, fuzzy, c-format -#| msgid "Create anyway? " +#, c-format msgid "creating anyway\n" -msgstr "Criar mesmo assim?" +msgstr "mesmo assim, criando\n" #, c-format msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n" msgstr "" +"Nota: Usar \"%s %s\" para uma caixa de diálogo completa de geração de " +"chave.\n" #, c-format msgid "Key generation canceled.\n" msgstr "Geração de chave cancelada.\n" -#, fuzzy, c-format +#, c-format msgid "can't create backup file '%s': %s\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível criar o ficheiro de backup '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: backup of card key saved to '%s'\n" -msgstr "NOTA: chave secreta %08lX expirou em %s\n" +msgstr "Nota: backup da chave do cartão guardada em '%s'\n" -#, fuzzy, c-format -#| msgid "writing public key to `%s'\n" +#, c-format msgid "writing public key to '%s'\n" -msgstr "a escrever chave pública para `%s'\n" +msgstr "escrevendo chave pública para '%s'\n" #, c-format msgid "no writable public keyring found: %s\n" -msgstr "nenhum porta-chaves público com permissões de escrita encontrado: %s\n" +msgstr "nenhum porta-chaves público com permissão de escrita encontrado: %s\n" -#, fuzzy, c-format -#| msgid "error writing public keyring `%s': %s\n" +#, c-format msgid "error writing public keyring '%s': %s\n" -msgstr "erro ao escrever no porta-chaves público `%s': %s\n" +msgstr "erro ao escrever o porta-chaves público '%s': %s\n" msgid "public and secret key created and signed.\n" msgstr "chaves pública e privada criadas e assinadas.\n" -#, fuzzy msgid "" "Note that this key cannot be used for encryption. You may want to use\n" "the command \"--edit-key\" to generate a subkey for this purpose.\n" msgstr "" -"Note que esta chave não pode ser usada para cifragem. Você pode usar\n" -"o comando \"--edit-key\" para gerar uma chave secundária para esse fim.\n" +"Repare que esta chave não pode ser usada para cifração. Poderá querer usar\n" +"o comando \"--edit-key\" para gerar uma subchave com esta finalidade.\n" #, c-format msgid "" "key has been created %lu second in future (time warp or clock problem)\n" msgstr "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"chave foi criada %lu segundo no futuro (deformação temporal ou problema de " +"relógio)\n" #, c-format msgid "" "key has been created %lu seconds in future (time warp or clock problem)\n" msgstr "" -"a chave foi criada %lu segundos no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"chave foi criada %lu segundos no futuro (deformação temporal ou problema de " +"relógio)\n" -#, fuzzy, c-format -#| msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n" +#, c-format msgid "Note: creating subkeys for v3 keys is not OpenPGP compliant\n" -msgstr "NOTA: a criação de sub-chave para chaves v3 não respeito o OpenPGP\n" +msgstr "" +"Nota: a criação de subchaves para chaves v3 não é compatível com OpenPGP\n" #, c-format msgid "Secret parts of primary key are not available.\n" -msgstr "Componentes secretas da chave primária não disponíveis.\n" +msgstr "Partes secretas da chave principal não disponíveis.\n" -#, fuzzy, c-format +#, c-format msgid "Secret parts of primary key are stored on-card.\n" -msgstr "Componentes secretas da chave primária não disponíveis.\n" +msgstr "Partes secretas da chave principal estão armazenadas no cartão.\n" -#, fuzzy msgid "Really create? (y/N) " -msgstr "Realmente criar? " +msgstr "De certeza que deseja criar? (s/N) " msgid "never " -msgstr "" +msgstr "nunca " msgid "AEAD: " -msgstr "" +msgstr "AEAD: " msgid "Digest: " -msgstr "'Digest': " +msgstr "Digest: " msgid "Features: " msgstr "Características: " msgid "Keyserver no-modify" -msgstr "" +msgstr "Servidor de chaves no-modify" msgid "Critical signature policy: " -msgstr "Politica de assinatura crítica: " +msgstr "Política de assinatura crítica: " msgid "Signature policy: " -msgstr "Politica de assinatura: " +msgstr "Política de assinatura: " msgid "Critical preferred keyserver: " -msgstr "" +msgstr "Servidor de chaves preferencial crítico: " msgid "Critical signature notation: " msgstr "Notação de assinatura crítica: " @@ -4787,208 +4572,200 @@ msgstr "Notação de assinatura crítica: " msgid "Signature notation: " msgstr "Notação de assinatura: " -#, fuzzy, c-format -#| msgid "%d bad signatures\n" +#, c-format msgid "%d good signature\n" msgid_plural "%d good signatures\n" -msgstr[0] "%d assinaturas incorrectas\n" -msgstr[1] "%d assinaturas incorrectas\n" +msgstr[0] "%d assinatura válida\n" +msgstr[1] "%d assinaturas válidas\n" -#, fuzzy, c-format -#| msgid "1 signature not checked due to an error\n" +#, c-format msgid "%d signature not checked due to an error\n" msgid_plural "%d signatures not checked due to errors\n" -msgstr[0] "1 assinatura não verificada devido a um erro\n" -msgstr[1] "1 assinatura não verificada devido a um erro\n" +msgstr[0] "%d assinatura não verificada devido a erro\n" +msgstr[1] "%d assinaturas não verificadas devido a erros\n" #, c-format msgid "Warning: %lu key skipped due to its large size\n" msgid_plural "Warning: %lu keys skipped due to their large sizes\n" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Aviso: %lu chave ignorada devido ao seu tamanho grande\n" +msgstr[1] "Aviso: %lu chaves ignoradas devido aos seus tamanhos grandes\n" msgid "Keyring" msgstr "Porta-chaves" msgid "Primary key fingerprint:" -msgstr "Impressão da chave primária:" +msgstr "Impressão digital da chave principal:" msgid " Subkey fingerprint:" -msgstr " Impressão da subchave:" +msgstr " Impressão digital da subchave:" #. TRANSLATORS: this should fit into 24 bytes so that the #. * fingerprint data is properly aligned with the user ID msgid " Primary key fingerprint:" -msgstr "Impressão da chave primária:" +msgstr " Impressão chave princ.:" msgid " Subkey fingerprint:" -msgstr " Impressão da subchave:" +msgstr " Impressão da subchave:" -#, fuzzy msgid " Key fingerprint =" -msgstr " Impressão da chave =" +msgstr " Impressão da chave =" msgid " Card serial no. =" -msgstr "" +msgstr "Nº de série do cartão =" -#, fuzzy, c-format +#, c-format msgid "caching keyring '%s'\n" -msgstr "a verificar o porta chaves `%s'\n" +msgstr "guardando na cache do porta-chaves '%s'\n" -#, fuzzy, c-format +#, c-format msgid "%lu keys cached so far (%lu signature)\n" msgid_plural "%lu keys cached so far (%lu signatures)\n" -msgstr[0] "%lu chave verificadas (%lu assinaturas)\n" -msgstr[1] "%lu chave verificadas (%lu assinaturas)\n" +msgstr[0] "" +"%lu chaves que, até agora, foram guardadas na cache (%lu assinatura)\n" +msgstr[1] "" +"%lu chaves que, até agora, foram guardadas na cache (%lu assinaturas)\n" #, c-format msgid "%lu key cached" msgid_plural "%lu keys cached" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lu chave guardada na cache" +msgstr[1] "%lu chaves guardadas na cache" -#, fuzzy, c-format -#| msgid "1 bad signature\n" +#, c-format msgid " (%lu signature)\n" msgid_plural " (%lu signatures)\n" -msgstr[0] "1 assinatura incorrecta\n" -msgstr[1] "1 assinatura incorrecta\n" +msgstr[0] " (%lu assinatura)\n" +msgstr[1] " (%lu assinaturas)\n" #, c-format msgid "%s: keyring created\n" msgstr "%s: porta-chaves criado\n" msgid "override proxy options set for dirmngr" -msgstr "" +msgstr "sobrepor opções de proxy definidas para dirmngr" msgid "include revoked keys in search results" -msgstr "" +msgstr "incluir chaves revogadas nos resultados da pesquisa" msgid "include subkeys when searching by key ID" -msgstr "" +msgstr "incluir subchaves ao pesquisar pela ID de chave" msgid "override timeout options set for dirmngr" -msgstr "" +msgstr "sobrepor opções de tempo limite definidas para dirmngr" msgid "automatically retrieve keys when verifying signatures" -msgstr "" +msgstr "obter chaves automaticamente quando se verifica assinaturas" -#, fuzzy msgid "honor the preferred keyserver URL set on the key" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "honrar a URL do servidor de chaves preferencial definida na chave" -#, fuzzy msgid "disabled" -msgstr "disable" +msgstr "desabilitado" msgid "Enter number(s), N)ext, or Q)uit > " -msgstr "" +msgstr "Introduzir o(s) número(s), N)ext, ou Q)uit > " -#, fuzzy, c-format +#, c-format msgid "invalid keyserver protocol (us %d!=handler %d)\n" -msgstr "opções de exportação inválidas\n" +msgstr "protocolo de servidor de chaves inválido (nós %d!=handler %d)\n" #, c-format msgid "\"%s\" not a key ID: skipping\n" -msgstr "" +msgstr "\"%s\" não é uma ID de chave: ignorando\n" -#, fuzzy, c-format +#, c-format msgid "refreshing %d key from %s\n" msgid_plural "refreshing %d keys from %s\n" -msgstr[0] "a pedir a chave %08lX de %s\n" -msgstr[1] "a pedir a chave %08lX de %s\n" +msgstr[0] "atualizando %d chave de %s\n" +msgstr[1] "atualizando %d chaves de %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unable to refresh key %s via %s: %s\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: não é possível atualizar a chave %s via %s: %s\n" -#, fuzzy, c-format +#, c-format msgid "key \"%s\" not found on keyserver\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave \"%s\" não encontrada no servidor de chaves\n" -#, fuzzy, c-format +#, c-format msgid "key not found on keyserver\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave não encontrada no servidor de chaves\n" -#, fuzzy, c-format +#, c-format msgid "requesting key %s from %s\n" -msgstr "a pedir a chave %08lX de %s\n" +msgstr "pedindo chave %s de %s\n" -#, fuzzy, c-format +#, c-format msgid "no keyserver known\n" -msgstr "opções de exportação inválidas\n" +msgstr "nenhum servidor de chaves conhecido\n" -#, fuzzy, c-format +#, c-format msgid "skipped \"%s\": %s\n" -msgstr "ignorado `%s': %s\n" +msgstr "ignorado \"%s\": %s\n" -#, fuzzy, c-format +#, c-format msgid "sending key %s to %s\n" -msgstr "" -"\"\n" -"assinado com a sua chave %08lX em %s\n" +msgstr "enviando a chave %s para %s\n" -#, fuzzy, c-format +#, c-format msgid "requesting key from '%s'\n" -msgstr "a pedir a chave %08lX de %s\n" +msgstr "pedindo chave de '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unable to fetch URI %s: %s\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: não é possível buscar o URI %s: %s\n" #, c-format msgid "weird size for an encrypted session key (%d)\n" msgstr "tamanho estranho para uma chave de sessão cifrada (%d)\n" -#, fuzzy, c-format +#, c-format msgid "%s.%s encrypted session key\n" -msgstr "tamanho estranho para uma chave de sessão cifrada (%d)\n" +msgstr "%s.%s chave de sessão cifrada\n" -#, fuzzy, c-format -#| msgid "%s encrypted data\n" +#, c-format msgid "%s.%s encrypted data\n" -msgstr "dados cifrados com %s\n" +msgstr "%s.%s dados cifrados\n" -#, fuzzy, c-format -#| msgid "encrypted with unknown algorithm %d\n" +#, c-format msgid "encrypted with unknown algorithm %d.%s\n" -msgstr "cifrado com algoritmo desconhecido %d\n" +msgstr "cifrado com algoritmo desconhecido %d.%s\n" -#, fuzzy, c-format +#, c-format msgid "passphrase generated with unknown digest algorithm %d\n" -msgstr "cifrado com algoritmo desconhecido %d\n" +msgstr "frase-secreta gerada com algoritmo de digest desconhecido %d\n" -#, fuzzy, c-format +#, c-format msgid "public key is %s\n" -msgstr "a chave pública é %08lX\n" +msgstr "chave pública é %s\n" -#, fuzzy, c-format +#, c-format msgid "encrypted with %s key, ID %s, created %s\n" -msgstr "cifrado com chave %u-bit %s, ID %08lX, criada em %s\n" +msgstr "cifrado com chave %s, ID %s, criado em %s\n" -#, fuzzy, c-format +#, c-format msgid " \"%s\"\n" -msgstr " ou \"" +msgstr " \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "encrypted with %s key, ID %s\n" -msgstr "cifrado com chave %s, ID %08lX\n" +msgstr "cifrado com chave %s, ID %s\n" #, c-format msgid "WARNING: multiple plaintexts seen\n" -msgstr "" +msgstr "AVISO: vários textos simples vistos\n" -#, fuzzy, c-format +#, c-format msgid "encrypted with %lu passphrases\n" -msgstr "Repita a frase secreta\n" +msgstr "cifrado com %lu frase-secretas\n" -#, fuzzy, c-format +#, c-format msgid "encrypted with 1 passphrase\n" -msgstr "Repita a frase secreta\n" +msgstr "cifrado com 1 frase-secreta\n" #, c-format msgid "public key decryption failed: %s\n" -msgstr "decifragem de chave pública falhou: %s\n" +msgstr "falha ao decifrar com chave pública: %s\n" #, c-format msgid "public key encrypted data: good DEK\n" @@ -4996,34 +4773,36 @@ msgstr "dados cifrados com chave pública: DEK válido\n" #, c-format msgid "assuming %s encrypted data\n" -msgstr "a assumir dados cifrados %s\n" +msgstr "assumindo %s dados cifrados\n" #, c-format msgid "IDEA cipher unavailable, optimistically attempting to use %s instead\n" -msgstr "Cifra IDEO não disponível, a tentar utilizar %s em substituição\n" +msgstr "a cifra IDEA não está disponível, tentando utilizar %s invés\n" #, c-format msgid "WARNING: message was not integrity protected\n" -msgstr "AVISO: a mensagem não tinha a sua integridade protegida\n" +msgstr "AVISO: a mensagem não tinha proteção de integridade\n" msgid "" "Hint: If this message was created before the year 2003 it is\n" "likely that this message is legitimate. This is because back\n" "then integrity protection was not widely used.\n" msgstr "" +"Dica: Se esta mensagem foi criada antes do ano de 2003 é\n" +"provável que esta mensagem seja legítima. Isto porque dantes\n" +"a proteção da integridade não era amplamente utilizada.\n" #, c-format msgid "Use the option '%s' to decrypt anyway.\n" -msgstr "" +msgstr "Usar a opção '%s' para, mesmo assim, decifrar.\n" -#, fuzzy, c-format -#| msgid "decryption failed: %s\n" +#, c-format msgid "decryption forced to fail!\n" -msgstr "decifragem falhou: %s\n" +msgstr "decifração forçada a falhar!\n" #, c-format msgid "decryption okay\n" -msgstr "decifragem correcta\n" +msgstr "decifração ok\n" #, c-format msgid "WARNING: encrypted message has been manipulated!\n" @@ -5031,16 +4810,16 @@ msgstr "CUIDADO: a mensagem cifrada foi manipulada!\n" #, c-format msgid "decryption failed: %s\n" -msgstr "decifragem falhou: %s\n" +msgstr "decifração falhou: %s\n" #, c-format msgid "operation forced to fail due to unfulfilled compliance rules\n" msgstr "" +"operação forçada a falhar devido a regras de conformidade não cumpridas\n" -#, fuzzy, c-format -#| msgid "NOTE: sender requested \"for-your-eyes-only\"\n" +#, c-format msgid "Note: sender requested \"for-your-eyes-only\"\n" -msgstr "NOTA: o remetente solicitou \"apenas-para-seus-olhos\"\n" +msgstr "Nota: remetente pediu \"for-your-eyes-only\"\n" #, c-format msgid "original file name='%.*s'\n" @@ -5048,317 +4827,307 @@ msgstr "nome do ficheiro original='%.*s'\n" #, c-format msgid "standalone revocation - use \"gpg --import\" to apply\n" -msgstr "revocação solitária - utilize \"gpg --import\" para aplicar\n" +msgstr "revogação autónoma - usar \"gpg --import\" para aplicar\n" -#, fuzzy, c-format +#, c-format msgid "no signature found\n" -msgstr "Assinatura correcta de \"" +msgstr "nenhuma assinatura encontrada\n" -#, fuzzy, c-format +#, c-format msgid "BAD signature from \"%s\"" -msgstr "Assinatura INCORRECTA de \"" +msgstr "Assinatura INVÁLIDA de \"%s\"" -#, fuzzy, c-format +#, c-format msgid "Expired signature from \"%s\"" -msgstr "Assinatura expirada de \"" +msgstr "Assinatura expirada de \"%s\"" -#, fuzzy, c-format +#, c-format msgid "Good signature from \"%s\"" -msgstr "Assinatura correcta de \"" +msgstr "Assinatura válida de \"%s\"" #, c-format msgid "signature verification suppressed\n" msgstr "verificação de assinatura suprimida\n" -#, fuzzy, c-format +#, c-format msgid "can't handle this ambiguous signature data\n" -msgstr "não consigo tratar estas assinaturas múltiplas\n" +msgstr "não é possível lidar com esses dados de assinatura ambíguos\n" -#, fuzzy, c-format +#, c-format msgid "Signature made %s\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Assinatura feita em %s\n" -#, fuzzy, c-format +#, c-format msgid " using %s key %s\n" -msgstr " ou \"" +msgstr " usando a chave %s de %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature made %s using %s key ID %s\n" -msgstr "Assinatura feita em %.*s usando %s, ID da chave %08lX\n" +msgstr "Assinatura feita em %s usando %s com ID de chave %s\n" -#, fuzzy, c-format +#, c-format msgid " issuer \"%s\"\n" -msgstr " ou \"" +msgstr " emissor \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "Key available at: " -msgstr "Nenhuma ajuda disponível" +msgstr "Chave disponível em: " #, c-format msgid "Note: Use '%s' to make use of this info\n" -msgstr "" +msgstr "Nota: Usar '%s' para fazer uso desta info\n" msgid "[uncertain]" msgstr "[incerto]" -#, fuzzy, c-format +#, c-format msgid " aka \"%s\"" -msgstr " ou \"" +msgstr " aka \"%s\"" -#, fuzzy, c-format -#| msgid "WARNING: This key is not certified with a trusted signature!\n" +#, c-format msgid "WARNING: This key is not suitable for signing in %s mode\n" -msgstr "AVISO: Esta chave não está certificada com uma assinatura confiável!\n" +msgstr "AVISO: Esta chave não é adequada para assinar no modo %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature expired %s\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "A assinatura expirou %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature expires %s\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "A assinatura expira %s\n" -#, fuzzy, c-format +#, c-format msgid "%s signature, digest algorithm %s%s%s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "assinatura %s, algoritmo de digest %s%s%s\n" -#, fuzzy msgid "binary" -msgstr "primary" +msgstr "binário" msgid "textmode" -msgstr "" +msgstr "modo de texto" -#, fuzzy msgid "unknown" -msgstr "versão desconhecida" +msgstr "desconhecido" -#, fuzzy -#| msgid "unknown pubkey algorithm" msgid ", key algorithm " -msgstr "algoritmo de chave pública desconhecido" +msgstr ", algoritmo da chave " #, c-format msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n" msgstr "" +"ATENÇÃO: não é uma assinatura desanexada; ficheiro '%s' NÃO foi verificado!\n" #, c-format msgid "Can't check signature: %s\n" -msgstr "Impossível verificar assinatura: %s\n" +msgstr "Não é possível verificar a assinatura: %s\n" #, c-format msgid "not a detached signature\n" -msgstr "não é uma assinatura separada\n" +msgstr "não é uma assinatura desanexada\n" #, c-format msgid "" "WARNING: multiple signatures detected. Only the first will be checked.\n" msgstr "" -"AVISO: várias assinaturas detectadas. Apenas a primeira será verificada.\n" +"AVISO: várias assinaturas detetadas. Apenas a primeira será verificada.\n" #, c-format msgid "standalone signature of class 0x%02x\n" -msgstr "assinatura de classe 0x%02x\n" +msgstr "assinatura autónoma da classe 0x%02x\n" #, c-format msgid "old style (PGP 2.x) signature\n" -msgstr "formato de assinatura antigo (PGP2.x)\n" +msgstr "tipo de assinatura antigo (PGP 2.x)\n" -#, fuzzy, c-format +#, c-format msgid "fstat of '%s' failed in %s: %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "fstat de '%s' falhou em %s: %s\n" -#, fuzzy, c-format +#, c-format msgid "fstat(%d) failed in %s: %s\n" -msgstr "base de dados de confiança: leitura falhou (n=%d): %s\n" +msgstr "fstat(%d) falhou em %s: %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: using experimental public key algorithm %s\n" -msgstr "impossível manipular algoritmo de chave pública %d\n" +msgstr "AVISO: usando o algoritmo de chave pública experimental %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n" -msgstr "" -"forçar o algoritmo de 'digest' %s (%d) viola as preferências do " -"destinatário\n" +msgstr "AVISO: chaves Elgamal de assinar+cifrar estão depreciadas\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: using experimental cipher algorithm %s\n" -msgstr "algoritmo de criptografia não implementado" +msgstr "AVISO: usando o algoritmo de cifra experimental %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: using experimental digest algorithm %s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "AVISO: usando o algoritmo de digest experimental %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: digest algorithm %s is deprecated\n" -msgstr "" -"forçar o algoritmo de 'digest' %s (%d) viola as preferências do " -"destinatário\n" +msgstr "AVISO: o algoritmo de digest %s foi depreciado\n" -#, fuzzy, c-format +#, c-format msgid "Note: signatures using the %s algorithm are rejected\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "Nota: as assinaturas que usam o algoritmo %s são rejeitadas\n" -#, fuzzy, c-format +#, c-format msgid "Note: third-party key signatures using the %s algorithm are rejected\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "" +"Nota: assinaturas de chave de terceiros usando o algoritmo %s são " +"rejeitadas\n" -#, fuzzy, c-format +#, c-format msgid "(reported error: %s)\n" -msgstr "armadura: %s\n" +msgstr "(reportado erro: %s)\n" -#, fuzzy, c-format +#, c-format msgid "(reported error: %s <%s>)\n" -msgstr "armadura: %s\n" +msgstr "(reportado erro: %s <%s>)\n" #, c-format msgid "(further info: " -msgstr "" +msgstr "(mais informações: " #, c-format msgid "%s:%d: deprecated option \"%s\"\n" -msgstr "%s:%d: opção depreciada \"%s\"\n" +msgstr "%s:%d: opção \"%s\" depreciada\n" #, c-format msgid "please use \"%s%s\" instead\n" -msgstr "por favor utilize \"%s%s\" em vez dela\n" +msgstr "use \"%s%s\" invés\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: \"%s\" is a deprecated command - do not use it\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "AVISO: \"%s\" é um comando depreciado - não o use\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "%s:%u: \"%s\" está obsoleto neste ficheiro - ele só tem efeito em %s\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "AVISO: \"%s%s\" é uma opção obsoleta - não tem efeito exceto em %s\n" -#, fuzzy msgid "Uncompressed" -msgstr "não processado" +msgstr "Descomprimido" #. TRANSLATORS: See doc/TRANSLATE about this string. -#, fuzzy msgid "uncompressed|none" -msgstr "não processado" +msgstr "descomprimido|nenhum" #, c-format msgid "this message may not be usable by %s\n" msgstr "esta mensagem poderá não ser utilizável pelo %s\n" -#, fuzzy, c-format +#, c-format msgid "ambiguous option '%s'\n" -msgstr "a ler opções de `%s'\n" +msgstr "opção ambígua '%s'\n" -#, fuzzy, c-format +#, c-format msgid "unknown option '%s'\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "opção desconhecida '%s'\n" #, c-format msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n" msgstr "" +"É esperado que a chave pública ECDSA esteja na codificação SEC múltiplo de 8 " +"bits\n" -#, fuzzy, c-format +#, c-format msgid "unknown weak digest '%s'\n" -msgstr "classe de assinatura desconhecida" +msgstr "digest '%s' fraco e desconhecido\n" -#, fuzzy, c-format -#| msgid "File `%s' exists. " +#, c-format msgid "File '%s' exists. " -msgstr "Arquivo `%s' já existe. " +msgstr "O ficheiro '%s' existe. " -#, fuzzy msgid "Overwrite? (y/N) " -msgstr "Escrever por cima (s/N)? " +msgstr "Sobrescrever? (s/N) " #, c-format msgid "%s: unknown suffix\n" msgstr "%s: sufixo desconhecido\n" msgid "Enter new filename" -msgstr "Digite novo nome de ficheiro" +msgstr "Introduzir um novo nome de ficheiro" #, c-format msgid "writing to stdout\n" -msgstr "a escrever em \"stdout\"\n" +msgstr "escrevendo para stdout\n" -#, fuzzy, c-format -#| msgid "assuming signed data in `%s'\n" +#, c-format msgid "assuming signed data in '%s'\n" -msgstr "a assumir dados assinados em `%s'\n" +msgstr "assumindo dados assinados em '%s'\n" #, c-format msgid "can't handle public key algorithm %d\n" -msgstr "impossível manipular algoritmo de chave pública %d\n" +msgstr "não é possível lidar com o algoritmo de chave pública %d\n" #, c-format msgid "WARNING: potentially insecure symmetrically encrypted session key\n" msgstr "" +"AVISO: chave de sessão simetricamente cifrada potencialmente insegura\n" -#, fuzzy, c-format -#| msgid "Critical signature notation: " +#, c-format msgid "Unknown critical signature notation: " -msgstr "Notação de assinatura crítica: " +msgstr "Notação de assinatura crítica desconhecida: " #, c-format msgid "subpacket of type %d has critical bit set\n" -msgstr "subpacote do tipo %d tem bit crítico ligado\n" +msgstr "sub-pacote do tipo %d tem bit crítico definido\n" -#, fuzzy msgid "Please enter the passphrase for decryption." -msgstr "muda a frase secreta" +msgstr "Introduza a frase-secreta para decifração." msgid "Enter passphrase\n" -msgstr "Insira a frase secreta\n" +msgstr "Introduzir a frase-secreta\n" #, c-format msgid "cancelled by user\n" -msgstr "cancelado pelo utilizador\n" +msgstr "cancelada pelo utilizador\n" -#, fuzzy, c-format +#, c-format msgid " (main key ID %s)" -msgstr " (ID principal da chave %08lX)" +msgstr " (ID da chave principal %s)" -#, fuzzy msgid "Please enter the passphrase to unlock the OpenPGP secret key:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para desbloquear a chave secreta OpenPGP:" -#, fuzzy msgid "Please enter the passphrase to import the OpenPGP secret key:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para importar a chave secreta OpenPGP:" -#, fuzzy msgid "Please enter the passphrase to export the OpenPGP secret subkey:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para exportar a subchave secreta OpenPGP:" -#, fuzzy msgid "Please enter the passphrase to export the OpenPGP secret key:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para exportar a chave secreta OpenPGP:" -#, fuzzy msgid "Do you really want to permanently delete the OpenPGP secret subkey key:" -msgstr "Você quer realmente remover as chaves selecionadas? " +msgstr "" +"De certeza que você deseja apagar permanentemente a subchave secreta OpenPGP:" -#, fuzzy msgid "Do you really want to permanently delete the OpenPGP secret key:" -msgstr "Você quer realmente remover as chaves selecionadas? " +msgstr "" +"De certeza que você deseja apagar permanentemente a chave secreta OpenPGP:" -#, fuzzy msgid "Please enter the passphrase to export the secret key with keygrip:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para exportar a chave secreta com keygrip:" -#, fuzzy, c-format +#, c-format msgid "" "%s\n" "\"%.*s\"\n" "%u-bit %s key, ID %s,\n" "created %s%s.\n" "%s" -msgstr "chave de %u-bit/%s, ID %08lX, criada em %s" +msgstr "" +"%s\n" +"\"%.*s\"\n" +"%u-bit chave %s, ID %s,\n" +"criada %s%s.\n" +"%s" msgid "" "\n" @@ -5367,66 +5136,74 @@ msgid "" "very large picture, your key will become very large as well!\n" "Keeping the image close to 240x288 is a good size to use.\n" msgstr "" +"\n" +"Escolha uma imagem para usar como ID fotográfica. A imagem deve ser um\n" +"ficheiro JPEG.\n" +"Lembre-se de que a imagem é armazenada dentro da sua chave pública.\n" +"Se você usar uma imagem muito grande, sua chave também se vai tornar\n" +"muito grande!\n" +"Manter a imagem perto de 240x288 é um bom tamanho para se usar.\n" msgid "Enter JPEG filename for photo ID: " -msgstr "" +msgstr "Introduzir um nome do ficheiro JPEG para a ID fotográfica: " -#, fuzzy, c-format +#, c-format msgid "unable to open JPEG file '%s': %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "não é possível abrir o ficheiro JPEG '%s': %s\n" #, c-format msgid "This JPEG is really large (%d bytes) !\n" -msgstr "" +msgstr "Este JPEG é mesmo grande (%d bytes) !\n" -#, fuzzy msgid "Are you sure you want to use it? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem certeza de que deseja usá-lo? (s/N) " -#, fuzzy, c-format +#, c-format msgid "'%s' is not a JPEG file\n" -msgstr "%s: não é um base de dados de confiança\n" +msgstr "'%s' não é um ficheiro JPEG\n" -#, fuzzy msgid "Is this photo correct (y/N/q)? " -msgstr "Está correto (s/n)? " +msgstr "Esta foto está correta? (s/N/q) " #, c-format msgid "no remote program execution supported\n" -msgstr "" +msgstr "não há suporte a execução de programas remotos\n" -#, fuzzy, c-format +#, c-format msgid "this platform requires temporary files when calling external programs\n" -msgstr "%s: erro ao ler registo de versão: %s\n" +msgstr "" +"esta plataforma requer ficheiros temporários ao chamar programas externos\n" -#, fuzzy, c-format +#, c-format msgid "unable to execute shell '%s': %s\n" -msgstr "não foi possível alterar o exec-path para %s\n" +msgstr "não é possível executar o shell '%s': %s\n" #, c-format msgid "unnatural exit of external program\n" -msgstr "" +msgstr "saída não natural do programa externo\n" -#, fuzzy, c-format +#, c-format msgid "system error while calling external program: %s\n" -msgstr "%s: erro ao ler registo de versão: %s\n" +msgstr "erro do sistema ao chamar o programa externo: %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: não é possível remover o ficheiro temporário (%s) '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unable to remove temp directory '%s': %s\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: não é possível remover a pasta temporária '%s': %s\n" #, c-format msgid "" "external program calls are disabled due to unsafe options file permissions\n" msgstr "" +"As chamadas de programa externo estão desativadas devido a opções não\n" +"seguras de permissões de ficheiro\n" -#, fuzzy, c-format +#, c-format msgid "unable to display photo ID!\n" -msgstr "não foi possível alterar o exec-path para %s\n" +msgstr "não é possível exibir uma ID fotográfica!\n" #. TRANSLATORS: These are the allowed answers in lower and #. uppercase. Below you will find the matching strings which @@ -5439,76 +5216,71 @@ msgstr "não foi possível alterar o exec-path para %s\n" #. q = quit #. msgid "iImMqQsS" -msgstr "iImMqQsS" +msgstr "mMvVsSiI" -#, fuzzy msgid "No trust value assigned to:\n" -msgstr "" -"Nenhum valor de confiança designado para:\n" -"%4u%c/%08lX %s \"" +msgstr "Nenhum valor da confiança atribuído a:\n" -#, fuzzy, c-format +#, c-format msgid " aka \"%s\"\n" -msgstr " ou \"" +msgstr " aka \"%s\"\n" -#, fuzzy msgid "" "How much do you trust that this key actually belongs to the named user?\n" -msgstr "Esta chave provavelmente pertence ao dono\n" +msgstr "" +"Quanto é que você confia que esta chave realmente pertence a tal " +"utilizador?\n" -#, fuzzy, c-format +#, c-format msgid " %d = I don't know or won't say\n" -msgstr " %d = Não sei\n" +msgstr " %d = Não sei ou não vou dizer\n" -#, fuzzy, c-format +#, c-format msgid " %d = I do NOT trust\n" -msgstr " %d = Eu NÃO confio\n" +msgstr " %d = NÃO confio\n" -#, fuzzy, c-format +#, c-format msgid " %d = I trust ultimately\n" -msgstr " %d = Confio de forma total\n" +msgstr " %d = Confio plenamente\n" -#, fuzzy msgid " m = back to the main menu\n" -msgstr " m = voltar ao menu principal\n" +msgstr " v = voltar ao menu principal\n" -#, fuzzy msgid " s = skip this key\n" -msgstr " s = saltar esta chave\n" +msgstr " i = ignorar esta chave\n" -#, fuzzy msgid " q = quit\n" -msgstr " q = sair\n" +msgstr " s = sair\n" #, c-format msgid "" "The minimum trust level for this key is: %s\n" "\n" msgstr "" +"O nível mínimo da confiança para esta chave é: %s\n" +"\n" msgid "Your decision? " -msgstr "Decisão? " +msgstr "Sua decisão? " -#, fuzzy msgid "Do you really want to set this key to ultimate trust? (y/N) " -msgstr "Tem a certeza que quer confiar totalmente nesta chave?" +msgstr "" +"De certeza que você deseja definir confiança plena para esta chave? (s/N) " msgid "Certificates leading to an ultimately trusted key:\n" msgstr "Certificados que levam a uma chave confiada plenamente:\n" -#, fuzzy, c-format +#, c-format msgid "%s: There is no assurance this key belongs to the named user\n" -msgstr "" -"%08lx: Não há indicação de que a assinatura pertence realmente ao dono.\n" +msgstr "%s: Não há garantia de que esta chave pertence a tal utilizador\n" -#, fuzzy, c-format +#, c-format msgid "%s: There is limited assurance this key belongs to the named user\n" -msgstr "" -"%08lx: Não há indicação de que a assinatura pertence realmente ao dono.\n" +msgstr "%s: Há garantia limitada de que esta chave pertence a tal utilizador\n" -#, fuzzy, c-format +#, c-format msgid "This key probably belongs to the named user\n" -msgstr "Esta chave provavelmente pertence ao dono\n" +msgstr "Esta chave provavelmente pertence a tal utilizador\n" #, c-format msgid "This key belongs to us\n" @@ -5516,69 +5288,64 @@ msgstr "Esta chave pertence-nos\n" #, c-format msgid "%s: This key is bad! It has been marked as untrusted!\n" -msgstr "" +msgstr "%s: Esta chave é inválida! Foi marcada como não confiável!\n" -#, fuzzy msgid "" "This key is bad! It has been marked as untrusted! If you\n" "*really* know what you are doing, you may answer the next\n" "question with yes.\n" msgstr "" -"NÃO se tem certeza de que esta chave pertence ao seu dono.\n" -"Se você *realmente* sabe o que está a fazer, pode responder\n" -"sim à próxima pergunta\n" -"\n" +"Esta chave é inválida! Foi marcada como não confiável! Se você\n" +"tem a *certeza* do que está fazendo, você pode responder à próxima\n" +"pergunta com sim.\n" -#, fuzzy msgid "" "It is NOT certain that the key belongs to the person named\n" "in the user ID. If you *really* know what you are doing,\n" "you may answer the next question with yes.\n" msgstr "" -"NÃO se tem certeza de que esta chave pertence ao seu dono.\n" -"Se você *realmente* sabe o que está a fazer, pode responder\n" -"sim à próxima pergunta\n" -"\n" +"NÃO é certo que a chave pertença à pessoa da ID de utilizador.\n" +"Se você tem a *certeza* do que está fazendo, você pode responder\n" +"à próxima pergunta com sim.\n" -#, fuzzy msgid "Use this key anyway? (y/N) " -msgstr "Usar esta chave de qualquer modo? " +msgstr "Mesmo assim, usar esta chave? (s/N) " #, c-format msgid "WARNING: Using untrusted key!\n" -msgstr "AVISO: A utilizar uma chave que não é de confiança!\n" +msgstr "AVISO: Usando chave não confiável!\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: this key might be revoked (revocation key not present)\n" msgstr "" -"AVISO: a chave %08lX pode estar revocada: chave de revocação %08lX não " -"presente.\n" +"AVISO: esta chave pode estar revogada (chave de revogação não presente)\n" -#, fuzzy, c-format +#, c-format msgid "checking User ID \"%s\"\n" -msgstr "ID de utilizador: \"" +msgstr "verificando a ID de Utilizador \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "option %s given but issuer \"%s\" does not match\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "opção %s dada, mas não corresponde ao emissor \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "issuer \"%s\" does not match any User ID\n" -msgstr "chave %08lX: não corresponde à nossa cópia\n" +msgstr "o emissor \"%s\" não corresponde a qualquer ID de Utilizador\n" -#, fuzzy, c-format +#, c-format msgid "option %s given but no matching User ID found\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "" +"opção %s dada, mas nenhuma ID de utilizador correspondente encontrada\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: This key has been revoked by its designated revoker!\n" -msgstr "AVISO: Esta chave foi revogada pelo seu dono!\n" +msgstr "AVISO: Esta chave foi revogada pela sua revogadora designada!\n" #, c-format msgid "WARNING: This key has been revoked by its owner!\n" msgstr "AVISO: Esta chave foi revogada pelo seu dono!\n" -#, fuzzy, c-format +#, c-format msgid " This could mean that the signature is forged.\n" msgstr " Isto pode significar que a assinatura é falsificada.\n" @@ -5588,16 +5355,17 @@ msgstr "AVISO: Esta subchave foi revogada pelo seu dono!\n" #, c-format msgid "Note: This key has been disabled.\n" -msgstr "Nota: Esta chave foi desactivada.\n" +msgstr "Nota: Esta chave foi desabilitada.\n" #, c-format msgid "Note: This key has expired!\n" msgstr "Nota: Esta chave expirou!\n" -#, fuzzy, c-format -#| msgid "WARNING: This key is not certified with a trusted signature!\n" +#, c-format msgid "WARNING: The key's User ID is not certified with a trusted signature!\n" -msgstr "AVISO: Esta chave não está certificada com uma assinatura confiável!\n" +msgstr "" +"AVISO: A ID de utilizador da chave não está certificada com uma assinatura " +"confiável!\n" #, c-format msgid "WARNING: This key is not certified with a trusted signature!\n" @@ -5606,7 +5374,7 @@ msgstr "AVISO: Esta chave não está certificada com uma assinatura confiável!\ #, c-format msgid "" " There is no indication that the signature belongs to the owner.\n" -msgstr " Não há indicação de que a assinatura pertence ao dono.\n" +msgstr " Não há indicação que a assinatura pertença ao dono.\n" #, c-format msgid "WARNING: We do NOT trust this key!\n" @@ -5616,137 +5384,133 @@ msgstr "AVISO: Nós NÃO confiamos nesta chave!\n" msgid " The signature is probably a FORGERY.\n" msgstr " A assinatura é provavelmente uma FALSIFICAÇÃO.\n" -#, fuzzy, c-format -#| msgid "" -#| "WARNING: This key is not certified with sufficiently trusted signatures!\n" +#, c-format msgid "" "WARNING: The key's User ID is not certified with sufficiently trusted " "signatures!\n" msgstr "" -"AVISO: Esta chave não está certificada com assinaturas suficientemente\n" -" confiáveis!\n" +"AVISO: A ID de utilizador da chave não é certificada com assinaturas " +"suficientemente confiáveis!\n" #, c-format msgid "" "WARNING: This key is not certified with sufficiently trusted signatures!\n" msgstr "" -"AVISO: Esta chave não está certificada com assinaturas suficientemente\n" -" confiáveis!\n" +"AVISO: Esta chave não está certificada com assinaturas suficientemente " +"confiáveis!\n" #, c-format msgid " It is not certain that the signature belongs to the owner.\n" -msgstr " Não se tem certeza de que a assinatura pertence ao dono.\n" +msgstr " Não há certeza que a assinatura pertença ao dono.\n" #, c-format msgid "%s: skipped: %s\n" -msgstr "%s: ignorado: %s\n" +msgstr "%s: ignorada: %s\n" #, c-format msgid "%s: skipped: public key is disabled\n" -msgstr "%s: ignorado: a chave pública está desactivada\n" +msgstr "%s: ignorada: a chave pública está desabilitada\n" #, c-format msgid "%s: skipped: public key already present\n" -msgstr "%s: ignorado: a chave pública já está presente\n" +msgstr "%s: ignorada: a chave pública já está presente\n" -#, fuzzy, c-format -#| msgid "can't connect to `%s': %s\n" +#, c-format msgid "can't encrypt to '%s'\n" -msgstr "impossível ligar a `%s': %s\n" +msgstr "não é possível cifrar para '%s'\n" -#, fuzzy, c-format +#, c-format msgid "option '%s' given, but no valid default keys given\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "opção '%s' dada, mas nenhuma chave pré-definida válida dada\n" -#, fuzzy, c-format +#, c-format msgid "option '%s' given, but option '%s' not given\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "opção '%s' dada, mas opção '%s' não foi dada\n" msgid "You did not specify a user ID. (you may use \"-r\")\n" -msgstr "Não especificou um identificador de utilizador. (pode usar \"-r\")\n" +msgstr "Não especificou uma ID de utilizador. (pode usar \"-r\")\n" msgid "Current recipients:\n" -msgstr "" +msgstr "Destinatários atuais:\n" msgid "" "\n" "Enter the user ID. End with an empty line: " msgstr "" "\n" -"Insira o identificador do utilizador. Termine com uma linha vazia: " +"Introduzir a ID do utilizador. Terminar com uma linha vazia: " msgid "No such user ID.\n" -msgstr "Identificador de utilizador inexistente.\n" +msgstr "Não existe tal ID de utilizador.\n" #, c-format msgid "skipped: public key already set as default recipient\n" -msgstr "ignorado: chave pública já colocada como destinatário por omissão\n" +msgstr "ignorada: chave pública já definida como destinatário pré-definido\n" msgid "Public key is disabled.\n" -msgstr "A chave pública está desativada.\n" +msgstr "A chave pública está desabilitada.\n" #, c-format msgid "skipped: public key already set\n" -msgstr "ignorado: a chave pública já está presente\n" +msgstr "ignorada: a chave pública já está presente\n" -#, fuzzy, c-format +#, c-format msgid "unknown default recipient \"%s\"\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "destinatário pré-definido \"%s\" desconhecido\n" #, c-format msgid "no valid addressees\n" -msgstr "nenhum endereço válido\n" +msgstr "nenhum destinatário válido\n" -#, fuzzy, c-format +#, c-format msgid "Note: key %s has no %s feature\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "Nota: a chave %s não tem a característica %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: key %s has no preference for %s\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "Nota: a chave %s não tem preferência por %s\n" #, c-format msgid "data not saved; use option \"--output\" to save it\n" msgstr "dados não gravados; use a opção \"--output\" para gravá-los\n" msgid "Detached signature.\n" -msgstr "Assinatura separada.\n" +msgstr "Assinatura desanexada.\n" msgid "Please enter name of data file: " -msgstr "Por favor digite o nome do ficheiro de dados: " +msgstr "Introduza o nome do ficheiro de dados: " #, c-format msgid "reading stdin ...\n" -msgstr "lendo do \"stdin\" ...\n" +msgstr "lendo do stdin ...\n" #, c-format msgid "no signed data\n" -msgstr "não há dados assinados\n" +msgstr "sem dados assinados\n" -#, fuzzy, c-format -#| msgid "can't open signed data `%s'\n" +#, c-format msgid "can't open signed data '%s'\n" -msgstr "impossível abrir dados assinados `%s'\n" +msgstr "não é possível abrir dados assinados '%s'\n" -#, fuzzy, c-format +#, c-format msgid "can't open signed data fd=%d: %s\n" -msgstr "impossível abrir dados assinados `%s'\n" +msgstr "não é possível abrir dados assinados fd=%d: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s is not suitable for decryption in %s mode\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "a chave %s não é adequada para decifração no modo %s\n" -#, fuzzy, c-format +#, c-format msgid "anonymous recipient; trying secret key %s ...\n" -msgstr "destinatário anónimo; a tentar chave secreta %08lX ...\n" +msgstr "destinatário anónimo; tentando chave secreta %s ...\n" -#, fuzzy, c-format +#, c-format msgid "used key is not marked for encryption use.\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "a chave usada não está marcada para uso de cifração.\n" #, c-format msgid "okay, we are the anonymous recipient.\n" -msgstr "certo, nós somos o destinatário anónimo.\n" +msgstr "ok, nós somos o destinatário anónimo.\n" #, c-format msgid "old encoding of the DEK is not supported\n" @@ -5754,68 +5518,67 @@ msgstr "codificação antiga do DEK não suportada\n" #, c-format msgid "cipher algorithm %d%s is unknown or disabled\n" -msgstr "algoritmo de cifra %d%s é desconhecido ou foi desactivado\n" +msgstr "o algoritmo de cifra %d%s é desconhecido ou foi desabilitado\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: cipher algorithm %s not found in recipient preferences\n" -msgstr "NOTA: algoritmo de cifragem %d não encontrado nas preferências\n" +msgstr "" +"AVISO: o algoritmo de cifra %s não foi encontrado nas preferências do " +"destinatário\n" -#, fuzzy, c-format +#, c-format msgid "Note: secret key %s expired at %s\n" -msgstr "NOTA: chave secreta %08lX expirou em %s\n" +msgstr "Nota: a chave secreta %s expirou em %s\n" -#, fuzzy, c-format -#| msgid "NOTE: key has been revoked" +#, c-format msgid "Note: key has been revoked" -msgstr "NOTA: a chave foi revogada" +msgstr "Nota: a chave foi revogada" -#, fuzzy, c-format +#, c-format msgid "build_packet failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "build_packet falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s has no user IDs\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "a chave %s não tem IDs de utilizador\n" msgid "To be revoked by:\n" -msgstr "" +msgstr "Para ser revogada por:\n" msgid "(This is a sensitive revocation key)\n" -msgstr "" +msgstr "(Esta é uma chave de revogação sensitiva)\n" -#, fuzzy -#| msgid "Secret key is available.\n" msgid "Secret key is not available.\n" -msgstr "Chave secreta disponível.\n" +msgstr "A chave secreta não está disponível.\n" -#, fuzzy msgid "Create a designated revocation certificate for this key? (y/N) " -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Criar um certificado de revogação designado para esta chave? (s/N) " msgid "ASCII armored output forced.\n" -msgstr "" +msgstr "Saída blindada ASCII forçada.\n" -#, fuzzy, c-format +#, c-format msgid "make_keysig_packet failed: %s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "make_keysig_packet falhou: %s\n" -#, fuzzy msgid "Revocation certificate created.\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "Certificado de revogação criado.\n" #, c-format msgid "no revocation keys found for \"%s\"\n" -msgstr "" +msgstr "Nenhuma chave de revogação encontrada para \"%s\"\n" -#, fuzzy msgid "This is a revocation certificate for the OpenPGP key:" -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Este é um certificado de revogação para a chave OpenPGP:" msgid "" "A revocation certificate is a kind of \"kill switch\" to publicly\n" "declare that a key shall not anymore be used. It is not possible\n" "to retract such a revocation certificate once it has been published." msgstr "" +"Um certificado de revogação é uma espécie de \"kill switch\" para\n" +"declarar publicamente que uma chave não deverá ser mais usada. Não\n" +"é possível retirar tal certificado de revogação depois de publicado." msgid "" "Use it to revoke this key in case of a compromise or loss of\n" @@ -5824,36 +5587,43 @@ msgid "" "a reason for the revocation. For details see the description of\n" "of the gpg command \"--generate-revocation\" in the GnuPG manual." msgstr "" +"Use-o para revogar esta chave caso seja comprometida ou em caso de\n" +"perda da chave secreta. No entanto, se a chave secreta ainda for\n" +"acessível, é melhor gerar um novo certificado de revogação e dar um\n" +"motivo para a revogação. Para obter detalhes, consulte a descrição do\n" +"comando gpg \"--generate-revocation\" no manual do GnuPG." msgid "" "To avoid an accidental use of this file, a colon has been inserted\n" "before the 5 dashes below. Remove this colon with a text editor\n" "before importing and publishing this revocation certificate." msgstr "" +"Para evitar o uso acidental deste ficheiro, 'dois pontos' foram\n" +"inseridos antes dos 5 traços abaixo. Remova estes 'dois pontos' com\n" +"um editor de texto antes de importar e publicar este certificado de\n" +"revogação." -#, fuzzy, c-format +#, c-format msgid "revocation certificate stored as '%s.rev'\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado de revogação armazenado como '%s.rev'\n" -#, fuzzy, c-format +#, c-format msgid "secret key \"%s\" not found\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave secreta \"%s\" não encontrada\n" #. TRANSLATORS: The %s prints a key specification which #. for example has been given at the command line. Several lines #. lines with secret key infos are printed after this message. #, c-format msgid "'%s' matches multiple secret keys:\n" -msgstr "" +msgstr "'%s' corresponde a várias chaves secretas:\n" -#, fuzzy, c-format -#| msgid "error creating keyring `%s': %s\n" +#, c-format msgid "error searching the keyring: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao pesquisar o porta-chaves: %s\n" -#, fuzzy msgid "Create a revocation certificate for this key? (y/N) " -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Criar um certificado de revogação para esta chave? (s/N) " msgid "" "Revocation certificate created.\n" @@ -5864,34 +5634,37 @@ msgid "" "your media become unreadable. But have some caution: The print system of\n" "your machine might store the data and make it available to others!\n" msgstr "" +"Certificado de revogação criado.\n" +"\n" +"Mova-o para um sítio em que você o possa esconder; se Mallory tiver\n" +"acesso a este certificado, ele poderá usá-lo para tornar sua chave\n" +"inutilizável. É inteligente imprimir este certificado e guardá-lo,\n" +"caso se torne ilegível em seu dispositivo. Mas tenha algum cuidado: o\n" +"sistema de impressão da sua máquina pode armazenar os dados e\n" +"disponibilizá-los para outras pessoas!\n" -#, fuzzy msgid "Please select the reason for the revocation:\n" -msgstr "motivo da revocação: " +msgstr "Selecione o motivo da revogação:\n" msgid "Cancel" -msgstr "" +msgstr "Cancelar" #, c-format msgid "(Probably you want to select %d here)\n" -msgstr "" +msgstr "(Provavelmente aqui você desejará selecionar %d)\n" -#, fuzzy msgid "Enter an optional description; end it with an empty line:\n" -msgstr "" -"\n" -"Insira o identificador do utilizador. Termine com uma linha vazia: " +msgstr "Introduzir uma descrição opcional; finalize com uma linha vazia:\n" -#, fuzzy, c-format +#, c-format msgid "Reason for revocation: %s\n" -msgstr "motivo da revocação: " +msgstr "Motivo da revogação: %s\n" msgid "(No description given)\n" -msgstr "" +msgstr "(Nenhuma descrição dada)\n" -#, fuzzy msgid "Is this okay? (y/N) " -msgstr "Usar esta chave de qualquer modo? " +msgstr "Isto está ok? (s/N) " #, c-format msgid "weak key created - retrying\n" @@ -5900,233 +5673,227 @@ msgstr "chave fraca criada - tentando novamente\n" #, c-format msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n" msgstr "" -"impossível evitar chave fraca para criptografia simétrica;\n" -"tentei %d vezes!\n" +"não pude evitar a chave fraca para a cifra simétrica; tentei %d vezes!\n" #, c-format msgid "%s key %s uses an unsafe (%zu bit) hash\n" -msgstr "" +msgstr "chave %s %s usa um hash não seguro (%zu bit)\n" #, c-format msgid "%s key %s requires a %zu bit or larger hash (hash is %s)\n" -msgstr "" +msgstr "chave %s %s requer um hash %zu bit ou maior (hash é %s)\n" -#, fuzzy, c-format -#| msgid "you may not use %s while in %s mode\n" +#, c-format msgid "key %s may not be used for signing in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "A chave %s não pode ser usada para assinar no modo %s\n" #, c-format msgid "WARNING: signature digest conflict in message\n" -msgstr "AVISO: conflito no 'digest' de assinatura da mensagem\n" +msgstr "AVISO: conflito no digest de assinatura na mensagem\n" #, c-format msgid "WARNING: signing subkey %s is not cross-certified\n" -msgstr "" +msgstr "AVISO: a subchave de assinatura %s não é cruzadamente certificada\n" -#, fuzzy, c-format +#, c-format msgid "please see %s for more information\n" -msgstr " i = mostrar mais informações\n" +msgstr "consulte %s para mais informações\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: signing subkey %s has an invalid cross-certification\n" -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "" +"AVISO: a subchave de assinatura %s tem uma certificação cruzada inválida\n" -#, fuzzy, c-format +#, c-format msgid "public key %s is %lu second newer than the signature\n" msgid_plural "public key %s is %lu seconds newer than the signature\n" -msgstr[0] "a chave pública %08lX é %lu segundo mais nova que a assinatura\n" -msgstr[1] "a chave pública %08lX é %lu segundo mais nova que a assinatura\n" +msgstr[0] "a chave pública %s é %lu segundo mais recente que a assinatura\n" +msgstr[1] "a chave pública %s é %lu segundos mais recente que a assinatura\n" -#, fuzzy, c-format +#, c-format msgid "public key %s is %lu day newer than the signature\n" msgid_plural "public key %s is %lu days newer than the signature\n" -msgstr[0] "a chave pública %08lX é %lu segundo mais nova que a assinatura\n" -msgstr[1] "a chave pública %08lX é %lu segundo mais nova que a assinatura\n" +msgstr[0] "a chave pública %s é %lu dia mais recente que a assinatura\n" +msgstr[1] "a chave pública %s é %lu dias mais recente que a assinatura\n" -#, fuzzy, c-format +#, c-format msgid "" "key %s was created %lu second in the future (time warp or clock problem)\n" msgid_plural "" "key %s was created %lu seconds in the future (time warp or clock problem)\n" msgstr[0] "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"a chave %s foi criada %lu segundo no futuro (deformação temporal ou problema " +"de relógio)\n" msgstr[1] "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"a chave %s foi criada %lu segundos no futuro (deformação temporal ou " +"problema de relógio)\n" -#, fuzzy, c-format +#, c-format msgid "key %s was created %lu day in the future (time warp or clock problem)\n" msgid_plural "" "key %s was created %lu days in the future (time warp or clock problem)\n" msgstr[0] "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"a chave %s foi criada %lu dia no futuro (deformação temporal ou problema de " +"relógio)\n" msgstr[1] "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"a chave %s foi criada %lu dias no futuro (deformação temporal ou problema de " +"relógio)\n" -#, fuzzy, c-format +#, c-format msgid "Note: signature key %s expired %s\n" -msgstr "NOTA: chave de assinatura %08lx expirou %s\n" +msgstr "Nota: a chave de assinatura %s expirou em %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: signature key %s has been revoked\n" -msgstr "NOTA: a chave foi revogada" +msgstr "Nota: a chave de assinatura %s foi revogada\n" -#, fuzzy, c-format -#| msgid "standalone signature of class 0x%02x\n" +#, c-format msgid "bad key signature from key %s: %s (0x%02x, 0x%x)\n" -msgstr "assinatura de classe 0x%02x\n" +msgstr "assinatura de chave inválida da chave %s: %s (0x%02x, 0x%x)\n" -#, fuzzy, c-format -#| msgid "standalone signature of class 0x%02x\n" +#, c-format msgid "bad data signature from key %s: %s (0x%02x, 0x%x)\n" -msgstr "assinatura de classe 0x%02x\n" +msgstr "assinatura de dados inválida da chave %s: %s (0x%02x, 0x%x)\n" -#, fuzzy, c-format +#, c-format msgid "assuming bad signature from key %s due to an unknown critical bit\n" msgstr "" -"assumindo assinatura incorrecta na chave %08lX devido a um bit crítico " +"assumindo assinatura inválida da chave %s devido a um bit crítico " "desconhecido\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no subkey for subkey revocation signature\n" -msgstr "chave %08lX: sem subchave para o pacote revocação de subchave\n" +msgstr "chave %s: nenhuma subchave para assinatura de revogação de subchave\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no subkey for subkey binding signature\n" -msgstr "chave %08lX: sem subchave para ligação de chaves\n" +msgstr "chave %s: nenhuma subchave para assinatura de vinculação de subchave\n" #, c-format msgid "WARNING: unable to %%-expand notation (too large). Using unexpanded.\n" msgstr "" -"AVISO: impossível expandir-%% a url de política (demasiado grande). A " -"utilizar não expandida.\n" +"AVISO: não é possível expandir-%% a notação (demasiado grande). Usando não " +"expandida.\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: unable to %%-expand policy URL (too large). Using unexpanded.\n" msgstr "" -"AVISO: impossível expandir-%% a url de política (demasiado grande).\n" -"A utilizar não expandida.\n" +"AVISO: não é possível %%-expandir a URL da política (muito grande). Usando " +"não expandida.\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: unable to %%-expand preferred keyserver URL (too large). Using " "unexpanded.\n" msgstr "" -"AVISO: impossível expandir-%% a url de política (demasiado grande).\n" -"A utilizar não expandida.\n" +"AVISO: não é possível %%-expandir a URL do servidor de chaves preferencial " +"(muito grande). Usando não expandida.\n" -#, fuzzy, c-format +#, c-format msgid "%s/%s signature from: \"%s\"\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "assinatura %s/%s de: \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n" msgstr "" -"forçar o algoritmo de 'digest' %s (%d) viola as preferências do " +"AVISO: forçar o algoritmo de digest %s (%d) viola as preferências do " "destinatário\n" #, c-format msgid "signing:" -msgstr "a assinar:" +msgstr "assinando:" -#, fuzzy, c-format -#| msgid "%s encryption will be used\n" +#, c-format msgid "%s.%s encryption will be used\n" -msgstr "será utilizada a cifragem %s\n" +msgstr "a cifração %s.%s será usada\n" #, c-format msgid "key is not flagged as insecure - can't use it with the faked RNG!\n" msgstr "" -"a chave não está marcada insegura - impossível usá-la com o RNG falso!\n" +"chave não está marcada como insegura - não pode usá-la com o RNG " +"falsificado!\n" -#, fuzzy, c-format +#, c-format msgid "skipped \"%s\": duplicated\n" -msgstr "ignorado `%s': duplicada\n" +msgstr "ignorado \"%s\": duplicada\n" #, c-format msgid "skipped: secret key already present\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "ignorada: a chave secreta já está presente\n" -#, fuzzy msgid "this is a PGP generated Elgamal key which is not secure for signatures!" msgstr "" -"ignorado `%s': esta é uma chave ElGamal gerada pelo PGP que não é segura " -"para assinaturas!\n" +"esta é uma chave Elgamal gerada por PGP que não é segura para assinaturas!" #, c-format msgid "trust record %lu, type %d: write failed: %s\n" -msgstr "registo de confiança %lu, tipo %d: escrita falhou: %s\n" +msgstr "registo da confiança %lu, tipo %d: falha ao escrever: %s\n" #, c-format msgid "" "# List of assigned trustvalues, created %s\n" "# (Use \"gpg --import-ownertrust\" to restore them)\n" msgstr "" +"# Lista de valores da confiança atribuídos, criado a %s\n" +"# (Usar \"gpg --import-ownertrust\" para restaurá-los)\n" -#, fuzzy, c-format +#, c-format msgid "error in '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro em '%s': %s\n" -#, fuzzy msgid "line too long" -msgstr "frase secreta demasiado longa\n" +msgstr "linha muito longa" msgid "colon missing" -msgstr "" +msgstr "'dois pontos' ausente" -#, fuzzy msgid "invalid fingerprint" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "impressão digital inválida" -#, fuzzy msgid "ownertrust value missing" -msgstr "importar os valores de confiança" +msgstr "valor ownertrust ausente" -#, fuzzy, c-format +#, c-format msgid "error finding trust record in '%s': %s\n" -msgstr "%s: erro ao escrever registo de diretório: %s\n" +msgstr "erro ao localizar registo da confiança em '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "read error in '%s': %s\n" -msgstr "armadura: %s\n" +msgstr "erro de leitura em '%s': %s\n" #, c-format msgid "trustdb: sync failed: %s\n" -msgstr "base de dados de confiança: sincronização falhou: %s\n" +msgstr "trustdb: falha na sincronização: %s\n" -#, fuzzy, c-format +#, c-format msgid "can't create lock for '%s'\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível criar bloqueio para '%s'\n" -#, fuzzy, c-format +#, c-format msgid "can't lock '%s'\n" -msgstr "impossível abrir `%s'\n" +msgstr "não é possível bloquear '%s'\n" #, c-format msgid "trustdb rec %lu: lseek failed: %s\n" -msgstr "base de dados de confiança rec %lu: lseek falhou: %s\n" +msgstr "registo trustdb %lu: falha no lseek: %s\n" #, c-format msgid "trustdb rec %lu: write failed (n=%d): %s\n" -msgstr "base de dados de confiança rec %lu: escrita falhou (n=%d): %s\n" +msgstr "registo trustdb %lu: falha ao escrever (n=%d): %s\n" #, c-format msgid "trustdb transaction too large\n" -msgstr "transação de base de dados de confiança muito grande\n" +msgstr "transação trustdb muito grande\n" #, c-format msgid "%s: directory does not exist!\n" -msgstr "%s: diretoria inexistente!\n" +msgstr "%s: pasta não existe!\n" -#, fuzzy, c-format +#, c-format msgid "can't access '%s': %s\n" -msgstr "impossível fechar `%s': %s\n" +msgstr "não é possível aceder '%s': %s\n" #, c-format msgid "%s: failed to create version record: %s" @@ -6134,28 +5901,27 @@ msgstr "%s: falha ao criar registo de versão: %s" #, c-format msgid "%s: invalid trustdb created\n" -msgstr "%s: base de dados de confiança inválida criada\n" +msgstr "%s: trustdb inválida criada\n" #, c-format msgid "%s: trustdb created\n" -msgstr "%s: base de dados de confiança criada\n" +msgstr "%s: trustdb criada\n" -#, fuzzy, c-format -#| msgid "NOTE: trustdb not writable\n" +#, c-format msgid "Note: trustdb not writable\n" -msgstr "NOTA: não é possível escrever na trustdb\n" +msgstr "Nota: trustdb sem permissão de escrita\n" #, c-format msgid "%s: invalid trustdb\n" -msgstr "%s: base de dados de confiança inválida\n" +msgstr "%s: trustdb inválida\n" #, c-format msgid "%s: failed to create hashtable: %s\n" -msgstr "%s: falha ao criar tabela de dispersão: %s\n" +msgstr "%s: falha ao criar hashtable: %s\n" #, c-format msgid "%s: error updating version record: %s\n" -msgstr "%s: erro a actualizar registo de versão: %s\n" +msgstr "%s: erro ao atualizar registo de versão: %s\n" #, c-format msgid "%s: error reading version record: %s\n" @@ -6167,15 +5933,15 @@ msgstr "%s: erro ao escrever registo de versão: %s\n" #, c-format msgid "trustdb: lseek failed: %s\n" -msgstr "base de dados de confiança: lseek falhou: %s\n" +msgstr "trustdb: falha no lseek: %s\n" #, c-format msgid "trustdb: read failed (n=%d): %s\n" -msgstr "base de dados de confiança: leitura falhou (n=%d): %s\n" +msgstr "trustdb: falha ao ler (n=%d): %s\n" #, c-format msgid "%s: not a trustdb file\n" -msgstr "%s: não é um base de dados de confiança\n" +msgstr "%s: não é um ficheiro trustdb\n" #, c-format msgid "%s: version record with recnum %lu\n" @@ -6191,7 +5957,7 @@ msgstr "%s: erro ao ler registo livre: %s\n" #, c-format msgid "%s: error writing dir record: %s\n" -msgstr "%s: erro ao escrever registo de diretório: %s\n" +msgstr "%s: erro ao escrever registo de pasta: %s\n" #, c-format msgid "%s: failed to zero a record: %s\n" @@ -6199,288 +5965,287 @@ msgstr "%s: falha ao zerar um registo: %s\n" #, c-format msgid "%s: failed to append a record: %s\n" -msgstr "%s: falha ao anexar um registo: %s\n" +msgstr "%s: falha ao acrescentar um registo: %s\n" -#, fuzzy, c-format +#, c-format msgid "Error: The trustdb is corrupted.\n" -msgstr "%s: base de dados de confiança criada\n" +msgstr "Erro: A trustdb está corrompida.\n" #, c-format msgid "can't handle text lines longer than %d characters\n" -msgstr "impossível manipular linhas de texto maiores que %d caracteres\n" +msgstr "não é possível lidar com linhas de texto maiores que %d caracteres\n" #, c-format msgid "input line longer than %d characters\n" msgstr "linha de entrada maior que %d caracteres\n" -#, fuzzy, c-format +#, c-format msgid "error beginning transaction on TOFU database: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao iniciar a transação na base de dados TOFU: %s\n" #, c-format msgid "error committing transaction on TOFU database: %s\n" -msgstr "" +msgstr "erro ao confirmar transação na base de dados TOFU: %s\n" #, c-format msgid "error rolling back transaction on TOFU database: %s\n" -msgstr "" +msgstr "erro ao reverter transação na base de dados TOFU: %s\n" -#, fuzzy, c-format +#, c-format msgid "unsupported TOFU database version: %s\n" -msgstr "" -"\n" -"Algoritmos suportados:\n" +msgstr "versão da base de dados TOFU sem suporte: %s\n" #, c-format msgid "TOFU DB error" -msgstr "" +msgstr "erro na base de dados TOFU" -#, fuzzy, c-format +#, c-format msgid "error reading TOFU database: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao ler a base de dados TOFU: %s\n" -#, fuzzy, c-format -#| msgid "error writing secret keyring `%s': %s\n" +#, c-format msgid "error determining TOFU database's version: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao determinar a versão da base de dados TOFU: %s\n" -#, fuzzy, c-format -#| msgid "%s: error writing dir record: %s\n" +#, c-format msgid "error initializing TOFU database: %s\n" -msgstr "%s: erro ao escrever registo de diretório: %s\n" +msgstr "erro ao inicializar a base de dados TOFU: %s\n" -#, fuzzy, c-format +#, c-format msgid "error opening TOFU database '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao abrir a base de dados TOFU '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error updating TOFU database: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao atualizar a base de dados TOFU: %s\n" #, c-format msgid "" "This is the first time the email address \"%s\" is being used with key %s." msgstr "" +"Esta é a primeira vez que o endereço de email \"%s\" está a ser usado com a " +"chave %s." #, c-format msgid "The email address \"%s\" is associated with %d key!" msgid_plural "The email address \"%s\" is associated with %d keys!" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "O endereço de email \"%s\" está associado a %d chave!" +msgstr[1] "O endereço de email \"%s\" está associado a %d chaves!" msgid " Since this binding's policy was 'auto', it has been changed to 'ask'." msgstr "" +" Como a política desta vinculação era 'auto', foi alterada para 'ask'." #, c-format msgid "" "Please indicate whether this email address should be associated with key %s " "or whether you think someone is impersonating \"%s\"." msgstr "" +"Indique se este endereço de email deve ser associado à chave %s ou se acha " +"que alguém está a fazer-se passar por \"%s\"." -#, fuzzy, c-format +#, c-format msgid "error gathering other user IDs: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao colecionar outros IDs de utilizador: %s\n" -#, fuzzy -#| msgid "list key and user IDs" msgid "This key's user IDs:\n" -msgstr "lista chave e identificadores de utilizadores" +msgstr "IDs de utilizador desta chave:\n" -#, fuzzy, c-format -#| msgid "Policy: " +#, c-format msgid "policy: %s" -msgstr "Política: " +msgstr "política: %s" -#, fuzzy, c-format +#, c-format msgid "error gathering signature stats: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao colecionar estatísticas de assinatura: %s\n" #, c-format msgid "The email address \"%s\" is associated with %d key:\n" msgid_plural "The email address \"%s\" is associated with %d keys:\n" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "O endereço de email \"%s\" está associado à chave %d:\n" +msgstr[1] "O endereço de email \"%s\" está associado às chaves %d:\n" #, c-format msgid "Statistics for keys with the email address \"%s\":\n" -msgstr "" +msgstr "Estatísticas para chaves com o endereço de email \"%s\":\n" -#, fuzzy -#| msgid "list keys" msgid "this key" -msgstr "listar as chaves" +msgstr "esta chave" -#, fuzzy, c-format +#, c-format msgid "Verified %d message." msgid_plural "Verified %d messages." -msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr[0] "Verifiquei %d mensagem." +msgstr[1] "Verifiquei %d mensagens." -#, fuzzy, c-format +#, c-format msgid "Encrypted %d message." msgid_plural "Encrypted %d messages." -msgstr[0] "Repita a frase secreta\n" -msgstr[1] "Repita a frase secreta\n" +msgstr[0] "Cifrei %d mensagem." +msgstr[1] "Cifrei %d mensagens." -#, fuzzy, c-format +#, c-format msgid "Verified %d message in the future." msgid_plural "Verified %d messages in the future." -msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr[0] "Verifiquei %d mensagem no futuro." +msgstr[1] "Verifiquei %d mensagens no futuro." -#, fuzzy, c-format +#, c-format msgid "Encrypted %d message in the future." msgid_plural "Encrypted %d messages in the future." -msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr[0] "Cifrei %d mensagem no futuro." +msgstr[1] "Cifrei %d mensagens no futuro." #, c-format msgid "Messages verified over the past %d day: %d." msgid_plural "Messages verified over the past %d days: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens verificadas no último %d dia: %d." +msgstr[1] "Mensagens verificadas nos últimos %d dias: %d." #, c-format msgid "Messages encrypted over the past %d day: %d." msgid_plural "Messages encrypted over the past %d days: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens cifradas no último %d dia: %d." +msgstr[1] "Mensagens cifradas nos últimos %d dias: %d." #, c-format msgid "Messages verified over the past %d month: %d." msgid_plural "Messages verified over the past %d months: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens verificadas no último %d mês: %d." +msgstr[1] "Mensagens verificadas nos últimos %d meses: %d." #, c-format msgid "Messages encrypted over the past %d month: %d." msgid_plural "Messages encrypted over the past %d months: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens cifradas no último %d mês: %d." +msgstr[1] "Mensagens cifradas nos últimos %d meses: %d." #, c-format msgid "Messages verified over the past %d year: %d." msgid_plural "Messages verified over the past %d years: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens verificadas no último %d ano: %d." +msgstr[1] "Mensagens verificadas nos últimos %d anos: %d." #, c-format msgid "Messages encrypted over the past %d year: %d." msgid_plural "Messages encrypted over the past %d years: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens cifradas no último %d ano: %d." +msgstr[1] "Mensagens cifradas nos últimos %d anos: %d." #, c-format msgid "Messages verified in the past: %d." -msgstr "" +msgstr "Mensagens verificadas no passado: %d." -#, fuzzy, c-format +#, c-format msgid "Messages encrypted in the past: %d." -msgstr "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr "Mensagens cifradas no passado: %d." #. TRANSLATORS: Please translate the text found in the source #. * file below. We don't directly internationalize that text so #. * that we can tweak it without breaking translations. msgid "TOFU detected a binding conflict" -msgstr "" +msgstr "O TOFU detetou um conflito de vinculação" #. TRANSLATORS: Two letters (normally the lower and upper case #. * version of the hotkey) for each of the five choices. If #. * there is only one choice in your language, repeat it. msgid "gGaAuUrRbB" -msgstr "" +msgstr "cCaAdDrRiI" msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? " msgstr "" +"(C)orreta, (A)ceitar uma vez, (D)esconhecida, (R)ejeitar uma vez, " +"(I)ncorreta? " msgid "Defaulting to unknown.\n" -msgstr "" +msgstr "Pré-definindo como desconhecido.\n" #, c-format msgid "TOFU db corruption detected.\n" -msgstr "" +msgstr "corrupção de base de dados TOFU detetada.\n" -#, fuzzy, c-format +#, c-format msgid "error changing TOFU policy: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao alterar a política de TOFU: %s\n" #, c-format msgid "%lld~year" msgid_plural "%lld~years" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~ano" +msgstr[1] "%lld~anos" #, c-format msgid "%lld~month" msgid_plural "%lld~months" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~mês" +msgstr[1] "%lld~meses" #, c-format msgid "%lld~week" msgid_plural "%lld~weeks" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~semana" +msgstr[1] "%lld~semanas" #, c-format msgid "%lld~day" msgid_plural "%lld~days" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~dia" +msgstr[1] "%lld~dias" #, c-format msgid "%lld~hour" msgid_plural "%lld~hours" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~hora" +msgstr[1] "%lld~horas" #, c-format msgid "%lld~minute" msgid_plural "%lld~minutes" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~minuto" +msgstr[1] "%lld~minutos" #, c-format msgid "%lld~second" msgid_plural "%lld~seconds" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~segundo" +msgstr[1] "%lld~segundos" #, c-format msgid "%s: Verified 0~signatures and encrypted 0~messages." -msgstr "" +msgstr "%s: 0~assinaturas verificadas e 0~mensagens cifradas." -#, fuzzy, c-format -#| msgid "Deleted %d signatures.\n" +#, c-format msgid "%s: Verified 0 signatures." -msgstr "%d assinaturas removidas.\n" +msgstr "%s: Verificado 0 assinaturas." -#, fuzzy msgid "Encrypted 0 messages." -msgstr "Repita a frase secreta\n" +msgstr "Cifrado 0 mensagens." -#, fuzzy, c-format -#| msgid "Policy: " +#, c-format msgid "(policy: %s)" -msgstr "Política: " +msgstr "(política: %s)" #, c-format msgid "" "Warning: we have yet to see a message signed using this key and user id!\n" msgstr "" +"Atenção: ainda não vimos uma mensagem assinada com esta chave e ID de " +"utilizador!\n" #, c-format msgid "" "Warning: we've only seen one message signed using this key and user id!\n" msgstr "" +"Atenção: apenas vimos uma mensagem assinada com esta chave e ID de " +"utilizador!\n" #, c-format msgid "Warning: you have yet to encrypt a message to this key!\n" -msgstr "" +msgstr "Atenção: você ainda não cifrou uma mensagem para esta chave!\n" #, c-format msgid "Warning: you have only encrypted one message to this key!\n" -msgstr "" +msgstr "Atenção: você apenas cifrou uma mensagem para esta chave!\n" #, c-format msgid "" @@ -6496,136 +6261,153 @@ msgid_plural "" " %s\n" "to mark it as being bad.\n" msgstr[0] "" +"Atenção: se acha que viu mais assinaturas feitas por esta chave e este ID de " +"utilizador, então esta chave pode ser uma falsificação! Examine " +"cuidadosamente o endereço de email à procura de de pequenas variações. Se a " +"chave for suspeita, use\n" +" %s\n" +"para marcá-la como sendo inválida.\n" msgstr[1] "" +"Atenção: se acha que viu mais assinaturas feitas por esta chave e estes IDs " +"de utilizador, então esta chave pode ser uma falsificação! Examine " +"cuidadosamente os endereços de email à procura de de pequenas variações. Se " +"a chave for suspeita, use\n" +" %s\n" +"para marcá-la como sendo inválida.\n" -#, fuzzy, c-format +#, c-format msgid "error opening TOFU database: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao abrir a base de dados TOFU: %s\n" #, c-format msgid "WARNING: Encrypting to %s, which has no non-revoked user ids\n" -msgstr "" +msgstr "AVISO: Cifrando para %s, que não tem ids de utilizador não revogados\n" -#, fuzzy, c-format -#| msgid "`%s' is not a valid long keyID\n" +#, c-format msgid "'%s' is not a valid long keyID\n" -msgstr "`%s' não é um identificador longo de chave válido\n" +msgstr "'%s' não é um keyID longo válido\n" -#, fuzzy, c-format +#, c-format msgid "key %s: accepted as trusted key\n" -msgstr "chave %08lX: aceite como chave de confiança\n" +msgstr "chave %s: aceite como chave confiável\n" -#, fuzzy, c-format +#, c-format msgid "key %s occurs more than once in the trustdb\n" -msgstr "chave %08lX ocrreu mais do que uma vez na base de dados de confiança\n" +msgstr "a chave %s ocorre mais de uma vez na trustdb\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no public key for trusted key - skipped\n" -msgstr "" -"chave %08lX: nenhuma chave pública para chave de confiança - ignorada\n" -"\n" +msgstr "chave %s: nenhuma chave pública para a chave confiável - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s marked as ultimately trusted\n" -msgstr "chave marcada como de confiança absoluta\n" +msgstr "chave %s marcada como plenamente confiável\n" #, c-format msgid "trust record %lu, req type %d: read failed: %s\n" -msgstr "registo de confiança %lu, tipo req %d: falha na leitura: %s\n" +msgstr "registo da confiança %lu, tipo pedido %d: falha na leitura: %s\n" #, c-format msgid "trust record %lu is not of requested type %d\n" -msgstr "registo de confiança %lu não é do tipo pedido %d\n" +msgstr "registo da confiança %lu não é do tipo %d pedido\n" #, c-format msgid "You may try to re-create the trustdb using the commands:\n" -msgstr "" +msgstr "Você pode tentar recriar a trustdb usando os comandos:\n" #, c-format msgid "If that does not work, please consult the manual\n" -msgstr "" +msgstr "Se isso não funcionar, consulte o manual\n" #, c-format msgid "unable to use unknown trust model (%d) - assuming %s trust model\n" msgstr "" +"não é possível usar modelo da confiança desconhecido (%d) - assumindo o " +"modelo da confiança %s\n" #, c-format msgid "using %s trust model\n" -msgstr "" +msgstr "usando o modelo da confiança %s\n" #, c-format msgid "no need for a trustdb check\n" -msgstr "não é necessária uma verificação da base de dados de confiança\n" +msgstr "não há necessidade de uma verificação da trustdb\n" #, c-format msgid "next trustdb check due at %s\n" -msgstr "proxima verificação da base de dados de confiança a %s\n" +msgstr "próxima verificação da trustdb a %s\n" -#, fuzzy, c-format +#, c-format msgid "no need for a trustdb check with '%s' trust model\n" -msgstr "não é necessária uma verificação da base de dados de confiança\n" +msgstr "" +"não há necessidade de uma verificação da trustdb, com o modelo da confiança " +"'%s'\n" -#, fuzzy, c-format +#, c-format msgid "no need for a trustdb update with '%s' trust model\n" -msgstr "não é necessária uma verificação da base de dados de confiança\n" +msgstr "" +"não há necessidade de uma atualização da trustdb, com o modelo da confiança " +"'%s'\n" -#, fuzzy, c-format +#, c-format msgid "public key %s not found: %s\n" -msgstr "chave pública %08lX não encontrada: %s\n" +msgstr "chave pública %s não encontrada: %s\n" #, c-format msgid "please do a --check-trustdb\n" -msgstr "" +msgstr "faça uma --check-trustdb\n" #, c-format msgid "checking the trustdb\n" -msgstr "a verificar a base de dados de confiança\n" +msgstr "verificando a trustdb\n" -#, fuzzy, c-format +#, c-format msgid "%d key processed" msgid_plural "%d keys processed" -msgstr[0] "%lu chaves processadas até agora\n" -msgstr[1] "%lu chaves processadas até agora\n" +msgstr[0] "%d chave processada" +msgstr[1] "%d chaves processadas" #, c-format msgid " (%d validity count cleared)\n" msgid_plural " (%d validity counts cleared)\n" -msgstr[0] "" -msgstr[1] "" +msgstr[0] " (%d contagem da validade limpa)\n" +msgstr[1] " (%d contagens das validades limpas)\n" -#, fuzzy, c-format +#, c-format msgid "no ultimately trusted keys found\n" -msgstr "" -"chave pública da chave absolutamente de confiança %08lX não encontrada\n" +msgstr "nenhumas chaves plenamente confiáveis encontradas\n" -#, fuzzy, c-format +#, c-format msgid "public key of ultimately trusted key %s not found\n" -msgstr "" -"chave pública da chave absolutamente de confiança %08lX não encontrada\n" +msgstr "chave pública da chave plenamente confiável %s não encontrada\n" #, c-format msgid "" "depth: %d valid: %3d signed: %3d trust: %d-, %dq, %dn, %dm, %df, %du\n" msgstr "" +"profundidade: %d válidas: %3d assinadas: %3d confiáveis: %d-, %di, %dn, %dm, " +"%dc, %dp\n" -#, fuzzy, c-format +#, c-format msgid "unable to update trustdb version record: write failed: %s\n" -msgstr "registo de confiança %lu, tipo %d: escrita falhou: %s\n" +msgstr "" +"não é possível atualizar o registo de versão da trustdb: falha ao escrever: " +"%s\n" msgid "undefined" -msgstr "" +msgstr "indefinida" msgid "never" -msgstr "" +msgstr "nunca" msgid "marginal" -msgstr "" +msgstr "marginal" msgid "full" -msgstr "" +msgstr "completa" msgid "ultimate" -msgstr "" +msgstr "plena" #. TRANSLATORS: these strings are similar to those in #. trust_value_to_string(), but are a fixed length. This is needed to @@ -6636,34 +6418,31 @@ msgstr "" #. essentially a comment and need not be translated. Either key and #. uid are both NULL, or neither are NULL. msgid "10 translator see trust.c:uid_trust_string_fixed" -msgstr "" +msgstr "12 translator see trust.c:uid_trust_string_fixed" -#, fuzzy msgid "[ revoked]" -msgstr "revkey" +msgstr "[ revogada ]" -#, fuzzy msgid "[ expired]" -msgstr "expire" +msgstr "[ expirada ]" -#, fuzzy msgid "[ unknown]" -msgstr "versão desconhecida" +msgstr "[desconhec.]" msgid "[ undef ]" -msgstr "" +msgstr "[indefinida]" msgid "[ never ]" -msgstr "" +msgstr "[ nunca ]" msgid "[marginal]" -msgstr "" +msgstr "[ marginal ]" msgid "[ full ]" -msgstr "" +msgstr "[ completa ]" msgid "[ultimate]" -msgstr "" +msgstr "[ plena ]" #, c-format msgid "" @@ -6672,665 +6451,643 @@ msgid "" "should be the first file given on the command line.\n" msgstr "" "a assinatura não pode ser verificada.\n" -"Não se esqueça que o ficheiro com a assinatura (.sig ou .asc)\n" -"deve ser o primeiro a ser dado na linha de comando.\n" +"Lembre-se que o ficheiro com a assinatura (.sig ou .asc)\n" +"deve ser o primeiro ficheiro a ser dado na linha de comando.\n" #, c-format msgid "input line %u too long or missing LF\n" -msgstr "linha de entrada %u demasiado longa ou falta o LF\n" +msgstr "linha de entrada %u demasiado longa ou LF ausente\n" -#, fuzzy, c-format +#, c-format msgid "can't open fd %d: %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "não é possível abrir fd %d: %s\n" -#, fuzzy, c-format -#| msgid "WARNING: message was not integrity protected\n" +#, c-format msgid "WARNING: encrypting without integrity protection is dangerous\n" -msgstr "AVISO: a mensagem não tinha a sua integridade protegida\n" +msgstr "AVISO: cifrar sem proteção de integridade é perigoso\n" -#, fuzzy, c-format +#, c-format msgid "Hint: Do not use option %s\n" -msgstr "a ler opções de `%s'\n" +msgstr "Dica: Não use a opção %s\n" msgid "set debugging flags" -msgstr "" +msgstr "definindo flags de debug" msgid "enable full debugging" -msgstr "" +msgstr "habilitando debug completo" -#, fuzzy msgid "Usage: kbxutil [options] [files] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: kbxutil [opções] [ficheiros] (-h para ajuda)" -#, fuzzy msgid "" "Syntax: kbxutil [options] [files]\n" "List, export, import Keybox data\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "" +"Sintaxe: kbxutil [opções] [ficheiros]\n" +"Listar, exportar, importar dados da Keybox\n" #. TRANSLATORS: Put a \x1f right before a colon. This can be #. * used by pinentry to nicely align the names and values. Keep #. * the %s at the start and end of the string. #, c-format msgid "%sNumber: %s%%0AHolder: %s%s" -msgstr "" +msgstr "%sNúmero: %s%%0ATitular: %s%s" #. TRANSLATORS: This is the number of remaining attempts to #. * enter a PIN. Use %%0A (double-percent,0A) for a linefeed. #, c-format msgid "Remaining attempts: %d" -msgstr "" +msgstr "Tentativas restantes: %d" -#, fuzzy msgid "|N|Please enter the new Global-PIN" -msgstr "muda a frase secreta" +msgstr "|N|Introduza o novo Global-PIN" -#, fuzzy msgid "||Please enter the Global-PIN of your PIV card" -msgstr "motivo da revocação: " +msgstr "||Introduza o Global-PIN do seu cartão PIV" -#, fuzzy msgid "|N|Please enter the new PIN" -msgstr "muda a frase secreta" +msgstr "|N|Introduza o novo PIN" -#, fuzzy msgid "||Please enter the PIN of your PIV card" -msgstr "motivo da revocação: " +msgstr "||Introduza o PIN do seu cartão PIV" -#, fuzzy msgid "|N|Please enter the new Unblocking Key" -msgstr "muda a frase secreta" +msgstr "|N|Introduza a nova Unblocking Key" -#, fuzzy msgid "||Please enter the Unblocking Key of your PIV card" -msgstr "motivo da revocação: " +msgstr "||Introduza a Unblocking Key do seu cartão PIV" #, c-format msgid "PIN callback returned error: %s\n" -msgstr "" +msgstr "callback de PIN retornou erro: %s\n" #, c-format msgid "PIN is too short; minimum length is %d\n" -msgstr "" +msgstr "O PIN é muito curto; o comprimento mínimo é %d\n" #, c-format msgid "PIN is too long; maximum length is %d\n" -msgstr "" +msgstr "O PIN é muito longo; o comprimento máximo é %d\n" #, c-format msgid "PIN has invalid characters; only digits are allowed\n" -msgstr "" +msgstr "O PIN tem caracteres inválidos; apenas dígitos são permitidos\n" -#, fuzzy, c-format +#, c-format msgid "key already exists\n" -msgstr "%s' já comprimido\n" +msgstr "chave já existe\n" #, c-format msgid "existing key will be replaced\n" -msgstr "" +msgstr "a chave existente será substituída\n" -#, fuzzy, c-format +#, c-format msgid "generating new key\n" -msgstr "gerar um novo par de chaves" +msgstr "gerando nova chave\n" -#, fuzzy, c-format +#, c-format msgid "writing new key\n" -msgstr "gerar um novo par de chaves" +msgstr "escrevendo nova chave\n" -#, fuzzy, c-format +#, c-format msgid "failed to store the key: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao armazenar a chave: %s\n" #, c-format msgid "response does not contain the RSA modulus\n" -msgstr "" +msgstr "resposta não contém o módulo de RSA\n" #, c-format msgid "response does not contain the RSA public exponent\n" -msgstr "" +msgstr "resposta não contém o expoente público de RSA\n" -#, fuzzy, c-format -#| msgid "remove keys from the public keyring" +#, c-format msgid "response does not contain the EC public key\n" -msgstr "remover chaves do porta-chaves público" +msgstr "resposta não contém a chave pública de EC\n" #, c-format msgid "please wait while key is being generated ...\n" -msgstr "" +msgstr "aguarde enquanto a chave está a ser gerada ...\n" -#, fuzzy, c-format +#, c-format msgid "generating key failed\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao gerar chave\n" -#, fuzzy, c-format +#, c-format msgid "key generation completed (%d second)\n" msgid_plural "key generation completed (%d seconds)\n" -msgstr[0] "A geração de chaves falhou: %s\n" -msgstr[1] "A geração de chaves falhou: %s\n" +msgstr[0] "geração de chave concluída (%d segundo)\n" +msgstr[1] "geração de chave concluída (%d segundos)\n" #, c-format msgid "response does not contain the public key data\n" -msgstr "" +msgstr "a resposta não contém os dados da chave pública\n" msgid "||Please enter the PIN for the key to create qualified signatures." -msgstr "" +msgstr "||Introduza o PIN da chave para criar assinaturas qualificadas." #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at #. the start of the string. Use %0A (single percent) for a linefeed. -#, fuzzy msgid "|A|Please enter the Admin PIN" -msgstr "muda a frase secreta" +msgstr "|A|Introduza o PIN do Admin" -#, fuzzy msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys." -msgstr "motivo da revocação: " +msgstr "|P|Introduza o PIN Unblocking Code (PUK) para as chaves padrão." -#, fuzzy msgid "||Please enter the PIN for the standard keys." -msgstr "muda a frase secreta" +msgstr "||Introduza o PIN das chaves padrão." #, c-format msgid "RSA modulus missing or not of size %d bits\n" -msgstr "" +msgstr "Módulo de RSA ausente ou não tem o tamanho de %d bits\n" #, c-format msgid "RSA public exponent missing or larger than %d bits\n" -msgstr "" +msgstr "Expoente público de RSA ausente ou maior que %d bits\n" -#, fuzzy -#| msgid "Note: This key has been disabled.\n" msgid "Note: PIN has not yet been enabled." -msgstr "Nota: Esta chave foi desactivada.\n" +msgstr "Nota: o PIN ainda não foi habilitado." #, c-format msgid "the NullPIN has not yet been changed\n" -msgstr "" +msgstr "o NullPIN ainda não foi alterado\n" -#, fuzzy msgid "|N|Please enter a new PIN for the standard keys." -msgstr "muda a frase secreta" +msgstr "|N|Introduza um novo PIN para as chaves padrão." -#, fuzzy msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys." -msgstr "motivo da revocação: " +msgstr "" +"|NP|Introduza um novo PIN Unblocking Code (PUK) para as chaves padrão. " msgid "|N|Please enter a new PIN for the key to create qualified signatures." -msgstr "" +msgstr "|N|Introduza um novo PIN para a chave criar assinaturas qualificadas." msgid "" "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create " "qualified signatures." msgstr "" +"|NP|Introduza um novo PIN Unblocking Code (PUK) para a chave criar " +"assinaturas qualificadas." msgid "" "|P|Please enter the PIN Unblocking Code (PUK) for the key to create " "qualified signatures." msgstr "" +"|P|Introduza o PIN Unblocking Code (PUK) para a chave criar assinaturas " +"qualificadas." -#, fuzzy, c-format +#, c-format msgid "error getting new PIN: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter novo PIN: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to store the fingerprint: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao armazenar a impressão digital: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to store the creation date: %s\n" -msgstr "falha ao criar 'cache' do porta-chaves: %s\n" +msgstr "falha ao armazenar a data de criação: %s\n" #, c-format msgid "error retrieving CHV status from card\n" -msgstr "" +msgstr "erro ao obter o status CHV do cartão\n" -#, fuzzy, c-format +#, c-format msgid "reading public key failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao ler a chave pública: %s\n" #. TRANSLATORS: Put a \x1f right before a colon. This can be #. * used by pinentry to nicely align the names and values. Keep #. * the %s at the start and end of the string. #, c-format msgid "%sNumber: %s%%0AHolder: %s%%0ACounter: %lu%s" -msgstr "" +msgstr "%sNúmero: %s%%0ATitular: %s%%0AContador: %lu%s" #, c-format msgid "using default PIN as %s\n" -msgstr "" +msgstr "usando o PIN pré-definido como %s\n" #, c-format msgid "failed to use default PIN as %s: %s - disabling further default use\n" msgstr "" +"falha ao usar o PIN pré-definido como %s: %s - desabilitando um uso pré-" +"definido adicional\n" -#, fuzzy msgid "||Please unlock the card" -msgstr "muda a frase secreta" +msgstr "||Desbloqueie o cartão" #, c-format msgid "PIN for CHV%d is too short; minimum length is %d\n" -msgstr "" +msgstr "O PIN para CHV%d é muito curto; o comprimento mínimo é %d\n" -#, fuzzy, c-format +#, c-format msgid "verify CHV%d failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "verificar CHV%d falhou: %s\n" #, c-format msgid "card is permanently locked!\n" -msgstr "" +msgstr "cartão está permanentemente bloqueado!\n" #, c-format msgid "%d Admin PIN attempt remaining before card is permanently locked\n" msgid_plural "" "%d Admin PIN attempts remaining before card is permanently locked\n" msgstr[0] "" +"%d tentativa de PIN do Admin restante antes de o cartão ser permanentemente " +"bloqueado\n" msgstr[1] "" +"%d tentativas de PIN do Admin restantes antes de o cartão ser " +"permanentemente bloqueado\n" #, c-format msgid "access to admin commands is not configured\n" -msgstr "" +msgstr "o acesso aos comandos admin não está configurado\n" -#, fuzzy msgid "||Please enter the PIN" -msgstr "muda a frase secreta" +msgstr "||Introduza o PIN" -#, fuzzy msgid "||Please enter the Reset Code for the card" -msgstr "motivo da revocação: " +msgstr "||Introduza o Código de Reset do cartão" #, c-format msgid "Reset Code is too short; minimum length is %d\n" -msgstr "" +msgstr "O Código de Reset é muito curto; o comprimento mínimo é %d\n" #. TRANSLATORS: Do not translate the "|*|" prefixes but #. keep it at the start of the string. We need this elsewhere #. to get some infos on the string. msgid "|RN|New Reset Code" -msgstr "" +msgstr "|RN|Novo Código de Reset" msgid "|AN|New Admin PIN" -msgstr "" +msgstr "|AN|Novo PIN do Admin" msgid "|N|New PIN" -msgstr "" +msgstr "|N|Novo PIN" -#, fuzzy msgid "||Please enter the Admin PIN and New Admin PIN" -msgstr "muda a frase secreta" +msgstr "||Introduza o PIN do Admin e o Novo PIN do Admin" -#, fuzzy msgid "||Please enter the PIN and New PIN" -msgstr "muda a frase secreta" +msgstr "||Introduza o PIN e o Novo PIN" -#, fuzzy, c-format +#, c-format msgid "error reading application data\n" -msgstr "erro na leitura do bloco de chave: %s\n" +msgstr "erro ao ler dados da aplicação\n" -#, fuzzy, c-format +#, c-format msgid "error reading fingerprint DO\n" -msgstr "%s: erro ao ler registo livre: %s\n" +msgstr "erro ao ler impressão digital DO\n" #, c-format msgid "creation timestamp missing\n" -msgstr "" +msgstr "timestamp de criação ausente\n" #, c-format msgid "RSA prime %s missing or not of size %d bits\n" -msgstr "" +msgstr "primo %s de RSA ausente ou não tem o tamanho de %d bits\n" -#, fuzzy, c-format -#| msgid "unsupported URI" +#, c-format msgid "unsupported curve\n" -msgstr "URI não suportado" +msgstr "sem suporte à curva\n" #, c-format msgid "invalid structure of OpenPGP card (DO 0x93)\n" -msgstr "" +msgstr "estrutura inválida do cartão OpenPGP (DO 0x93)\n" #, c-format msgid "fingerprint on card does not match requested one\n" -msgstr "" +msgstr "impressão digital no cartão não corresponde à pedida\n" -#, fuzzy, c-format +#, c-format msgid "card does not support digest algorithm %s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "cartão não suporta algoritmo digest %s\n" #, c-format msgid "signatures created so far: %lu\n" -msgstr "" +msgstr "assinaturas criadas até agora: %lu\n" #, c-format msgid "" "verification of Admin PIN is currently prohibited through this command\n" msgstr "" +"a verificação do PIN do Admin é atualmente proibida através deste comando\n" -#, fuzzy, c-format +#, c-format msgid "can't access %s - invalid OpenPGP card?\n" -msgstr "nenhum dado OpenPGP válido encontrado.\n" +msgstr "incapaz aceder %s - cartão OpenPGP inválido?\n" -#, fuzzy msgid "||Please enter your PIN at the reader's pinpad" -msgstr "muda a frase secreta" +msgstr "||Introduza o seu PIN no pinpad do leitor" #. TRANSLATORS: Do not translate the "|*|" prefixes but #. keep it at the start of the string. We need this elsewhere #. to get some infos on the string. msgid "|N|Initial New PIN" -msgstr "" +msgstr "|N|Novo PIN Inicial" msgid "run in multi server mode (foreground)" -msgstr "" +msgstr "executar no modo multi server (primeiro plano)" msgid "|LEVEL|set the debugging level to LEVEL" -msgstr "" +msgstr "|LEVEL|definir o nível de debug para LEVEL" -#, fuzzy msgid "|FILE|write a log to FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|escrever um log no FILE" msgid "|N|connect to reader at port N" -msgstr "" +msgstr "|N|conectar ao leitor na porta N" -#, fuzzy msgid "|NAME|use NAME as ct-API driver" -msgstr "|NOME|usar NOME como destinatário por omissão" +msgstr "|NAME|usar NAME como driver ct-API" -#, fuzzy msgid "|NAME|use NAME as PC/SC driver" -msgstr "|NOME|usar NOME como destinatário por omissão" +msgstr "|NAME|usar NAME como driver de PC/SC" -#, fuzzy msgid "do not use the internal CCID driver" -msgstr "nunca usar o terminal" +msgstr "não usar o driver CCID interno" msgid "|N|disconnect the card after N seconds of inactivity" -msgstr "" +msgstr "|N|desconectar o cartão após N segundos de inatividade" msgid "do not use a reader's pinpad" -msgstr "" +msgstr "não usar o pinpad de um leitor" msgid "use variable length input for pinpad" -msgstr "" +msgstr "usar entrada de comprimento variável para o pinpad" msgid "|LIST|change the application priority to LIST" -msgstr "" +msgstr "|LIST|alterar a prioridade da aplicação para LIST" -#, fuzzy msgid "deny the use of admin card commands" -msgstr "comandos em conflito\n" +msgstr "negar o uso de comandos admin do cartão" -#, fuzzy msgid "Usage: @SCDAEMON@ [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @SCDAEMON@ [opções] (-h para ajuda)" msgid "" "Syntax: scdaemon [options] [command [args]]\n" "Smartcard daemon for @GNUPG@\n" msgstr "" +"Sintaxe: scdaemon [opções] [comando [args]]\n" +"Daemon de smartcard para @GNUPG@\n" #, c-format msgid "please use the option '--daemon' to run the program in the background\n" -msgstr "" +msgstr "use a opção '--daemon' para executar o programa em segundo plano\n" #, c-format msgid "handler for fd %d started\n" -msgstr "" +msgstr "handler para fd %d iniciado\n" #, c-format msgid "handler for fd %d terminated\n" -msgstr "" +msgstr "handler para fd %d terminado\n" -#, fuzzy, c-format +#, c-format msgid "error getting key usage information: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao obter informações de utilização da chave: %s\n" msgid "Tor might be in use - network access is limited" -msgstr "" +msgstr "O Tor pode estar em uso - o acesso à rede é limitado" #, c-format msgid "validation model requested by certificate: %s" -msgstr "" +msgstr "modelo de validação pedido pelo certificado: %s" msgid "chain" -msgstr "" +msgstr "corrente" -#, fuzzy msgid "shell" -msgstr "help" +msgstr "shell" -#, fuzzy, c-format +#, c-format msgid "critical certificate extension %s is not supported" -msgstr "a versão %d do protocolo gpg-agent não é suportada\n" +msgstr "extensão de certificado crítico %s não é suportada" #, c-format msgid "issuer certificate is not marked as a CA" -msgstr "" +msgstr "certificado do emissor não está marcado como uma CA" msgid "critical marked policy without configured policies" -msgstr "" +msgstr "política marcada crítica sem políticas configuradas" -#, fuzzy, c-format +#, c-format msgid "failed to open '%s': %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "falha ao abrir '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: non-critical certificate policy not allowed" -msgstr "a escrever chave privada para `%s'\n" +msgstr "Nota: a política de certificado não crítico não é permitida" -#, fuzzy, c-format +#, c-format msgid "certificate policy not allowed" -msgstr "a escrever chave privada para `%s'\n" +msgstr "política de certificado não permitida" -#, fuzzy, c-format +#, c-format msgid "failed to get the fingerprint\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao obter a impressão digital\n" #, c-format msgid "looking up issuer at external location\n" -msgstr "" +msgstr "procurando o emissor no local externo\n" #, c-format msgid "number of issuers matching: %d\n" -msgstr "" +msgstr "número de emissores correspondentes: %d\n" -#, fuzzy, c-format -#| msgid "%s: can't access: %s\n" +#, c-format msgid "can't get authorityInfoAccess: %s\n" -msgstr "%s: impossível aceder: %s\n" +msgstr "não é possível obter authorityInfoAccess: %s\n" #, c-format msgid "looking up issuer from the Dirmngr cache\n" -msgstr "" +msgstr "procurando o emissor a partir da cache do Dirmngr\n" -#, fuzzy, c-format +#, c-format msgid "number of matching certificates: %d\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "número de certificados correspondentes: %d\n" -#, fuzzy, c-format +#, c-format msgid "dirmngr cache-only key lookup failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao procurar por chave apenas na cache do dirmngr: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to allocate keyDB handle\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao alocar handle de keyDB\n" -#, fuzzy msgid "certificate has been revoked" -msgstr "NOTA: a chave foi revogada" +msgstr "o certificado foi revogado" msgid "the status of the certificate is unknown" -msgstr "" +msgstr "o status do certificado é desconhecido" #, c-format msgid "please make sure that the \"dirmngr\" is properly installed\n" -msgstr "" +msgstr "certifique-se de que o \"dirmngr\" está instalado corretamente\n" -#, fuzzy, c-format +#, c-format msgid "checking the CRL failed: %s" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao verificar a CRL: %s" #, c-format msgid "certificate with invalid validity: %s" -msgstr "" +msgstr "certificado com validação inválida: %s" #, c-format msgid "certificate not yet valid" -msgstr "" +msgstr "certificado ainda não está válido" -#, fuzzy msgid "root certificate not yet valid" -msgstr "a escrever chave privada para `%s'\n" +msgstr "certificado raiz ainda não está válido" msgid "intermediate certificate not yet valid" -msgstr "" +msgstr "certificado intermediário ainda não está válido" -#, fuzzy, c-format +#, c-format msgid "certificate has expired" -msgstr "Esta chave expirou!" +msgstr "o certificado expirou" -#, fuzzy msgid "root certificate has expired" -msgstr "Esta chave expirou!" +msgstr "o certificado raiz expirou" -#, fuzzy msgid "intermediate certificate has expired" -msgstr "Esta chave expirou!" +msgstr "o certificado intermediário expirou" #, c-format msgid "required certificate attributes missing: %s%s%s" -msgstr "" +msgstr "atributos de certificado necessários ausentes: %s%s%s" -#, fuzzy msgid "certificate with invalid validity" -msgstr "Esta chave expirou!" +msgstr "certificado com validação inválida" msgid "signature not created during lifetime of certificate" -msgstr "" +msgstr "assinatura não criada durante a vida útil do certificado" msgid "certificate not created during lifetime of issuer" -msgstr "" +msgstr "certificado não criado durante a vida útil do emissor" msgid "intermediate certificate not created during lifetime of issuer" -msgstr "" +msgstr "certificado intermediário não criado durante a vida útil do emissor" -#, fuzzy, c-format +#, c-format msgid " ( signature created at " -msgstr " novas assinaturas: %lu\n" +msgstr " ( assinatura criada em " -#, fuzzy, c-format +#, c-format msgid " (certificate created at " -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr " ( certificado criado em " -#, fuzzy, c-format +#, c-format msgid " (certificate valid from " -msgstr "certificado incorrecto" +msgstr " (certificado válido desde " #, c-format msgid " ( issuer valid from " -msgstr "" +msgstr " ( emissor válido desde " -#, fuzzy, c-format +#, c-format msgid "fingerprint=%s\n" -msgstr "mostra impressão digital" +msgstr "impressão digital=%s\n" #, c-format msgid "root certificate has now been marked as trusted\n" -msgstr "" +msgstr "o certificado raiz foi agora marcado como confiável\n" #, c-format msgid "interactive marking as trusted not enabled in gpg-agent\n" -msgstr "" +msgstr "marcar interativamente como confiável não habilitado no gpg-agent\n" #, c-format msgid "interactive marking as trusted disabled for this session\n" -msgstr "" +msgstr "marcar interativamente como confiável desabilitado para esta sessão\n" msgid "WARNING: creation time of signature not known - assuming current time" msgstr "" +"AVISO: tempo de criação da assinatura não conhecido - supondo a hora atual" -#, fuzzy msgid "no issuer found in certificate" -msgstr "gerar um certificado de revogação" +msgstr "nenhum emissor encontrado no certificado" msgid "self-signed certificate has a BAD signature" -msgstr "" +msgstr "certificado auto-assinado tem uma assinatura INVÁLIDA" #, c-format msgid "root certificate is not marked trusted" -msgstr "" +msgstr "o certificado raiz não está marcado como confiável" -#, fuzzy, c-format +#, c-format msgid "checking the trust list failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao verificar a lista da confiança: %s\n" #, c-format msgid "certificate chain too long\n" -msgstr "" +msgstr "corrente de certificados muito longa\n" #, c-format msgid "issuer certificate not found" -msgstr "" +msgstr "certificado do emissor não encontrado" -#, fuzzy, c-format +#, c-format msgid "certificate has a BAD signature" -msgstr "verificar uma assinatura" +msgstr "certificado tem uma assinatura INVÁLIDA" msgid "found another possible matching CA certificate - trying again" msgstr "" +"encontrado outro certificado de CA que possivelmente corresponde - tentando " +"novamente" #, c-format msgid "certificate chain longer than allowed by CA (%d)" -msgstr "" +msgstr "corrente de certificados maior do que o permitido pela CA (%d)" -#, fuzzy, c-format +#, c-format msgid "certificate is good\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado é válido\n" -#, fuzzy, c-format +#, c-format msgid "intermediate certificate is good\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado intermediário é válido\n" -#, fuzzy, c-format +#, c-format msgid "root certificate is good\n" -msgstr "certificado incorrecto" +msgstr "certificado raiz é válido\n" msgid "switching to chain model" -msgstr "" +msgstr "mudando para o modelo de corrente" #, c-format msgid "validation model used: %s" -msgstr "" +msgstr "modelo de validação usado: %s" #, c-format msgid "a %u bit hash is not valid for a %u bit %s key\n" -msgstr "" +msgstr "um hash de %u bit não é válido para uma chave de %u bit %s\n" -#, fuzzy, c-format +#, c-format msgid "out of core\n" -msgstr "não processado" +msgstr "fora do core\n" #, c-format msgid "(this is the MD2 algorithm)\n" -msgstr "" +msgstr "(este é o algoritmo MD2)\n" -#, fuzzy msgid "none" -msgstr "não" +msgstr "nenhuma" -#, fuzzy msgid "[Error - invalid encoding]" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "[Erro - codificação inválida]" msgid "[Error - out of core]" -msgstr "" +msgstr "[Erro - fora do core]" msgid "[Error - No name]" -msgstr "" +msgstr "[Erro - Sem nome]" -#, fuzzy msgid "[Error - invalid DN]" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "[Erro - DN inválido]" -#, fuzzy, c-format +#, c-format msgid "" "Please enter the passphrase to unlock the secret key for the X.509 " "certificate:\n" @@ -7338,343 +7095,325 @@ msgid "" "S/N %s, ID 0x%08lX,\n" "created %s, expires %s.\n" msgstr "" -"Precisa de uma frase secreta para desbloquear a chave secreta do " -"utilizador:\n" -"\n" -"\"%.*s\"\n" -"chave %u bits %s, ID %08lx, criada %s%s\n" +"Introduza a frase-secreta para desbloquear a chave secreta para o " +"certificado X.509:\n" +"\"%s\"\n" +"S/N %s, ID 0x%08lX,\n" +"criado %s, expira %s.\n" #, c-format msgid "no key usage specified - assuming all usages\n" msgstr "" +"nenhuma utilização da chave especificada - supondo todos as utilizações\n" #, c-format msgid "certificate should not have been used for certification\n" -msgstr "" +msgstr "certificado não deveria ter sido usado para certificação\n" #, c-format msgid "certificate should not have been used for OCSP response signing\n" msgstr "" +"certificado não deveria ter sido usado para assinatura de resposta OCSP\n" #, c-format msgid "certificate should not have been used for encryption\n" -msgstr "" +msgstr "certificado não deveria ter sido usado para a cifração\n" #, c-format msgid "certificate should not have been used for signing\n" -msgstr "" +msgstr "certificado não deveria ter sido usado para a assinatura\n" #, c-format msgid "certificate is not usable for encryption\n" -msgstr "" +msgstr "o certificado não é utilizável para cifração\n" #, c-format msgid "certificate is not usable for signing\n" -msgstr "" +msgstr "o certificado não é utilizável para assinar\n" -#, fuzzy, c-format +#, c-format msgid "looking for another certificate\n" -msgstr "certificado incorrecto" +msgstr "à procura de outro certificado\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid algorithm\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: algoritmo inválido\n" #, c-format msgid "line %d: invalid key length %u (valid are %d to %d)\n" -msgstr "" +msgstr "linha %d: comprimento de chave %u inválido (é válido desde %d a %d)\n" #, c-format msgid "line %d: no subject name given\n" -msgstr "" +msgstr "linha %d: nenhum nome de entidade fornecido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid subject name label '%.*s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: rótulo do nome de entidade '%.*s' inválido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid subject name '%s' at pos %d\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: nome de entidade '%s' inválido no PDV %d\n" -#, fuzzy, c-format +#, c-format msgid "line %d: not a valid email address\n" -msgstr "Endereço eletrónico inválido\n" +msgstr "linha %d: não é um endereço de email válido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid serial number\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: número de série inválido\n" #, c-format msgid "line %d: invalid issuer name label '%.*s'\n" -msgstr "" +msgstr "linha %d: rótulo do nome do emissor '%.*s' inválido\n" #, c-format msgid "line %d: invalid issuer name '%s' at pos %d\n" -msgstr "" +msgstr "linha %d: nome do emissor '%s' inválido no PDV %d\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid date given\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: fornecida data inválida\n" -#, fuzzy, c-format +#, c-format msgid "line %d: error getting signing key by keygrip '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "linha %d: erro ao obter a chave de assinatura pelo keygrip '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid hash algorithm given\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: fornecido algoritmo de hash inválido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid authority-key-id\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: authority-key-id inválido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid subject-key-id\n" -msgstr "chave %08lX: ligação de subchave inválida\n" +msgstr "linha %d: subject-key-id inválido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid extension syntax\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: sintaxe de extensão inválida\n" -#, fuzzy, c-format +#, c-format msgid "line %d: error reading key '%s' from card: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "linha %d: erro ao ler a chave '%s' do cartão: %s\n" -#, fuzzy, c-format +#, c-format msgid "line %d: error getting key by keygrip '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "linha %d: erro ao obter chave por keygrip '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "line %d: key generation failed: %s <%s>\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "linha %d: falha na geração de chaves: %s <%s>\n" msgid "" "To complete this certificate request please enter the passphrase for the key " "you just created once more.\n" msgstr "" +"Para concluir este pedido de certificado, introduza mais uma vez a frase-" +"secreta para a chave que você acabou de criar.\n" -#, fuzzy, c-format +#, c-format msgid " (%d) Existing key\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) Chave existente\n" #, c-format msgid " (%d) Existing key from card\n" -msgstr "" +msgstr " (%d) Chave existente do cartão\n" #, c-format msgid "Possible actions for a %s key:\n" -msgstr "" +msgstr "Ações possíveis para uma chave %s:\n" -#, fuzzy, c-format +#, c-format msgid " (%d) sign, encrypt\n" -msgstr " (%d) RSA (assinatura e cifragem)\n" +msgstr " (%d) assinar, cifrar\n" -#, fuzzy, c-format +#, c-format msgid " (%d) sign\n" -msgstr " (%d) DSA (apenas assinatura)\n" +msgstr " (%d) assinar\n" -#, fuzzy, c-format +#, c-format msgid " (%d) encrypt\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) cifrar\n" msgid "Enter the X.509 subject name: " -msgstr "" +msgstr "Introduzir o nome de entidade X.509: " msgid "No subject name given\n" -msgstr "" +msgstr "Nenhum nome de entidade fornecido\n" -#, fuzzy, c-format +#, c-format msgid "Invalid subject name label '%.*s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "Rótulo do nome de entidade inválido '%.*s'\n" #. TRANSLATORS: The 22 in the second string is the #. length of the first string up to the "%s". Please #. adjust it do the length of your translation. The #. second string is merely passed to atoi so you can #. drop everything after the number. -#, fuzzy, c-format +#, c-format msgid "Invalid subject name '%s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "Nome de entidade inválido '%s'\n" msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty" -msgstr "" +msgstr "27 translator: see certreg-ui.c:gpgsm_gencertreq_tty" -#, fuzzy msgid "Enter email addresses" -msgstr "Endereço de correio eletrónico: " +msgstr "Introduzir os endereços de email" -#, fuzzy msgid " (end with an empty line):\n" -msgstr "" -"\n" -"Insira o identificador do utilizador. Termine com uma linha vazia: " +msgstr " (terminar com uma linha vazia):\n" -#, fuzzy msgid "Enter DNS names" -msgstr "Digite novo nome de ficheiro" +msgstr "Introduzir nomes DNS" -#, fuzzy msgid " (optional; end with an empty line):\n" -msgstr "" -"\n" -"Insira o identificador do utilizador. Termine com uma linha vazia: " +msgstr " (opcional; terminar com uma linha vazia):\n" msgid "Enter URIs" -msgstr "" +msgstr "Introduzir URIs" -#, fuzzy msgid "Create self-signed certificate? (y/N) " -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Criar certificado auto-assinado? (s/N) " msgid "These parameters are used:\n" -msgstr "" +msgstr "São usados estes parâmetros:\n" -#, fuzzy, c-format +#, c-format msgid "error creating temporary file: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar ficheiro temporário: %s\n" msgid "Now creating self-signed certificate. " -msgstr "" +msgstr "Criando agora certificado auto-assinado. " -#, fuzzy msgid "Now creating certificate request. " -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "Criando agora o pedido de certificado. " msgid "This may take a while ...\n" -msgstr "" +msgstr "Isto pode demorar um pouco...\n" msgid "Ready.\n" -msgstr "" +msgstr "Pronto.\n" msgid "Ready. You should now send this request to your CA.\n" -msgstr "" +msgstr "Pronto. Agora você deverá enviar este pedido para sua CA.\n" #, c-format msgid "resource problem: out of core\n" -msgstr "" +msgstr "problema de recurso: fora do core\n" #, c-format msgid "(this is the RC2 algorithm)\n" -msgstr "" +msgstr "(este é o algoritmo RC2)\n" #, c-format msgid "(this does not seem to be an encrypted message)\n" -msgstr "" +msgstr "(esta não parece ser uma mensagem cifrada)\n" -#, fuzzy, c-format +#, c-format msgid "encrypted to %s key %s\n" -msgstr "cifrado com chave %s, ID %08lX\n" +msgstr "cifrado para chave %s %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate '%s' not found: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "certificado '%s' não encontrado: %s\n" -#, fuzzy, c-format +#, c-format msgid "error locking keybox: %s\n" -msgstr "erro na leitura do bloco de chave: %s\n" +msgstr "erro ao bloquear a keybox: %s\n" -#, fuzzy, c-format +#, c-format msgid "duplicated certificate '%s' deleted\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado duplicado '%s' apagado\n" -#, fuzzy, c-format +#, c-format msgid "certificate '%s' deleted\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado '%s' apagado\n" -#, fuzzy, c-format +#, c-format msgid "deleting certificate \"%s\" failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao apagar o certificado \"%s\": %s\n" -#, fuzzy, c-format +#, c-format msgid "no valid recipients given\n" -msgstr "resposta do agente inválida\n" +msgstr "nenhum destinatário válido fornecido\n" -#, fuzzy msgid "list external keys" -msgstr "listar as chaves secretas" +msgstr "listar chaves externas" -#, fuzzy msgid "list certificate chain" -msgstr "certificado incorrecto" +msgstr "listar corrente de certificados" -#, fuzzy msgid "import certificates" -msgstr "certificado incorrecto" +msgstr "importar certificados" -#, fuzzy msgid "export certificates" -msgstr "certificado incorrecto" +msgstr "exportar certificados" msgid "register a smartcard" -msgstr "" +msgstr "registar um smartcard" msgid "pass a command to the dirmngr" -msgstr "" +msgstr "passar um comando para o dirmngr" msgid "invoke gpg-protect-tool" -msgstr "" +msgstr "invocar gpg-protect-tool" msgid "don't use the terminal at all" msgstr "nunca usar o terminal" msgid "|N|number of certificates to include" -msgstr "" +msgstr "|N|número de certificados a incluir" msgid "|FILE|take policy information from FILE" -msgstr "" +msgstr "|FILE|pegar informações de política do FILE" msgid "assume input is in PEM format" -msgstr "" +msgstr "supor que a entrada esteja no formato PEM" msgid "assume input is in base-64 format" -msgstr "" +msgstr "supor que a entrada esteja no formato base-64" msgid "assume input is in binary format" -msgstr "" +msgstr "supor que a entrada esteja em formato binário" -#, fuzzy msgid "create base-64 encoded output" -msgstr "criar saída com armadura ascii" +msgstr "criar saída codificada em base-64" -#, fuzzy msgid "|USER-ID|use USER-ID as default secret key" -msgstr "|NOME|usar NOME como chave secreta por omissão" +msgstr "|USER-ID|usar USER-ID como chave secreta pré-definida" -#, fuzzy msgid "|FILE|add keyring to the list of keyrings" -msgstr "" -"adicionar este porta-chaves\n" -"à lista de porta-chaves" +msgstr "|FILE|adicionar porta-chaves à lista dos porta-chaves" msgid "fetch missing issuer certificates" -msgstr "" +msgstr "buscar certificados de emissor ausentes" -#, fuzzy msgid "|NAME|use encoding NAME for PKCS#12 passphrases" -msgstr "" -"|NOME|usar algoritmo de criptografia NOME para\n" -"frases secretas" +msgstr "|NAME|usar a codificação NAME para frases-secretas PKCS#12" msgid "never consult a CRL" -msgstr "" +msgstr "nunca consultar uma CRL" msgid "do not check CRLs for root certificates" -msgstr "" +msgstr "não verificar CRLs para certificados raiz" msgid "check validity using OCSP" -msgstr "" +msgstr "verificar a validade usando OCSP" msgid "do not check certificate policies" -msgstr "" +msgstr "não verificar políticas de certificado" msgid "|NAME|use cipher algorithm NAME" -msgstr "|NOME|usar algoritmo de criptografia NOME" +msgstr "|NAME|usar algoritmo da cifra NAME" msgid "|NAME|use message digest algorithm NAME" -msgstr "|NOME|usar algoritmo de \"digest\" de mensagens NOME" +msgstr "|NAME|usar algoritmo de digest das mensagens NAME" msgid "batch mode: never ask" -msgstr "modo não-interactivo: nunca perguntar" +msgstr "modo batch: nunca perguntar" msgid "assume yes on most questions" msgstr "assumir sim para a maioria das perguntas" @@ -7682,111 +7421,107 @@ msgstr "assumir sim para a maioria das perguntas" msgid "assume no on most questions" msgstr "assumir não para a maioria das perguntas" -#, fuzzy msgid "|FILE|write an audit log to FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|escrever um log de auditoria no FILE" -#, fuzzy -#| msgid "Usage: gpg [options] [files] (-h for help)" msgid "Usage: @GPGSM@ [options] [files] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPGSM@ [opções] [ficheiros] (-h para ajuda)" -#, fuzzy msgid "" "Syntax: @GPGSM@ [options] [files]\n" "Sign, check, encrypt or decrypt using the S/MIME protocol\n" "Default operation depends on the input data\n" msgstr "" -"Sintaxe: gpg [opções] [ficheiros]\n" -"assina, verifica, cifra ou decifra\n" -"a operação por omissão depende dos dados de entrada\n" +"Sintaxe: @GPGSM@ [opções] [ficheiros]\n" +"Assinar, verificar, cifrar, ou decifrar usando o protocolo S/MIME\n" +"A operação pré-definida depende dos dados de entrada\n" -#, fuzzy, c-format +#, c-format msgid "Note: won't be able to encrypt to '%s': %s\n" -msgstr "impossível ligar a `%s': %s\n" +msgstr "Nota: não será possível cifrar para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "unknown validation model '%s'\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "modelo de validação '%s' desconhecido\n" -#, fuzzy, c-format +#, c-format msgid "importing common certificates '%s'\n" -msgstr "a escrever para `%s'\n" +msgstr "importando certificados comuns '%s'\n" -#, fuzzy, c-format +#, c-format msgid "can't sign using '%s': %s\n" -msgstr "impossível fechar `%s': %s\n" +msgstr "não é possível assinar usando '%s': %s\n" #, c-format msgid "invalid command (there is no implicit command)\n" -msgstr "" +msgstr "comando inválido (não há comando implícito)\n" -#, fuzzy, c-format +#, c-format msgid "total number processed: %lu\n" -msgstr "Número total processado: %lu\n" +msgstr "número total processado: %lu\n" -#, fuzzy, c-format +#, c-format msgid "error storing certificate\n" -msgstr "gerar um certificado de revogação" +msgstr "erro ao armazenar certificado\n" #, c-format msgid "basic certificate checks failed - not imported\n" -msgstr "" +msgstr "falha nas verificações básicas de certificado - não importado\n" -#, fuzzy, c-format +#, c-format msgid "error getting stored flags: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter flags armazenadas: %s\n" -#, fuzzy, c-format +#, c-format msgid "error importing certificate: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao importar certificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading input: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler a entrada: %s\n" -#, fuzzy, c-format +#, c-format msgid "no keyboxd running in this session\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "nenhum keyboxd em execução nesta sessão\n" -#, fuzzy, c-format +#, c-format msgid "error opening key DB: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao abrir keyDB: %s\n" #, c-format msgid "problem looking for existing certificate: %s\n" -msgstr "" +msgstr "problema ao procurar certificado existente: %s\n" -#, fuzzy, c-format +#, c-format msgid "error finding writable keyDB: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao encontrar keyDB com permissão de escrita: %s\n" -#, fuzzy, c-format +#, c-format msgid "error storing certificate: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao armazenar certificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "problem re-searching certificate: %s\n" -msgstr "rev? problema ao verificar revogação: %s\n" +msgstr "problema ao pesquisar novamente o certificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "error storing flags: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao armazenar flags: %s\n" msgid "Error - " -msgstr "" +msgstr "Erro - " #, c-format msgid "GPG_TTY has not been set - using maybe bogus default\n" -msgstr "" +msgstr "GPG_TTY não foi definido - talvez esteja usando falsa pré-definição\n" -#, fuzzy, c-format +#, c-format msgid "invalid formatted fingerprint in '%s', line %d\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "impressão digital formatada está inválida em '%s', linha %d\n" -#, fuzzy, c-format +#, c-format msgid "invalid country code in '%s', line %d\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "código de país está inválido em '%s', linha %d\n" #, c-format msgid "" @@ -7797,12 +7532,20 @@ msgid "" "\n" "%s%sAre you really sure that you want to do this?" msgstr "" +"Você está prestes a criar uma assinatura usando seu certificado:\n" +"\"%s\"\n" +"Isto criará uma assinatura qualificada por lei equiparada a uma assinatura " +"manuscrita.\n" +"\n" +"%s%sTem certeza de que deseja fazer isto?" #, c-format msgid "" "Note, that this software is not officially approved to create or verify such " "signatures.\n" msgstr "" +"Note que este software não é oficialmente aprovado para criar ou verificar " +"tais assinaturas.\n" #, c-format msgid "" @@ -7810,604 +7553,601 @@ msgid "" "\"%s\"\n" "Note, that this certificate will NOT create a qualified signature!" msgstr "" +"Você está prestes a criar uma assinatura usando seu certificado:\n" +"\"%s\"\n" +"Note que este certificado NÃO criará uma assinatura qualificada!" -#, fuzzy, c-format +#, c-format msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "" +"algoritmo de hash %d (%s) para o signatário %d não suportado; usando %s\n" #, c-format msgid "hash algorithm used for signer %d: %s (%s)\n" -msgstr "" +msgstr "algoritmo de hash usado para o signatário %d: %s (%s)\n" -#, fuzzy, c-format +#, c-format msgid "checking for qualified certificate failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha na verificação do certificado qualificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "%s/%s signature using %s key %s\n" -msgstr "Assinatura feita em %.*s usando %s, ID da chave %08lX\n" +msgstr "assinatura %s/%s usando a chave %s %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature made " -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Assinatura feita " #, c-format msgid "[date not given]" -msgstr "" +msgstr "[data não fornecida]" -#, fuzzy, c-format +#, c-format msgid "algorithm:" -msgstr "armadura: %s\n" +msgstr "algoritmo:" #, c-format msgid "" "invalid signature: message digest attribute does not match computed one\n" msgstr "" +"assinatura inválida: o atributo digest da mensagem não corresponde ao " +"computado\n" -#, fuzzy, c-format +#, c-format msgid "Good signature from" -msgstr "Assinatura correcta de \"" +msgstr "Assinatura válida de" -#, fuzzy, c-format +#, c-format msgid " aka" -msgstr " ou \"" +msgstr " aka" -#, fuzzy, c-format +#, c-format msgid "This is a qualified signature\n" -msgstr "" -"\n" -"Isto será uma auto-assinatura.\n" +msgstr "Esta é uma assinatura qualificada\n" -#, fuzzy, c-format +#, c-format msgid "can't initialize certificate cache lock: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "não é possível inicializar o bloqueio da cache de certificados: %s\n" #, c-format msgid "can't acquire read lock on the certificate cache: %s\n" msgstr "" +"não é possível adquirir bloqueio de leitura da cache de certificados: %s\n" #, c-format msgid "can't acquire write lock on the certificate cache: %s\n" msgstr "" +"não é possível adquirir bloqueio de escrita da cache de certificados: %s\n" #, c-format msgid "can't release lock on the certificate cache: %s\n" -msgstr "" +msgstr "não é possível libertar o bloqueio da cache de certificados: %s\n" #, c-format msgid "dropping %u certificates from the cache\n" -msgstr "" +msgstr "descartando %u certificados da cache\n" -#, fuzzy, c-format -#| msgid "can't create `%s': %s\n" +#, c-format msgid "can't parse certificate '%s': %s\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível processar o certificado '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate '%s' already cached\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado '%s' já armazenado em cache\n" -#, fuzzy, c-format +#, c-format msgid "trusted certificate '%s' loaded\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado confiável '%s' carregado\n" -#, fuzzy, c-format +#, c-format msgid "certificate '%s' loaded\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado '%s' carregado\n" -#, fuzzy, c-format +#, c-format msgid " SHA1 fingerprint = %s\n" -msgstr "mostra impressão digital" +msgstr " impressão digital SHA1 = %s\n" msgid " issuer =" -msgstr "" +msgstr " emissor =" msgid " subject =" -msgstr "" +msgstr " entidade =" -#, fuzzy, c-format +#, c-format msgid "error loading certificate '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao carregar o certificado '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "permanently loaded certificates: %u\n" -msgstr "certificado incorrecto" +msgstr " certificados permanentemente carregados: %u\n" -#, fuzzy, c-format +#, c-format msgid " runtime cached certificates: %u\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "certificados de cache em tempo de execução: %u\n" -#, fuzzy, c-format +#, c-format msgid " trusted certificates: %u (%u,%u,%u,%u)\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr " certificados confiáveis: %u (%u,%u,%u,%u)\n" -#, fuzzy, c-format +#, c-format msgid "certificate already cached\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado já em cache\n" -#, fuzzy, c-format +#, c-format msgid "certificate cached\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado armazenado em cache\n" -#, fuzzy, c-format +#, c-format msgid "error caching certificate: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao armazenar o certificado em cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "invalid SHA1 fingerprint string '%s'\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "string de impressão digital SHA1 inválida '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error fetching certificate by S/N: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao buscar certificado por S/N: %s\n" -#, fuzzy, c-format +#, c-format msgid "error fetching certificate by subject: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao buscar certificado por entidade: %s\n" -#, fuzzy, c-format +#, c-format msgid "no issuer found in certificate\n" -msgstr "gerar um certificado de revogação" +msgstr "nenhum emissor encontrado no certificado\n" -#, fuzzy, c-format +#, c-format msgid "error getting authorityKeyIdentifier: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter authorityKeyIdentifier: %s\n" -#, fuzzy, c-format +#, c-format msgid "creating directory '%s'\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "criando a pasta '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error creating directory '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao criar a pasta '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "ignoring database dir '%s'\n" -msgstr "erro na última linha\n" +msgstr "ignorando a pasta da base de dados '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error reading directory '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler a pasta '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "removing cache file '%s'\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "removendo o ficheiro de cache '%s'\n" -#, fuzzy, c-format -#| msgid "enarmoring failed: %s\n" +#, c-format msgid "not removing file '%s'\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "não removendo ficheiro '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error closing cache file: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fechar o ficheiro de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to open cache dir file '%s': %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "falha ao abrir o ficheiro '%s' da pasta de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "error creating new cache dir file '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar novo ficheiro '%s' da pasta de cache: %s\n" -#, fuzzy, c-format -#| msgid "error writing secret keyring `%s': %s\n" +#, c-format msgid "error writing new cache dir file '%s': %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao escrever novo ficheiro '%s' da pasta de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "error closing new cache dir file '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fechar novo ficheiro '%s' da pasta de cache: %s\n" -#, fuzzy, c-format -#| msgid "new configuration file `%s' created\n" +#, c-format msgid "new cache dir file '%s' created\n" -msgstr "criado um novo ficheiro de configuração `%s'\n" +msgstr "novo ficheiro '%s' da pasta de cache criado\n" -#, fuzzy, c-format +#, c-format msgid "failed to re-open cache dir file '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "falha ao reabrir ficheiro '%s' da pasta de cache: %s\n" #, c-format msgid "first record of '%s' is not the version\n" -msgstr "" +msgstr "primeiro registo de '%s' não é a versão\n" #, c-format msgid "old version of cache directory - cleaning up\n" -msgstr "" +msgstr "versão antiga da pasta de cache - limpando\n" #, c-format msgid "old version of cache directory - giving up\n" -msgstr "" +msgstr "versão antiga da pasta de cache - desistindo\n" #, c-format msgid "extra field detected in crl record of '%s' line %u\n" -msgstr "" +msgstr "campo extra detetado no registo crl de '%s' linha %u\n" -#, fuzzy, c-format +#, c-format msgid "invalid line detected in '%s' line %u\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "linha inválida detetada em '%s' linha %u\n" -#, fuzzy, c-format +#, c-format msgid "duplicate entry detected in '%s' line %u\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "entrada duplicada detetada em '%s' linha %u\n" #, c-format msgid "unsupported record type in '%s' line %u skipped\n" -msgstr "" +msgstr "tipo de registo sem suporte em '%s' linha %u ignorada\n" -#, fuzzy, c-format +#, c-format msgid "invalid issuer hash in '%s' line %u\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "hash do emissor inválido em '%s' linha %u\n" -#, fuzzy, c-format +#, c-format msgid "no issuer DN in '%s' line %u\n" -msgstr "armadura: %s\n" +msgstr "nenhum DN emissor em '%s' linha %u\n" -#, fuzzy, c-format +#, c-format msgid "invalid timestamp in '%s' line %u\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "timestamp inválido em '%s' linha %u\n" -#, fuzzy, c-format -#| msgid "WARNING: invalid size of random_seed file - not used\n" +#, c-format msgid "WARNING: invalid cache file hash in '%s' line %u\n" -msgstr "" -"AVISO: o ficheiro random_seed tem um tamanho inválido - não utilizado\n" +msgstr "AVISO: hash de ficheiro de cache inválido em '%s' linha %u\n" #, c-format msgid "detected errors in cache dir file\n" -msgstr "" +msgstr "erros detetados no ficheiro da pasta de cache\n" #, c-format msgid "please check the reason and manually delete that file\n" -msgstr "" +msgstr "verifique o motivo e apague manualmente este ficheiro\n" -#, fuzzy, c-format +#, c-format msgid "failed to create temporary cache dir file '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "falha ao criar o ficheiro temporário '%s' da pasta de cache: %s\n" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" +#, c-format msgid "error renaming '%s' to '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao renomear '%s' para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "can't hash '%s': %s\n" -msgstr "impossível fechar `%s': %s\n" +msgstr "não é possível fazer hash de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error setting up MD5 hash context: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao definir o contexto da hash MD5: %s\n" -#, fuzzy, c-format +#, c-format msgid "error hashing '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fazer hash de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "invalid formatted checksum for '%s'\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "checksum formatada inválida para '%s'\n" #, c-format msgid "too many open cache files; can't open anymore\n" -msgstr "" +msgstr "muitos ficheiros de cache abertos; posso abrir mais nenhum\n" -#, fuzzy, c-format +#, c-format msgid "opening cache file '%s'\n" -msgstr "assinatura falhou: %s\n" +msgstr "abrindo o ficheiro de cache '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error opening cache file '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao abrir o ficheiro de cache '%s': %s\n" #, c-format msgid "error initializing cache file '%s' for reading: %s\n" -msgstr "" +msgstr "erro ao inicializar o ficheiro de cache '%s' para leitura: %s\n" #, c-format msgid "calling unlock_db_file on a closed file\n" -msgstr "" +msgstr "chamando unlock_db_file num ficheiro fechado\n" #, c-format msgid "calling unlock_db_file on an unlocked file\n" -msgstr "" +msgstr "chamando unlock_db_file num ficheiro desbloqueado\n" -#, fuzzy, c-format +#, c-format msgid "failed to create a new cache object: %s\n" -msgstr "%s: falha ao criar tabela de dispersão: %s\n" +msgstr "falha ao criar um novo objeto de cache: %s\n" -#, fuzzy, c-format -#| msgid "No help available for `%s'" +#, c-format msgid "no CRL available for issuer id %s\n" -msgstr "Nenhuma ajuda disponível para `%s'" +msgstr "nenhuma CRL disponível para a id do emissor %s\n" #, c-format msgid "cached CRL for issuer id %s too old; update required\n" msgstr "" +"CRL em cache muito antiga para a id do emissor %s; atualização necessária\n" #, c-format msgid "" "force-crl-refresh active and %d minutes passed for issuer id %s; update " "required\n" msgstr "" +"force-crl-refresh ativa e %d minutos passados para a id do emissor %s; " +"atualização necessária\n" #, c-format msgid "force-crl-refresh active for issuer id %s; update required\n" msgstr "" +"force-crl-refresh ativa para a id do emissor %s; atualização necessária\n" #, c-format msgid "available CRL for issuer ID %s can't be used\n" -msgstr "" +msgstr "CRL disponível para a id do emissor %s não pode ser usada\n" #, c-format msgid "cached CRL for issuer id %s tampered; we need to update\n" msgstr "" +"CRL em cache adulterada para a id do emissor %s; precisamos atualizar\n" #, c-format msgid "WARNING: invalid cache record length for S/N " -msgstr "" +msgstr "AVISO: comprimento do registo de cache inválido para S/N " -#, fuzzy, c-format +#, c-format msgid "problem reading cache record for S/N %s: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "problema ao ler o registo de cache para S/N %s: %s\n" #, c-format msgid "S/N %s is not valid; reason=%02X date=%.15s\n" -msgstr "" +msgstr "S/N %s não é válido; razão=%02X data=%.15s\n" #, c-format msgid "S/N %s is valid, it is not listed in the CRL\n" -msgstr "" +msgstr "S/N %s é válido, não está listado na CRL\n" -#, fuzzy, c-format +#, c-format msgid "error getting data from cache file: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter os dados do ficheiro de cache: %s\n" #, c-format msgid "got an invalid S-expression from libksba\n" -msgstr "" +msgstr "obtive uma S-expression inválida da libksba\n" -#, fuzzy, c-format +#, c-format msgid "converting S-expression failed: %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "falha na conversão da S-expression: %s\n" -#, fuzzy, c-format -#| msgid "invalid hash algorithm `%s'\n" +#, c-format msgid "unknown hash algorithm '%s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash desconhecido '%s'\n" #, c-format msgid "gcry_md_open for algorithm %d failed: %s\n" -msgstr "" +msgstr "gcry_md_open para o algoritmo %d falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "creating S-expression failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao criar a S-expression: %s\n" -#, fuzzy, c-format +#, c-format msgid "ksba_crl_parse failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "ksba_crl_parse falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "error getting update times of CRL: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter tempos de atualização da CRL: %s\n" #, c-format msgid "update times of this CRL: this=%s next=%s\n" -msgstr "" +msgstr "tempos de atualização desta CRL: este=%s próximo=%s\n" #, c-format msgid "nextUpdate not given; assuming a validity period of one day\n" -msgstr "" +msgstr "nextUpdate não fornecido; assumindo que expira num período de um dia\n" -#, fuzzy, c-format +#, c-format msgid "error getting CRL item: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter o item da CRL: %s\n" -#, fuzzy, c-format +#, c-format msgid "error inserting item into temporary cache file: %s\n" -msgstr "a escrever para `%s'\n" +msgstr "erro ao inserir item no ficheiro de cache temporário: %s\n" -#, fuzzy, c-format +#, c-format msgid "no CRL issuer found in CRL: %s\n" -msgstr "gerar um certificado de revogação" +msgstr "nenhum emissor de CRL encontrado na CRL: %s\n" #, c-format msgid "locating CRL issuer certificate by authorityKeyIdentifier\n" msgstr "" +"localizando o certificado do emissor da CRL por authorityKeyIdentifier\n" -#, fuzzy, c-format -#| msgid "signature verification suppressed\n" +#, c-format msgid "CRL signature verification failed: %s\n" -msgstr "verificação de assinatura suprimida\n" +msgstr "falha na verificação de assinatura da CRL: %s\n" -#, fuzzy, c-format +#, c-format msgid "error checking validity of CRL issuer certificate: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "erro ao verificar a validade do certificado do emissor da CRL: %s\n" -#, fuzzy, c-format +#, c-format msgid "ksba_crl_new failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "ksba_crl_new falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "ksba_crl_set_reader failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "ksba_crl_set_reader falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "removed stale temporary cache file '%s'\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "ficheiro de cache temporário obsoleto '%s' foi removido\n" -#, fuzzy, c-format +#, c-format msgid "problem removing stale temporary cache file '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "problema ao remover o ficheiro de cache temporário obsoleto '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error creating temporary cache file '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar o ficheiro de cache temporário '%s': %s\n" -#, fuzzy, c-format -#| msgid "update secret failed: %s\n" +#, c-format msgid "crl_parse_insert failed: %s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "crl_parse_insert falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "error finishing temporary cache file '%s': %s\n" -msgstr "a escrever para `%s'\n" +msgstr "erro ao finalizar o ficheiro de cache temporário '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error closing temporary cache file '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao fechar o ficheiro de cache temporário '%s': %s\n" #, c-format msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n" msgstr "" +"ATENÇÃO: nova CRL ainda muito antiga; ela expirou em %s - carregando mesmo " +"assim\n" #, c-format msgid "new CRL still too old; it expired on %s\n" -msgstr "" +msgstr "nova CRL ainda muito antiga; expirou em %s\n" #, c-format msgid "unknown critical CRL extension %s\n" -msgstr "" +msgstr "extensão crítica de CRL desconhecida %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading CRL extensions: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler extensões de CRL: %s\n" -#, fuzzy, c-format +#, c-format msgid "creating cache file '%s'\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "criando o ficheiro de cache '%s'\n" -#, fuzzy, c-format +#, c-format msgid "problem renaming '%s' to '%s': %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "problema ao renomear '%s' para '%s': %s\n" #, c-format msgid "" "updating the DIR file failed - cache entry will get lost with the next " "program start\n" msgstr "" +"falha ao atualizar o ficheiro DIR - a entrada de cache será perdida com o " +"próximo início do programa\n" #, c-format msgid "Begin CRL dump (retrieved via %s)\n" -msgstr "" +msgstr "Iniciar dump de CRL (obtido via %s)\n" msgid "" " ERROR: The CRL will not be used because it was still too old after an " "update!\n" msgstr "" +" ERRO: A CRL não será usada porque ainda era muito antiga após uma " +"atualização!\n" msgid "" " ERROR: The CRL will not be used due to an unknown critical extension!\n" msgstr "" +" ERRO: A CRL não será usada devido a uma extensão crítica desconhecida!\n" msgid " ERROR: The CRL will not be used\n" -msgstr "" +msgstr " ERRO: A CRL não será usada\n" msgid " ERROR: This cached CRL may have been tampered with!\n" -msgstr "" +msgstr " ERRO: Esta CRL em cache pode ter sido adulterada!\n" -#, fuzzy, c-format -#| msgid "WARNING: invalid size of random_seed file - not used\n" +#, c-format msgid " WARNING: invalid cache record length\n" -msgstr "" -"AVISO: o ficheiro random_seed tem um tamanho inválido - não utilizado\n" +msgstr " AVISO: comprimento de registo de cache inválido\n" -#, fuzzy, c-format +#, c-format msgid "problem reading cache record: %s\n" -msgstr "%s: erro ao ler registo livre: %s\n" +msgstr "problema ao ler o registo de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "problem reading cache key: %s\n" -msgstr "rev? problema ao verificar revogação: %s\n" +msgstr "problema ao ler a chave de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading cache entry from db: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler a entrada de cache da base de dados: %s\n" msgid "End CRL dump\n" -msgstr "" +msgstr "Fim do dump de CRL\n" -#, fuzzy, c-format +#, c-format msgid "crl_fetch via DP failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "crl_fetch via DP falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "crl_cache_insert via DP failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "crl_cache_insert via DP falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "crl_cache_insert via issuer failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "crl_cache_insert via emissor falhou: %s\n" #, c-format msgid "reader to file mapping table full - waiting\n" -msgstr "" +msgstr "leitor cheio para tabela de mapeamento de ficheiros - aguardando\n" -#, fuzzy msgid "CRL access not possible due to Tor mode" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "o acesso à CRL não é possível devido ao modo Tor" #, c-format msgid "CRL access not possible due to disabled %s\n" -msgstr "" +msgstr "o acesso à CRL não é possível devido a %s estar desabilitado\n" -#, fuzzy, c-format +#, c-format msgid "error retrieving '%s': %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "erro ao obter '%s': %s\n" -#, fuzzy, c-format -#| msgid "%s: error writing dir record: %s\n" +#, c-format msgid "error initializing reader object: %s\n" -msgstr "%s: erro ao escrever registo de diretório: %s\n" +msgstr "erro ao inicializar o objeto leitor: %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate search not possible due to disabled %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "" +"a pesquisa de certificados não é possível devido a %s estar desabilitado\n" msgid "use OCSP instead of CRLs" -msgstr "" +msgstr "usar OCSP em vez de CRLs" msgid "check whether a dirmngr is running" -msgstr "" +msgstr "verificar se um dirmngr está em execução" -#, fuzzy msgid "add a certificate to the cache" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "adicionar um certificado à cache" -#, fuzzy msgid "validate a certificate" -msgstr "certificado incorrecto" +msgstr "validar um certificado" -#, fuzzy msgid "lookup a certificate" -msgstr "certificado incorrecto" +msgstr "procurar um certificado" -#, fuzzy msgid "lookup only locally stored certificates" -msgstr "certificado incorrecto" +msgstr "procurar apenas certificados armazenados localmente" msgid "expect an URL for --lookup" -msgstr "" +msgstr "esperar uma URL para --lookup" msgid "load a CRL into the dirmngr" -msgstr "" +msgstr "carregar uma CRL no dirmngr" msgid "special mode for use by Squid" -msgstr "" +msgstr "modo especial para uso pelo Squid" -#, fuzzy msgid "expect certificates in PEM format" -msgstr "certificado incorrecto" +msgstr "esperar certificados no formato PEM" -#, fuzzy -#| msgid "Enter the user ID of the designated revoker: " msgid "force the use of the default OCSP responder" -msgstr "Insira o ID de utilizador do revogador escolhido: " +msgstr "forçar o uso do respondente OCSP pré-definido" -#, fuzzy -#| msgid "Usage: gpg [options] [files] (-h for help)" msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "" +"Uso: dirmngr-client [opções] [ficheiro-cert|padrão] (-h para obter ajuda)\n" msgid "" "Syntax: dirmngr-client [options] [certfile|pattern]\n" @@ -8415,2987 +8155,821 @@ msgid "" "The process returns 0 if the certificate is valid, 1 if it is\n" "not valid and other error codes for general failures\n" msgstr "" +"Sintaxe: dirmngr-client [opções] [ficheiro-cert|padrão]\n" +"Testar um certificado X.509 em relação a uma CRL ou fazer uma\n" +"verificação OCSP.\n" +"O processo retorna 0 se o certificado for válido, 1 se não for\n" +"válido, e outros códigos de erro para falhas gerais.\n" -#, fuzzy, c-format +#, c-format msgid "error reading certificate from stdin: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao ler certificado de stdin: %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading certificate from '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler o certificado de '%s': %s\n" #, c-format msgid "certificate too large to make any sense\n" -msgstr "" +msgstr "certificado demasiado grande para fazer qualquer sentido\n" -#, fuzzy, c-format -#| msgid "can't connect to `%s': %s\n" +#, c-format msgid "can't connect to the dirmngr: %s\n" -msgstr "impossível ligar a `%s': %s\n" +msgstr "não é possível conectar-se ao dirmngr: %s\n" -#, fuzzy, c-format -#| msgid "update failed: %s\n" +#, c-format msgid "lookup failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "falha na procura: %s\n" -#, fuzzy, c-format +#, c-format msgid "loading CRL '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha ao carregar a CRL '%s': %s\n" #, c-format msgid "a dirmngr daemon is up and running\n" -msgstr "" +msgstr "um daemon dirmngr está a correr\n" -#, fuzzy, c-format +#, c-format msgid "validation of certificate failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha na validação do certificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate is valid\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado é válido\n" -#, fuzzy, c-format +#, c-format msgid "certificate has been revoked\n" -msgstr "NOTA: a chave foi revogada" +msgstr "o certificado foi revogado\n" -#, fuzzy, c-format +#, c-format msgid "certificate check failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha na verificação do certificado: %s\n" -#, fuzzy, c-format -#| msgid "can't stat `%s': %s\n" +#, c-format msgid "got status: '%s'\n" -msgstr "impossível 'stat' a `%s': %s\n" +msgstr "recebi status: '%s'\n" -#, fuzzy, c-format -#| msgid "error writing secret keyring `%s': %s\n" +#, c-format msgid "error writing base64 encoding: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao escrever codificação base64: %s\n" -#, fuzzy, c-format +#, c-format msgid "unsupported inquiry '%s'\n" -msgstr "" -"\n" -"Algoritmos suportados:\n" +msgstr "inquérito não suportado '%s'\n" #, c-format msgid "absolute file name expected\n" -msgstr "" +msgstr "esperado nome absoluto de ficheiro\n" #, c-format msgid "looking up '%s'\n" -msgstr "" +msgstr "procurando '%s'\n" msgid "list the contents of the CRL cache" -msgstr "" +msgstr "listar o conteúdo da cache de CRL" -#, fuzzy msgid "|FILE|load CRL from FILE into cache" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|carregar CRL de FILE para cache" msgid "|URL|fetch a CRL from URL" -msgstr "" +msgstr "|URL|buscar uma CRL de URL" msgid "shutdown the dirmngr" -msgstr "" +msgstr "terminar o dirmngr" msgid "flush the cache" -msgstr "" +msgstr "limpar a cache" msgid "allow online software version check" -msgstr "" +msgstr "permitir verificação online da versão do software" msgid "|N|do not return more than N items in one query" -msgstr "" +msgstr "|N|não retornar mais de N itens em uma consulta" msgid "Network related options" -msgstr "" +msgstr "Opções relacionadas à rede" msgid "route all network traffic via Tor" -msgstr "" +msgstr "direcionar todo o tráfego de rede via Tor" msgid "Configuration for HTTP servers" -msgstr "" +msgstr "Configurações para servidores HTTP" msgid "inhibit the use of HTTP" -msgstr "" +msgstr "inibir o uso de HTTP" msgid "ignore HTTP CRL distribution points" -msgstr "" +msgstr "ignorar os pontos de distribuição de CRL que são HTTP" msgid "|URL|redirect all HTTP requests to URL" -msgstr "" +msgstr "|URL|redirecionar todas os pedidos HTTP para URL" msgid "use system's HTTP proxy setting" -msgstr "" +msgstr "usar a definição de proxy HTTP do sistema" msgid "Configuration for OpenPGP servers" -msgstr "" +msgstr "Configurações para servidores OpenPGP" -#, fuzzy msgid "|URL|use keyserver at URL" -msgstr "não consegui processar a URI do servidor de chaves\n" +msgstr "|URL|usar servidor de chaves na URL" msgid "|FILE|use the CA certificates in FILE for HKP over TLS" -msgstr "" +msgstr "|FILE|usar os certificados CA em FILE para HKP sobre TLS" msgid "Configuration for X.509 servers" -msgstr "" +msgstr "Configurações para servidores X.509" msgid "inhibit the use of LDAP" -msgstr "" +msgstr "inibir o uso do LDAP" msgid "ignore LDAP CRL distribution points" -msgstr "" +msgstr "ignorar os pontos de distribuição de CRL que são LDAP" msgid "|HOST|use HOST for LDAP queries" -msgstr "" +msgstr "|HOST|usar HOST para consultas LDAP" msgid "do not use fallback hosts with --ldap-proxy" -msgstr "" +msgstr "não usar hosts de fallback com --ldap-proxy" -#, fuzzy msgid "|SPEC|use this keyserver to lookup keys" -msgstr "|ENDEREÇO|usar este servidor para buscar chaves" +msgstr "|SPEC|usar este servidor de chaves para procurar por chaves" -#, fuzzy msgid "|FILE|read LDAP server list from FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|ler lista de servidores LDAP do FILE" msgid "add new servers discovered in CRL distribution points to serverlist" msgstr "" +"adicionar novos servidores descobertos em pontos de distribuição de CRL à " +"serverlist" msgid "|N|set LDAP timeout to N seconds" -msgstr "" +msgstr "|N|definir tempo limite LDAP para N segundos" msgid "Configuration for OCSP" -msgstr "" +msgstr "Configurações para OCSP" msgid "allow sending OCSP requests" -msgstr "" +msgstr "permitir enviar pedidos OCSP" msgid "ignore certificate contained OCSP service URLs" -msgstr "" +msgstr "ignorar URL de serviço OCSP contido no certificado" -#, fuzzy msgid "|URL|use OCSP responder at URL" -msgstr "não consegui processar a URI do servidor de chaves\n" +msgstr "|URL|usar o respondente de OCSP na URL" msgid "|FPR|OCSP response signed by FPR" -msgstr "" +msgstr "|FPR|resposta OCSP assinada por FPR" msgid "force loading of outdated CRLs" -msgstr "" +msgstr "forçar o carregar de CRLs desatualizados" -#, fuzzy -#| msgid "" -#| "@\n" -#| "(See the man page for a complete listing of all commands and options)\n" msgid "" "@\n" "(See the \"info\" manual for a complete listing of all commands and " "options)\n" msgstr "" "@\n" -"(Veja a página man para uma lista completa de comandos e opções)\n" +"(Veja o manual \"info\" para obter uma lista completa de todos os comandos e " +"opções)\n" -#, fuzzy msgid "Usage: @DIRMNGR@ [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @DIRMNGR@ [opções] (-h para ajuda)" msgid "" "Syntax: @DIRMNGR@ [options] [command [args]]\n" "Keyserver, CRL, and OCSP access for @GNUPG@\n" msgstr "" +"Sintaxe: @DIRMNGR@ [opções] [comando [args]]\n" +"Acesso a servidor de chaves, CRL, e OCSP para @GNUPG@\n" #, c-format msgid "valid debug levels are: %s\n" -msgstr "" +msgstr "os níveis de debug válidos são: %s\n" -#, fuzzy, c-format +#, c-format msgid "usage: %s [options] " -msgstr "uso: gpg [opções] " +msgstr "uso: %s [opções] " -#, fuzzy, c-format -#| msgid "%s not allowed with %s!\n" +#, c-format msgid "colons are not allowed in the socket name\n" -msgstr "%s não é permitido com %s!\n" +msgstr "'dois pontos' não são permitidos no nome do socket\n" -#, fuzzy, c-format +#, c-format msgid "fetching CRL from '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha ao buscar a CRL de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "processing CRL from '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha ao processar a CRL de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: line too long - skipped\n" -msgstr "frase secreta demasiado longa\n" +msgstr "%s:%u: linha muito longa - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: invalid fingerprint detected\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "%s:%u: impressão digital inválida detetada\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: read error: %s\n" -msgstr "armadura: %s\n" +msgstr "%s:%u: erro de leitura: %s\n" #, c-format msgid "%s:%u: garbage at end of line ignored\n" -msgstr "" +msgstr "%s:%u: lixo no final da linha ignorado\n" #, c-format msgid "SIGHUP received - re-reading configuration and flushing caches\n" -msgstr "" +msgstr "SIGHUP recebido - re-lendo a configuração e limpando as caches\n" #, c-format msgid "SIGUSR2 received - no action defined\n" -msgstr "" +msgstr "SIGUSR2 recebido - nenhuma ação definida\n" #, c-format msgid "SIGTERM received - shutting down ...\n" -msgstr "" +msgstr "SIGTERM recebido - terminando ...\n" #, c-format msgid "SIGTERM received - still %d active connections\n" -msgstr "" +msgstr "SIGTERM recebido - ainda há %d conexões ativas\n" -#, fuzzy, c-format +#, c-format msgid "shutdown forced\n" -msgstr "não processado" +msgstr "terminar forçado\n" #, c-format msgid "SIGINT received - immediate shutdown\n" -msgstr "" +msgstr "SIGINT recebido - terminando imediatamente\n" #, c-format msgid "signal %d received - no action defined\n" -msgstr "" +msgstr "sinal %d recebido - nenhuma ação definida\n" -#, fuzzy, c-format +#, c-format msgid "error accessing '%s': http status %u\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao aceder '%s': status http %u\n" #, c-format msgid "URL '%s' redirected to '%s' (%u)\n" -msgstr "" +msgstr "URL '%s' redirecionada para '%s' (%u)\n" -#, fuzzy, c-format +#, c-format msgid "too many redirections\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiados redirecionamentos\n" -#, fuzzy, c-format -#| msgid "writing to `%s'\n" +#, c-format msgid "redirection changed to '%s'\n" -msgstr "a escrever para `%s'\n" +msgstr "redirecionamento alterado para '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error printing log line: %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao mostrar linha de log: %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading log from ldap wrapper %d: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler log do wrapper ldap %d: %s\n" #, c-format msgid "ldap wrapper %d ready" -msgstr "" +msgstr "wrapper ldap %d pronto" #, c-format msgid "ldap wrapper %d ready: timeout\n" -msgstr "" +msgstr "wrapper ldap %d pronto: pausa\n" #, c-format msgid "ldap wrapper %d ready: exitcode=%d\n" -msgstr "" +msgstr "wrapper ldap %d pronto: exitcode=%d\n" -#, fuzzy, c-format +#, c-format msgid "waiting for ldap wrapper %d failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "falha ao aguardar por wrapper ldap %d: %s\n" #, c-format msgid "ldap wrapper %d stalled - killing\n" -msgstr "" +msgstr "wrapper ldap %d obsoleto - matando\n" #, c-format msgid "invalid char 0x%02x in host name - not added\n" -msgstr "" +msgstr "char 0x%02x inválido no nome do host - não adicionado\n" -#, fuzzy, c-format +#, c-format msgid "adding '%s:%d' to the ldap server list\n" -msgstr "a procurar por \"%s\" no servidor HKP %s\n" +msgstr "adicionando '%s:%d' à lista de servidores ldap\n" -#, fuzzy, c-format +#, c-format msgid "malloc failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "malloc falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "'%s' is not an LDAP URL\n" -msgstr "%s: não é um base de dados de confiança\n" +msgstr "'%s' não é uma URL LDAP\n" #, c-format msgid "'%s' is an invalid LDAP URL\n" -msgstr "" +msgstr "'%s' é uma URL LDAP inválida\n" #, c-format msgid "ldap_search hit the size limit of the server\n" -msgstr "" +msgstr "ldap_search atingiu o tamanho limite do servidor\n" #, c-format msgid "%s:%u: password given without user\n" -msgstr "" +msgstr "%s:%u: senha dada sem utilizador\n" #, c-format msgid "%s:%u: ignoring unknown flag '%s'\n" -msgstr "" +msgstr "%s:%u: ignorando flag '%s' desconhecida\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: skipping this line\n" -msgstr " s = saltar esta chave\n" +msgstr "%s:%u: ignorando esta linha\n" -#, fuzzy, c-format -#| msgid "%s: invalid file version %d\n" +#, c-format msgid "invalid canonical S-expression found\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "encontrada S-expression canónica inválida\n" -#, fuzzy, c-format +#, c-format msgid "gcry_md_open failed: %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "gcry_md_open falhou: %s\n" -#, fuzzy, c-format -#| msgid "update secret failed: %s\n" +#, c-format msgid "oops: ksba_cert_hash failed: %s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "oops: ksba_cert_hash falhou: %s\n" #, c-format msgid "bad URL encoding detected\n" -msgstr "" +msgstr "detetada codificação de URL inválida\n" -#, fuzzy, c-format +#, c-format msgid "error reading from responder: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler do respondente: %s\n" #, c-format msgid "response from server too large; limit is %d bytes\n" -msgstr "" +msgstr "resposta do servidor muito grande; limite é %d bytes\n" -#, fuzzy msgid "OCSP request not possible due to Tor mode" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "pedido OCSP não é possível devido ao modo Tor" #, c-format msgid "OCSP request not possible due to disabled HTTP\n" -msgstr "" +msgstr "pedido OCSP não é possível devido a HTTP desabilitado\n" -#, fuzzy, c-format +#, c-format msgid "error setting OCSP target: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao definir o destino OCSP: %s\n" -#, fuzzy, c-format +#, c-format msgid "error building OCSP request: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao criar o pedido OCSP: %s\n" -#, fuzzy, c-format +#, c-format msgid "error connecting to '%s': %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao conectar a '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading HTTP response for '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler a resposta HTTP para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error parsing OCSP response for '%s': %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao processar a resposta OCSP para '%s': %s\n" #, c-format msgid "OCSP responder at '%s' status: %s\n" -msgstr "" +msgstr "respondente OCSP no status '%s': %s\n" #, c-format msgid "failed to establish a hashing context for OCSP: %s\n" -msgstr "" +msgstr "falha ao estabelecer um contexto de hash para OCSP: %s\n" -#, fuzzy, c-format +#, c-format msgid "hashing the OCSP response for '%s' failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao fazer hashing da resposta OCSP para '%s': %s\n" #, c-format msgid "not signed by a default OCSP signer's certificate" -msgstr "" +msgstr "não assinado por um certificado de signatário OCSP pré-definido" -#, fuzzy, c-format +#, c-format msgid "allocating list item failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao alocar item de lista: %s\n" -#, fuzzy, c-format +#, c-format msgid "error getting responder ID: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter o ID do respondente: %s\n" #, c-format msgid "no suitable certificate found to verify the OCSP response\n" msgstr "" +"nenhum certificado adequado encontrado para verificar a resposta do OCSP\n" -#, fuzzy, c-format +#, c-format msgid "issuer certificate not found: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "certificado do emissor não encontrado: %s\n" #, c-format msgid "caller did not return the target certificate\n" -msgstr "" +msgstr "o chamador não retornou o certificado de destino\n" -#, fuzzy, c-format +#, c-format msgid "caller did not return the issuing certificate\n" -msgstr "gerar um certificado de revogação" +msgstr "o chamador não retornou o certificado de emissão\n" -#, fuzzy, c-format +#, c-format msgid "failed to allocate OCSP context: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao alocar contexto OCSP: %s\n" #, c-format msgid "no default OCSP responder defined\n" -msgstr "" +msgstr "nenhum respondente OCSP pré-definido\n" -#, fuzzy, c-format -#| msgid "no default secret keyring: %s\n" +#, c-format msgid "no default OCSP signer defined\n" -msgstr "sem porta-chaves público por omissão: %s\n" +msgstr "nenhum assinante OCSP pré-definido\n" #, c-format msgid "using default OCSP responder '%s'\n" -msgstr "" +msgstr "usando o respondente OCSP pré-definido '%s'\n" -#, fuzzy, c-format +#, c-format msgid "using OCSP responder '%s'\n" -msgstr "assinatura falhou: %s\n" +msgstr "usando o respondente OCSP '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error getting OCSP status for target certificate: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter o status OCSP para o certificado de destino: %s\n" #, c-format msgid "certificate status is: %s (this=%s next=%s)\n" -msgstr "" +msgstr "o status do certificado é: %s (este=%s próximo=%s)\n" msgid "good" -msgstr "" +msgstr "válido" -#, fuzzy, c-format +#, c-format msgid "certificate has been revoked at: %s due to: %s\n" -msgstr "NOTA: a chave foi revogada" +msgstr "o certificado foi revogado em: %s devido a: %s\n" #, c-format msgid "OCSP responder returned a status in the future\n" -msgstr "" +msgstr "o respondente OCSP retornou um status no futuro\n" #, c-format msgid "OCSP responder returned a non-current status\n" -msgstr "" +msgstr "o respondente OCSP retornou um status não atual\n" #, c-format msgid "OCSP responder returned an too old status\n" -msgstr "" +msgstr "o respondente OCSP retornou um status muito antigo\n" -#, fuzzy, c-format +#, c-format msgid "assuan_inquire(%s) failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "assuan_inquire(%s) falhou: %s\n" msgid "serialno missing in cert ID" -msgstr "" +msgstr "número de série ausente na ID do certificado" -#, fuzzy, c-format +#, c-format msgid "assuan_inquire failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "assuan_inquire falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "fetch_cert_by_url failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "fetch_cert_by_url falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "error sending data: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao enviar dados: %s\n" -#, fuzzy, c-format +#, c-format msgid "start_cert_fetch failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "start_cert_fetch falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "fetch_next_cert failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "fetch_next_cert falhou: %s\n" #, c-format msgid "max_replies %d exceeded\n" -msgstr "" +msgstr "excedido max_replies %d\n" -#, fuzzy, c-format +#, c-format msgid "can't allocate control structure: %s\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível alocar a estrutura de controle: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to allocate assuan context: %s\n" -msgstr "%s: falha ao criar tabela de dispersão: %s\n" +msgstr "falha ao alocar contexto assuan: %s\n" -#, fuzzy, c-format -#| msgid "failed to initialize the TrustDB: %s\n" +#, c-format msgid "failed to initialize the server: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao inicializar o servidor: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to the register commands with Assuan: %s\n" -msgstr "falha ao criar 'cache' do porta-chaves: %s\n" +msgstr "falha ao registar comandos com Assuan: %s\n" #, c-format msgid "Assuan accept problem: %s\n" -msgstr "" +msgstr "problema de aceitação Assuan: %s\n" -#, fuzzy, c-format -#| msgid "signing failed: %s\n" +#, c-format msgid "Assuan processing failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "falha no processamento do Assuan: %s\n" #, c-format msgid "accepting root CA not marked as a CA" -msgstr "" +msgstr "aceitando a CA raiz não marcada como uma CA" -#, fuzzy, c-format -#| msgid "checking the trustdb\n" +#, c-format msgid "CRL checking too deeply nested\n" -msgstr "a verificar a base de dados de confiança\n" +msgstr "verificação de CRL muito aprofundadamente aninhada\n" msgid "not checking CRL for" -msgstr "" +msgstr "não verificando CRL para" -#, fuzzy msgid "checking CRL for" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "verificando CRL para" -#, fuzzy, c-format +#, c-format msgid "checking trustworthiness of root certificate failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha na verificação da confiança do certificado raiz: %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate chain is good\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "a corrente de certificados é válida\n" #, c-format msgid "certificate should not have been used for CRL signing\n" -msgstr "" +msgstr "certificado não deveria ter sido usado para assinatura de CRL\n" -#, fuzzy msgid "quiet" -msgstr "sair" +msgstr "silencioso" msgid "print data out hex encoded" -msgstr "" +msgstr "imprimir dados codificados em hex" msgid "decode received data lines" -msgstr "" +msgstr "descodificar linhas de dados recebidas" msgid "connect to the dirmngr" -msgstr "" +msgstr "conectar ao dirmngr" msgid "connect to the keyboxd" -msgstr "" +msgstr "conectar ao keyboxd" msgid "|NAME|connect to Assuan socket NAME" -msgstr "" +msgstr "|NAME|conectar ao socket Assuan NAME" msgid "|ADDR|connect to Assuan server at ADDR" -msgstr "" +msgstr "|ADDR|conectar ao servidor Assuan em ADDR" msgid "run the Assuan server given on the command line" -msgstr "" +msgstr "execute o servidor Assuan fornecido na linha de comando" msgid "do not use extended connect mode" -msgstr "" +msgstr "não usar o modo de conexão estendida" -#, fuzzy msgid "|FILE|run commands from FILE on startup" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|executar comandos do FILE na inicialização" msgid "run /subst on startup" -msgstr "" +msgstr "executar /subst na inicialização" -#, fuzzy msgid "Usage: @GPG@-connect-agent [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPG@-connect-agent [opções] (-h para ajuda)" msgid "" "Syntax: @GPG@-connect-agent [options]\n" "Connect to a running agent and send commands\n" msgstr "" +"Sintaxe: @GPG@-connect-agent [opções]\n" +"Conectar-se a um agent em execução e enviar comandos\n" #, c-format msgid "option \"%s\" requires a program and optional arguments\n" -msgstr "" +msgstr "a opção \"%s\" requer um programa e argumentos opcionais\n" #, c-format msgid "option \"%s\" ignored due to \"%s\"\n" -msgstr "" +msgstr "opção \"%s\" ignorada devido a \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "receiving line failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao receber linha: %s\n" -#, fuzzy, c-format +#, c-format msgid "line too long - skipped\n" -msgstr "frase secreta demasiado longa\n" +msgstr "linha muito longa - ignorada\n" #, c-format msgid "line shortened due to embedded Nul character\n" -msgstr "" +msgstr "linha encurtada devido ao caractere Nul incorporado\n" -#, fuzzy, c-format +#, c-format msgid "unknown command '%s'\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "comando desconhecido '%s'\n" -#, fuzzy, c-format +#, c-format msgid "sending line failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "falha ao enviar linha: %s\n" -#, fuzzy, c-format +#, c-format msgid "no keybox daemon running in this session\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "nenhum daemon keybox em execução nesta sessão\n" -#, fuzzy, c-format +#, c-format msgid "error sending standard options: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao enviar opções padrão: %s\n" msgid "OpenPGP" -msgstr "" +msgstr "OpenPGP" msgid "S/MIME" -msgstr "" +msgstr "S/MIME" -#, fuzzy msgid "Public Keys" -msgstr "a chave pública é %08lX\n" +msgstr "Chaves Públicas" msgid "Private Keys" -msgstr "" +msgstr "Chaves Privadas" msgid "Smartcards" -msgstr "" +msgstr "Smartcards" msgid "TPM" -msgstr "" +msgstr "TPM" -#, fuzzy -#| msgid "network error" msgid "Network" -msgstr "erro na rede" +msgstr "Rede" -#, fuzzy msgid "Passphrase Entry" -msgstr "frase secreta incorrecta" +msgstr "Entrada de Frase-secreta" -#, fuzzy msgid "Component not suitable for launching" -msgstr "chave pública não encontrada" +msgstr "Componente não adequado para lançamento" #, c-format msgid "Configuration file of component %s is broken\n" -msgstr "" +msgstr "O ficheiro de configuração do componente %s está quebrado\n" -#, fuzzy, c-format -#| msgid "Please use the command \"toggle\" first.\n" +#, c-format msgid "Note: Use the command \"%s%s\" to get details.\n" -msgstr "Por favor utilize o comando \"toggle\" primeiro.\n" +msgstr "Nota: Usar o comando \"%s%s\" para obter detalhes.\n" #, c-format msgid "External verification of component %s failed" -msgstr "" +msgstr "Falha na verificação externa do componente %s" msgid "Note that group specifications are ignored\n" -msgstr "" +msgstr "Repare que as especificações do grupo são ignoradas\n" -#, fuzzy, c-format +#, c-format msgid "error closing '%s'\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fechar '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error parsing '%s'\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao processar '%s'\n" msgid "list all components" -msgstr "" +msgstr "listar todos os componentes" msgid "check all programs" -msgstr "" +msgstr "verificar todos os programas" msgid "|COMPONENT|list options" -msgstr "" +msgstr "|COMPONENT|listar opções" msgid "|COMPONENT|change options" -msgstr "" +msgstr "|COMPONENT|alterar opções" msgid "|COMPONENT|check options" -msgstr "" +msgstr "|COMPONENT|verificar opções" msgid "apply global default values" -msgstr "" +msgstr "aplicar valores globais pré-definidos" msgid "|FILE|update configuration files using FILE" -msgstr "" +msgstr "|FILE|atualizar ficheiros de configuração usando FILE" msgid "get the configuration directories for @GPGCONF@" -msgstr "" +msgstr "obter as pastas de configuração para @GPGCONF@" -#, fuzzy msgid "list global configuration file" -msgstr "criado um novo ficheiro de configuração `%s'\n" +msgstr "listar ficheiro de configuração global" -#, fuzzy msgid "check global configuration file" -msgstr "criado um novo ficheiro de configuração `%s'\n" +msgstr "verificar ficheiro de configuração global" -#, fuzzy -#| msgid "update the trust database" msgid "query the software version database" -msgstr "actualizar a base de dados de confiança" +msgstr "consultar a base de dados da versão do software" msgid "reload all or a given component" -msgstr "" +msgstr "recarregar todos ou um determinado componente" msgid "launch a given component" -msgstr "" +msgstr "lançar um determinado componente" msgid "kill a given component" -msgstr "" +msgstr "matar um determinado componente" msgid "use as output file" msgstr "usar como ficheiro de saída" msgid "activate changes at runtime, if possible" -msgstr "" +msgstr "ativar alterações em tempo de execução, se possível" -#, fuzzy msgid "Usage: @GPGCONF@ [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPGCONF@ [opções] (-h para ajuda)" msgid "" "Syntax: @GPGCONF@ [options]\n" "Manage configuration options for tools of the @GNUPG@ system\n" msgstr "" +"Sintaxe: @GPGCONF@ [opções]\n" +"Gerir opções de configuração para as ferramentas do sistema @GNUPG@\n" msgid "Need one component argument" -msgstr "" +msgstr "Precisa de um argumento de componente" -#, fuzzy msgid "Component not found" -msgstr "chave pública não encontrada" +msgstr "Componente não encontrado" -#, fuzzy msgid "No argument allowed" -msgstr "a escrever chave privada para `%s'\n" +msgstr "Nenhum argumento permitido" -#, fuzzy msgid "Usage: gpg-check-pattern [options] patternfile (-h for help)\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "" +"Uso: gpg-check-pattern [opções] ficheiro-de-padrões (-h para obter ajuda)\n" msgid "" "Syntax: gpg-check-pattern [options] patternfile\n" "Check a passphrase given on stdin against the patternfile\n" msgstr "" +"Sintaxe: gpg-check-pattern [opções] ficheiro-de-padrões\n" +"Verificar uma frase-secreta dada em stdin em relação a um ficheiro de " +"padrão\n" -#, fuzzy, c-format +#, c-format msgid "Note: key %s is already stored on the card!\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "Nota: a chave %s já está armazenada no cartão!\n" -#, fuzzy, c-format +#, c-format msgid "Note: Keys are already stored on the card!\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "Nota: As chaves já estão armazenadas no cartão!\n" #, c-format msgid "Replace existing key %s ? (y/N) " -msgstr "" +msgstr "Substituir a chave %s existente? (s/N) " #, c-format msgid "%s card no. %s detected\n" -msgstr "" +msgstr "cartão %s nº %s detetado\n" #, c-format msgid "User Interaction Flag is set to \"%s\" - can't change\n" msgstr "" +"a User Interaction Flag está definido como \"%s\" - não é possível alterar\n" #, c-format msgid "" "Warning: Setting the User Interaction Flag to \"%s\"\n" " can only be reverted using a factory reset!\n" msgstr "" +"Aviso: Definindo a User Interaction Flag como \"%s\" só\n" +" pode ser revertida usando uma reset de fábrica!\n" #, c-format msgid "Please use \"uif --yes %d %s\"\n" -msgstr "" +msgstr "Use \"uif --yes %d %s\"\n" -#, fuzzy msgid "authenticate to the card" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "autenticar no cartão" msgid "send a reset to the card daemon" -msgstr "" +msgstr "enviar uma reset para o daemon do cartão" -#, fuzzy -#| msgid "|NAME|use NAME as default recipient" msgid "setup KDF for PIN authentication" -msgstr "|NOME|usar NOME como destinatário por omissão" +msgstr "configurar o KDF para autenticação por PIN" -#, fuzzy -#| msgid "change the expire date" msgid "change a private data object" -msgstr "muda a data de validade" +msgstr "alterar um objeto de dados privados" -#, fuzzy msgid "read a certificate from a data object" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "ler um certificado a partir de um objeto de dados" -#, fuzzy msgid "store a certificate to a data object" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "armazenar um certificado em um objeto de dados" msgid "store a private key to a data object" -msgstr "" +msgstr "armazenar uma chave privada em um objeto de dados" msgid "Yubikey management commands" -msgstr "" +msgstr "comandos de gerir uma Yubikey" msgid "manage the command history" -msgstr "" - -#, fuzzy -#~| msgid "selected digest algorithm is invalid\n" -#~ msgid "selected AEAD algorithm is invalid\n" -#~ msgstr "o algoritmo de \"digest\" selecionado é inválido\n" - -#, fuzzy -#~| msgid "invalid personal cipher preferences\n" -#~ msgid "invalid personal AEAD preferences\n" -#~ msgstr "preferências pessoais de cifra inválidas\n" - -#, fuzzy -#~ msgid "AEAD algorithm '%s' may not be used in %s mode\n" -#~ msgstr "não pode utilizar %s enquanto estiver no modo %s\n" - -#~ msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" -#~ msgstr "" -#~ "ao forçar a cifra simétrica %s (%d) viola as preferências do " -#~ "destinatário\n" - -#, fuzzy -#~ msgid "error writing to temporary file: %s\n" -#~ msgstr "a escrever para `%s'\n" - -#, fuzzy -#~| msgid "Key is superseded" -#~ msgid "run in supervised mode" -#~ msgstr "A chave foi substituída" - -#~ msgid "Name may not start with a digit\n" -#~ msgstr "O nome não pode começar com um dígito\n" - -#~ msgid "Name must be at least 5 characters long\n" -#~ msgstr "O nome deve ter pelo menos 5 caracteres\n" - -#, fuzzy -#~ msgid "selfsigned certificate has a BAD signature" -#~ msgstr "verificar uma assinatura" - -#, fuzzy -#~ msgid "requesting key %s from %s server %s\n" -#~ msgstr "a pedir a chave %08lX de %s\n" - -#, fuzzy -#~ msgid "could not parse keyserver\n" -#~ msgstr "não consegui processar a URI do servidor de chaves\n" - -#, fuzzy -#~| msgid "|NAME|set terminal charset to NAME" -#~ msgid "|NAME|connect to host NAME" -#~ msgstr "" -#~ "|NOME|definir mapa de caracteres do terminal como\n" -#~ "NOME" - -#, fuzzy -#~| msgid "|NAME|use NAME as default recipient" -#~ msgid "|NAME|use user NAME for authentication" -#~ msgstr "|NOME|usar NOME como destinatário por omissão" - -#, fuzzy -#~| msgid "Usage: gpg [options] [files] (-h for help)" -#~ msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#, fuzzy -#~| msgid "invalid import options\n" -#~ msgid "invalid port number %d\n" -#~ msgstr "opções de importação inválidas\n" - -#, fuzzy -#~ msgid "error writing to stdout: %s\n" -#~ msgstr "erro na escrita do porta-chaves `%s': %s\n" - -#, fuzzy -#~ msgid "attribute '%s' not found\n" -#~ msgstr "chave `%s' não encontrada: %s\n" - -#, fuzzy -#~| msgid "reading from `%s'\n" -#~ msgid "processing url '%s'\n" -#~ msgstr "lendo de `%s'\n" - -#, fuzzy -#~| msgid " w/o user IDs: %lu\n" -#~ msgid " user '%s'\n" -#~ msgstr " sem IDs de utilizadores: %lu\n" - -#, fuzzy -#~ msgid " pass '%s'\n" -#~ msgstr " ou \"" - -#, fuzzy -#~ msgid " host '%s'\n" -#~ msgstr " ou \"" - -#, fuzzy -#~| msgid " not imported: %lu\n" -#~ msgid " port %d\n" -#~ msgstr " não importadas: %lu\n" - -#, fuzzy -#~ msgid " DN '%s'\n" -#~ msgstr " ou \"" - -#, fuzzy -#~ msgid " attr '%s'\n" -#~ msgstr " ou \"" - -#, fuzzy -#~| msgid "WARNING: using insecure memory!\n" -#~ msgid "WARNING: using first attribute only\n" -#~ msgstr "AVISO: a utilizar memória insegura!\n" - -#, fuzzy -#~ msgid "LDAP init to '%s:%d' failed: %s\n" -#~ msgstr "criação de armadura falhou: %s\n" - -#, fuzzy -#~ msgid "LDAP init to '%s' failed: %s\n" -#~ msgstr "criação de armadura falhou: %s\n" - -#, fuzzy -#~ msgid "LDAP init to '%s' done\n" -#~ msgstr "criação de armadura falhou: %s\n" - -#, fuzzy -#~ msgid "binding to '%s:%d' failed: %s\n" -#~ msgstr "criação de armadura falhou: %s\n" - -#, fuzzy -#~| msgid "dearmoring failed: %s\n" -#~ msgid "searching '%s' failed: %s\n" -#~ msgstr "retirada de armadura falhou: %s\n" - -#, fuzzy -#~ msgid "Suggest a random passphrase." -#~ msgstr "muda a frase secreta" - -#, fuzzy -#~ msgid "no authentication key for ssh on card: %s\n" -#~ msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" - -#, fuzzy -#~ msgid "use a log file for the server" -#~ msgstr "procurar chaves num servidor de chaves" - -#, fuzzy -#~ msgid "argument not expected" -#~ msgstr "a escrever chave privada para `%s'\n" - -#, fuzzy -#~ msgid "read error" -#~ msgstr "erro de leitura" - -#, fuzzy -#~ msgid "keyword too long" -#~ msgstr "frase secreta demasiado longa\n" - -#, fuzzy -#~ msgid "missing argument" -#~ msgstr "argumento inválido" - -#, fuzzy -#~| msgid "invalid armor" -#~ msgid "invalid argument" -#~ msgstr "armadura inválida" - -#, fuzzy -#~ msgid "invalid command" -#~ msgstr "comandos em conflito\n" - -#, fuzzy -#~ msgid "invalid alias definition" -#~ msgstr "opções de importação inválidas\n" - -#, fuzzy -#~ msgid "out of core" -#~ msgstr "não processado" - -#, fuzzy -#~ msgid "invalid meta command" -#~ msgstr "comandos em conflito\n" - -#, fuzzy -#~ msgid "unknown meta command" -#~ msgstr "destinatário por omissão desconhecido `%s'\n" - -#, fuzzy -#~| msgid "unexpected data" -#~ msgid "unexpected meta command" -#~ msgstr "dados inesperados" - -#, fuzzy -#~ msgid "invalid option" -#~ msgstr "opções de importação inválidas\n" - -#, fuzzy -#~ msgid "invalid command \"%.50s\"\n" -#~ msgstr "Comando inválido (tente \"help\")\n" - -#, fuzzy -#~ msgid "invalid option \"%.50s\"\n" -#~ msgstr "opções de importação inválidas\n" - -#, fuzzy -#~| msgid "NOTE: no default option file `%s'\n" -#~ msgid "Note: no default option file '%s'\n" -#~ msgstr "NOTA: ficheiro de opções por omissão `%s' inexistente\n" - -#, fuzzy -#~| msgid "option file `%s': %s\n" -#~ msgid "option file '%s': %s\n" -#~ msgstr "ficheiro de opções `%s': %s\n" - -#, fuzzy -#~| msgid "you may not use %s while in %s mode\n" -#~ msgid "keyserver option \"%s\" may not be used in %s mode\n" -#~ msgstr "não pode utilizar %s enquanto estiver no modo %s\n" - -#, fuzzy -#~ msgid "unable to execute program '%s': %s\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid "unable to execute external program\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid "unable to read external program response: %s\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid " (%d) ECC and ECC\n" -#~ msgstr " (%d) DSA e ElGamal (por omissão)\n" - -#, fuzzy -#~ msgid "run without asking a user" -#~ msgstr "Sair sem gravar? " - -#, fuzzy -#~| msgid "NOTE: old default options file `%s' ignored\n" -#~ msgid "Note: old default options file '%s' ignored\n" -#~ msgstr "NOTA: o ficheiro antigo de opções por omissão `%s' foi ignorado\n" - -#, fuzzy -#~ msgid "" -#~ "@\n" -#~ "Commands:\n" -#~ " " -#~ msgstr "" -#~ "@Comandos:\n" -#~ " " - -#, fuzzy -#~ msgid "decryption modus" -#~ msgstr "decifragem correcta\n" - -#, fuzzy -#~ msgid "encryption modus" -#~ msgstr "decifragem correcta\n" - -#, fuzzy -#~ msgid "program filename" -#~ msgstr "--store [nome_do_ficheiro]" - -#, fuzzy -#~ msgid "Usage: symcryptrun [options] (-h for help)" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#, fuzzy -#~ msgid "%s on %s aborted with status %i\n" -#~ msgstr "%s não é permitido com %s!\n" - -#, fuzzy -#~ msgid "%s on %s failed with status %i\n" -#~ msgstr "impossível abrir %s: %s\n" - -#, fuzzy -#~ msgid "can't create temporary directory '%s': %s\n" -#~ msgstr "%s: impossível criar directoria: %s\n" - -#, fuzzy -#~ msgid "could not open %s for writing: %s\n" -#~ msgstr "impossível abrir %s: %s\n" - -#, fuzzy -#~ msgid "error closing %s: %s\n" -#~ msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy -#~ msgid "could not create pipe: %s\n" -#~ msgstr "impossível criar %s: %s\n" - -#, fuzzy -#~ msgid "could not create pty: %s\n" -#~ msgstr "impossível criar %s: %s\n" - -#, fuzzy -#~ msgid "execv failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~ msgid "select failed: %s\n" -#~ msgstr "remoção do bloco de chave falhou: %s\n" - -#, fuzzy -#~ msgid "read failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~ msgid "pty read failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~ msgid "waitpid failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~ msgid "cannot allocate infile string: %s\n" -#~ msgstr "impossível criar `%s': %s\n" - -#, fuzzy -#~ msgid "cannot allocate outfile string: %s\n" -#~ msgstr "impossível criar `%s': %s\n" - -#, fuzzy -#~ msgid "class %s is not supported\n" -#~ msgstr "algoritmo de protecção %d%s não é suportado\n" - -#, fuzzy -#~ msgid " using certificate ID 0x%08lX\n" -#~ msgstr "erro na criação da frase secreta: %s\n" - -#, fuzzy -#~ msgid "male" -#~ msgstr "enable" - -#, fuzzy -#~ msgid "female" -#~ msgstr "enable" - -#, fuzzy -#~ msgid "unspecified" -#~ msgstr "Nenhum motivo especificado" - -#, fuzzy -#~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n" -#~ msgstr "erro na criação da frase secreta: %s\n" - -#, fuzzy -#~ msgid "error creating 'encryptions' TOFU table: %s\n" -#~ msgstr "erro ao enviar para `%s': %s\n" - -#, fuzzy -#~ msgid "resetting keydb: %s\n" -#~ msgstr "erro na escrita do porta-chaves `%s': %s\n" - -#, fuzzy -#~ msgid "error setting TOFU binding's policy to %s\n" -#~ msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy -#~ msgid "%s: Verified %ld~signature in the past %s." -#~ msgid_plural "%s: Verified %ld~signatures in the past %s." -#~ msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -#~ msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" - -#, fuzzy -#~ msgid "Encrypted %ld~message in the past %s." -#~ msgid_plural "Encrypted %ld~messages in the past %s." -#~ msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -#~ msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" - -#, fuzzy -#~| msgid "error writing public keyring `%s': %s\n" -#~ msgid "error setting policy for key %s, user id \"%s\": %s" -#~ msgstr "erro ao escrever no porta-chaves público `%s': %s\n" - -#, fuzzy -#~ msgid "error looking up: %s\n" -#~ msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy -#~| msgid "error creating keyring `%s': %s\n" -#~ msgid "Warning: %s appears in the keyring %d times\n" -#~ msgstr "erro ao criar porta-chaves `%s': %s\n" - -#, fuzzy -#~ msgid "error retrieving '%s': http status %u\n" -#~ msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy -#~ msgid "npth_select failed: %s - waiting 1s\n" -#~ msgstr "actualização da chave secreta falhou: %s\n" - -#, fuzzy -#~ msgid "reading from ldap wrapper %d failed: %s\n" -#~ msgstr "remoção do bloco de chave falhou: %s\n" - -#, fuzzy -#~ msgid "What keysize do you want for the Signature key? (%u) " -#~ msgstr "Qual o tamanho de chave desejado? (1024) " - -#, fuzzy -#~ msgid "What keysize do you want for the Encryption key? (%u) " -#~ msgstr "Qual o tamanho de chave desejado? (1024) " - -#, fuzzy -#~ msgid "What keysize do you want for the Authentication key? (%u) " -#~ msgstr "Qual o tamanho de chave desejado? (1024) " - -#, fuzzy -#~ msgid "listen() failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~| msgid "new configuration file `%s' created\n" -#~ msgid "new configuration file '%s' created\n" -#~ msgstr "criado um novo ficheiro de configuração `%s'\n" - -#, fuzzy -#~| msgid "WARNING: options in `%s' are not yet active during this run\n" -#~ msgid "WARNING: options in '%s' are not yet active during this run\n" -#~ msgstr "AVISO: opções em `%s' ainda não estão activas nesta execução\n" - -#, fuzzy -#~| msgid "Key generation failed: %s\n" -#~ msgid "User ID revocation failed: %s\n" -#~ msgstr "A geração de chaves falhou: %s\n" - -#, fuzzy -#~ msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]" -#~ msgstr "muda a frase secreta" - -#~ msgid "DSA requires the use of a 160 bit hash algorithm\n" -#~ msgstr "" -#~ "DSA necessita de utilização de uma algoritmo de dispersão de 160 bit\n" - -#~ msgid "--store [filename]" -#~ msgstr "--store [nome_do_ficheiro]" - -#~ msgid "--symmetric [filename]" -#~ msgstr "--symmetric [nome_do_ficheiro]" - -#~ msgid "--encrypt [filename]" -#~ msgstr "--encrypt [nome_do_ficheiro]" - -#, fuzzy -#~ msgid "--symmetric --encrypt [filename]" -#~ msgstr "--sign --encrypt [nome_do_ficheiro]" - -#~ msgid "--sign [filename]" -#~ msgstr "--sign [nome_do_ficheiro]" - -#~ msgid "--sign --encrypt [filename]" -#~ msgstr "--sign --encrypt [nome_do_ficheiro]" - -#, fuzzy -#~ msgid "--symmetric --sign --encrypt [filename]" -#~ msgstr "--sign --encrypt [nome_do_ficheiro]" - -#~ msgid "--sign --symmetric [filename]" -#~ msgstr "--sign --symmetric [nome_do_ficheiro]" - -#~ msgid "--clear-sign [filename]" -#~ msgstr "--clear-sign [nome_do_ficheiro]" - -#~ msgid "--decrypt [filename]" -#~ msgstr "--decrypt [nome_do_ficheiro]" - -#~ msgid "--sign-key user-id" -#~ msgstr "--sign-key id-utilizador" - -#~ msgid "--lsign-key user-id" -#~ msgstr "--lsign-key id-utilizador" - -#~ msgid "--edit-key user-id [commands]" -#~ msgstr "--edit-key id-utilizador [comandos]" - -#, fuzzy -#~ msgid "--passwd " -#~ msgstr "--sign-key id-utilizador" - -#~ msgid "[filename]" -#~ msgstr "[nome_do_ficheiro]" - -#, fuzzy -#~ msgid "shadowing the key failed: %s\n" -#~ msgstr "remoção do bloco de chave falhou: %s\n" - -#, fuzzy -#~ msgid "available TOFU policies:\n" -#~ msgstr "desactiva uma chave" - -#, fuzzy -#~ msgid "%ld message signed" -#~ msgid_plural "%ld messages signed" -#~ msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -#~ msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" - -#~ msgid "communication problem with gpg-agent\n" -#~ msgstr "problemas na comunicação com o gpg-agent\n" - -#, fuzzy -#~ msgid "canceled by user\n" -#~ msgstr "cancelado pelo utilizador\n" - -#, fuzzy -#~ msgid "problem with the agent\n" -#~ msgstr "problema com o agente: o agente returnou 0x%lx\n" - -#, fuzzy -#~ msgid "problem with the agent (unexpected response \"%s\")\n" -#~ msgstr "problema com o agente: o agente returnou 0x%lx\n" - -#, fuzzy -#~ msgid "unknown TOFU DB format '%s'\n" -#~ msgstr "destinatário por omissão desconhecido `%s'\n" - -#, fuzzy -#~ msgid "" -#~ "Please enter the passphrase to unlock the secret key for the OpenPGP " -#~ "certificate:\n" -#~ "\"%.*s\"\n" -#~ "%u-bit %s key, ID %s,\n" -#~ "created %s%s.\n" -#~ msgstr "" -#~ "Precisa de uma frase secreta para desbloquear a chave secreta do " -#~ "utilizador:\n" -#~ "\n" -#~ "\"%.*s\"\n" -#~ "chave %u bits %s, ID %08lx, criada %s%s\n" - -#, fuzzy -#~ msgid "" -#~ "You need a passphrase to unlock the secret key for\n" -#~ "user: \"%s\"\n" -#~ msgstr "" -#~ "\n" -#~ "Você precisa de uma frase secreta para desbloquear a chave secreta do\n" -#~ "utilizador: \"" - -#, fuzzy -#~ msgid "%u-bit %s key, ID %s, created %s" -#~ msgstr "chave de %u-bit/%s, ID %08lX, criada em %s" - -#, fuzzy -#~ msgid "can't access directory '%s': %s\n" -#~ msgstr "%s: impossível criar directoria: %s\n" - -#~ msgid "you found a bug ... (%s:%d)\n" -#~ msgstr "você encontrou um bug ... (%s:%d)\n" - -#, fuzzy -#~| msgid "%d user IDs without valid self-signatures detected\n" -#~ msgid "%d user ID without valid self-signature detected\n" -#~ msgid_plural "%d user IDs without valid self-signatures detected\n" -#~ msgstr[0] "%d IDs de utilizadores sem auto-assinaturas válidas detectados\n" -#~ msgstr[1] "%d IDs de utilizadores sem auto-assinaturas válidas detectados\n" - -#~ msgid "moving a key signature to the correct place\n" -#~ msgstr "a mover a assinatura da chave para o local correcto\n" - -#~ msgid "%d signatures not checked due to missing keys\n" -#~ msgstr "%d assinaturas não verificadas por falta de chaves\n" - -#~ msgid "%d signatures not checked due to errors\n" -#~ msgstr "%d assinaturas não verificadas devido a erros\n" - -#~ msgid "1 user ID without valid self-signature detected\n" -#~ msgstr "1 ID de utilizador sem auto-assinatura válida detectado\n" - -#, fuzzy -#~ msgid "User ID \"%s\": %d signatures removed\n" -#~ msgstr "Utilizador \"%s\" está revocado." - -#~ msgid "" -#~ "You need a Passphrase to protect your secret key.\n" -#~ "\n" -#~ msgstr "" -#~ "Você precisa de uma frase secreta para proteger a sua chave.\n" -#~ "\n" - -#, fuzzy -#~ msgid "" -#~ "Please enter a passphrase to protect the off-card backup of the new " -#~ "encryption key." -#~ msgstr "Por favor digite a frase secreta \n" - -#~ msgid "passphrase not correctly repeated; try again" -#~ msgstr "a frase secreta não foi repetida corretamente; tente outra vez" - -#~ msgid "%s.\n" -#~ msgstr "%s.\n" - -#~ msgid "" -#~ "You don't want a passphrase - this is probably a *bad* idea!\n" -#~ "I will do it anyway. You can change your passphrase at any time,\n" -#~ "using this program with the option \"--edit-key\".\n" -#~ "\n" -#~ msgstr "" -#~ "Você não quer uma frase secreta - provavelmente isto é uma *má* idéia!\n" -#~ "Vou continuar assim mesmo. Você pode mudar sua frase secreta a\n" -#~ "qualquer hora, usando este programa com a opção \"--edit-key\".\n" -#~ "\n" - -#, fuzzy -#~ msgid "storing key onto card failed: %s\n" -#~ msgstr "remoção do bloco de chave falhou: %s\n" - -#, fuzzy -#~| msgid "1 bad signature\n" -#~ msgid "1 good signature\n" -#~ msgstr "1 assinatura incorrecta\n" - -#, fuzzy -#~ msgid "%lu keys cached (%lu signatures)\n" -#~ msgstr "%lu chave verificadas (%lu assinaturas)\n" - -#, fuzzy -#~ msgid "refreshing 1 key from %s\n" -#~ msgstr "a pedir a chave %08lX de %s\n" - -#, fuzzy -#~ msgid "sending key %s to %s server %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "public key %s is %lu seconds newer than the signature\n" -#~ msgstr "a chave pública %08lX é %lu segundos mais nova que a assinatura\n" - -#, fuzzy -#~ msgid "" -#~ "key %s was created %lu seconds in the future (time warp or clock " -#~ "problem)\n" -#~ msgstr "" -#~ "a chave foi criada %lu segundos no futuro\n" -#~ "(viagem no tempo ou problema no relógio)\n" - -#, fuzzy -#~| msgid "can't open the keyring" -#~ msgid "Failed to open the keyring DB.\n" -#~ msgstr "não é possível abrir o porta-chaves" - -#, fuzzy -#~ msgid "Failed to parse '%s'.\n" -#~ msgstr "impossível abrir `%s': %s\n" - -#, fuzzy -#~ msgid "error looking up secret key \"%s\": %s\n" -#~ msgstr "erro na leitura do bloco de chave secreto `%s': %s\n" - -#, fuzzy -#~ msgid "Please select at most one subkey.\n" -#~ msgstr "Por favor seleccione no máximo uma chave secundária.\n" - -#, fuzzy -#~ msgid "malformed %s environment variable\n" -#~ msgstr "variável de ambiente GPG_AGENT_INFO inválida\n" - -#, fuzzy -#~ msgid "dirmngr protocol version %d is not supported\n" -#~ msgstr "a versão %d do protocolo gpg-agent não é suportada\n" - -#, fuzzy -#~ msgid "toggle between the secret and public key listings" -#~ msgstr "alterna entre listagem de chave secreta e pública" - -#, fuzzy -#~ msgid "WARNING: keyserver option '%s' is not used on this platform\n" -#~ msgstr "AVISO: opções em `%s' ainda não estão activas nesta execução\n" - -#~ msgid "gpg-agent is not available in this session\n" -#~ msgstr "o gpg-agent não está disponível nesta sessão\n" - -#, fuzzy -#~ msgid "use a standard location for the socket" -#~ msgstr "" -#~ "Realmente actualizar as preferências para os utilizadores seleccionados?" - -#, fuzzy -#~ msgid "Usage: gpg-agent [options] (-h for help)" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#~ msgid "malformed GPG_AGENT_INFO environment variable\n" -#~ msgstr "variável de ambiente GPG_AGENT_INFO inválida\n" - -#~ msgid "gpg-agent protocol version %d is not supported\n" -#~ msgstr "a versão %d do protocolo gpg-agent não é suportada\n" - -#, fuzzy -#~ msgid "can't fdopen pipe for reading: %s\n" -#~ msgstr "impossível abrir %s: %s\n" - -#, fuzzy -#~ msgid "error creating socket: %s\n" -#~ msgstr "erro ao criar `%s': %s\n" - -#, fuzzy -#~ msgid "host not found" -#~ msgstr "[Utilizador não encontrado]" - -#, fuzzy -#~ msgid "unknown key protection algorithm\n" -#~ msgstr "algoritmo de compressão desconhecido" - -#, fuzzy -#~ msgid "secret parts of key are not available\n" -#~ msgstr "Componentes secretas da chave primária não disponíveis.\n" - -#, fuzzy -#~ msgid "secret key already stored on a card\n" -#~ msgstr "ignorado: a chave secreta já está presente\n" - -#, fuzzy -#~ msgid "error writing key to card: %s\n" -#~ msgstr "erro na escrita do porta-chaves `%s': %s\n" - -#~ msgid "" -#~ "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n" -#~ msgstr "" -#~ "no modo --pgp2 só pode cifrar com chaves RSA de 2048 bits ou menos\n" - -#~ msgid "" -#~ "unable to use the IDEA cipher for all of the keys you are encrypting to.\n" -#~ msgstr "" -#~ "impossível utilizar a cifra IDEA para todas as chaves para que está a " -#~ "cifrar.\n" - -#, fuzzy -#~ msgid "remove the passphrase from exported subkeys" -#~ msgstr "revoga uma chave secundária" - -#, fuzzy -#~ msgid "key %s: not protected - skipped\n" -#~ msgstr "chave %08lX: não está protegida - ignorada\n" - -#, fuzzy -#~ msgid "failed to unprotect the subkey: %s\n" -#~ msgstr "falha ao inicializar a base de dados de confiança: %s\n" - -#~ msgid "too many entries in pk cache - disabled\n" -#~ msgstr "entradas demais no cache pk - desactivado\n" - -#, fuzzy -#~ msgid "no secret subkey for public subkey %s - ignoring\n" -#~ msgstr "há uma chave secreta para a chave pública \"%s\"!\n" - -#, fuzzy -#~ msgid "key %s: secret key without public key - skipped\n" -#~ msgstr "chave %08lX: chave secreta sem chave pública - ignorada\n" - -#~ msgid "usage: gpg [options] " -#~ msgstr "uso: gpg [opções] " - -#~ msgid "" -#~ "you can only make detached or clear signatures while in --pgp2 mode\n" -#~ msgstr "" -#~ "só pode fazer assinaturas separadas ou em texto puro no modo --pgp2\n" - -#~ msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n" -#~ msgstr "não pode assinar e cifrar ao mesmo tempo no modo --pgp2\n" - -#~ msgid "" -#~ "you must use files (and not a pipe) when working with --pgp2 enabled.\n" -#~ msgstr "" -#~ "deve utilizar ficheiros (e não um 'pipe') quando trabalho no modo --" -#~ "pgp2.\n" - -#~ msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n" -#~ msgstr "cifrar uma mensagem no modo --pgp2 necessita da cifra IDEA\n" - -#, fuzzy -#~ msgid "key %s: already in secret keyring\n" -#~ msgstr "chave %08lX: já está no porta-chaves secreto\n" - -#, fuzzy -#~ msgid "key %s: secret key not found: %s\n" -#~ msgstr "chave %08lX: chave secreta não encontrada: %s\n" - -#, fuzzy -#~ msgid "NOTE: primary key is online and stored on card\n" -#~ msgstr "ignorado: a chave secreta já está presente\n" - -#, fuzzy -#~ msgid "NOTE: secondary key is online and stored on card\n" -#~ msgstr "ignorado: a chave secreta já está presente\n" - -#~ msgid "" -#~ "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 " -#~ "mode.\n" -#~ msgstr "" -#~ "Não pode criar uma assinatura OpenPGP numa chave PGP 2.x no modo --pgp2.\n" - -#~ msgid "This would make the key unusable in PGP 2.x.\n" -#~ msgstr "Isto tornaria a chave inutilizável no PGP 2.x.\n" - -#~ msgid "This key is not protected.\n" -#~ msgstr "Esta chave não é protegida.\n" - -#~ msgid "Key is protected.\n" -#~ msgstr "A chave é protegida.\n" - -#~ msgid "Can't edit this key: %s\n" -#~ msgstr "Impossível editar esta chave: %s\n" - -#~ msgid "" -#~ "Enter the new passphrase for this secret key.\n" -#~ "\n" -#~ msgstr "" -#~ "Digite a nova frase para esta chave secreta.\n" -#~ "\n" - -#~ msgid "" -#~ "You don't want a passphrase - this is probably a *bad* idea!\n" -#~ "\n" -#~ msgstr "" -#~ "Você não quer uma frase secreta - provavelmente isto é uma *má* idéia!\n" -#~ "\n" - -#, fuzzy -#~ msgid "Do you really want to do this? (y/N) " -#~ msgstr "Você quer realmente fazer isso? " - -#~ msgid "Please remove selections from the secret keys.\n" -#~ msgstr "Por favor remova as selecções das chaves secretas.\n" - -#~ msgid "No corresponding signature in secret ring\n" -#~ msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" - -#, fuzzy -#~ msgid "writing secret key stub to `%s'\n" -#~ msgstr "a escrever chave privada para `%s'\n" - -#~ msgid "writing secret key to `%s'\n" -#~ msgstr "a escrever chave privada para `%s'\n" - -#~ msgid "no writable secret keyring found: %s\n" -#~ msgstr "" -#~ "nenhum porta-chaves secreto com permissões de escrita encontrado: %s\n" - -#~ msgid "WARNING: 2 files with confidential information exists.\n" -#~ msgstr "AVISO: existem 2 ficheiros com informações confidenciais.\n" - -#~ msgid "%s is the unchanged one\n" -#~ msgstr "%s é o não modificado\n" - -#~ msgid "%s is the new one\n" -#~ msgstr "%s é o novo\n" - -#~ msgid "Please fix this possible security flaw\n" -#~ msgstr "Por favor conserte esta possível falha de segurança\n" - -#, fuzzy -#~ msgid "searching for names from %s server %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "searching for names from %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "searching for \"%s\" from %s server %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "searching for \"%s\" from %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "keyserver timed out\n" -#~ msgstr "erro do servidor de chaves" - -#, fuzzy -#~ msgid "keyserver internal error\n" -#~ msgstr "erro do servidor de chaves" - -#, fuzzy -#~ msgid "keyserver communications error: %s\n" -#~ msgstr "A geração de chaves falhou: %s\n" - -#, fuzzy -#~ msgid "WARNING: unable to parse URI %s\n" -#~ msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" - -#~ msgid "invalid root packet detected in proc_tree()\n" -#~ msgstr "pacote raiz inválido detectado em proc_tree()\n" - -#~ msgid "the IDEA cipher plugin is not present\n" -#~ msgstr "o 'plugin' com a cifra IDEA não está presente\n" - -#, fuzzy -#~ msgid "no corresponding public key: %s\n" -#~ msgstr "a escrever chave pública para `%s'\n" - -#, fuzzy -#~ msgid "unknown protection algorithm\n" -#~ msgstr "algoritmo de compressão desconhecido" - -#, fuzzy -#~ msgid "NOTE: This key is not protected!\n" -#~ msgstr "Esta chave não é protegida.\n" - -#, fuzzy -#~ msgid "protection digest %d is not supported\n" -#~ msgstr "algoritmo de protecção %d%s não é suportado\n" - -#~ msgid "Invalid passphrase; please try again" -#~ msgstr "Frase secreta inválida; por favor tente novamente" - -#~ msgid "%s ...\n" -#~ msgstr "%s ...\n" - -#~ msgid "WARNING: Weak key detected - please change passphrase again.\n" -#~ msgstr "" -#~ "AVISO: Chave fraca detectada - por favor mude a frase secreta novamente.\n" - -#~ msgid "" -#~ "generating the deprecated 16-bit checksum for secret key protection\n" -#~ msgstr "" -#~ "a gerar a 'checksum' (depreciada) de 16-bit para protecção da chave " -#~ "secreta\n" - -#~ msgid "" -#~ "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n" -#~ msgstr "" -#~ "só pode assinar-desligar com chaves do tipo PGP 2.x no modo --pgp2\n" - -#~ msgid "" -#~ "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n" -#~ msgstr "só pode assinar à vista com chaves do tipo PGP 2.x no modo --pgp2\n" - -#, fuzzy -#~ msgid "Usage: scdaemon [options] (-h for help)" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#, fuzzy -#~ msgid "Usage: gpgsm [options] [files] (-h for help)" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#, fuzzy -#~ msgid "usage: gpgconf [options] " -#~ msgstr "uso: gpg [opções] " - -#, fuzzy -#~ msgid "failed to allocated keyDB handle\n" -#~ msgstr "falha ao inicializar a base de dados de confiança: %s\n" - -#~ msgid "Command> " -#~ msgstr "Comando> " - -#~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n" -#~ msgstr "" -#~ "A base de dados de confiança está danificada; por favor execute\n" -#~ "\"gpg --fix-trustdb\".\n" - -#~ msgid "Please report bugs to .\n" -#~ msgstr "Por favor comunique bugs para .\n" - -#, fuzzy -#~ msgid "Please report bugs to " -#~ msgstr "Por favor comunique bugs para .\n" - -#, fuzzy -#~ msgid "DSA keypair will have %u bits.\n" -#~ msgstr "O par de chaves DSA terá 1024 bits.\n" - -#~ msgid "Repeat passphrase\n" -#~ msgstr "Repita a frase secreta\n" - -#, fuzzy -#~ msgid "read options from file" -#~ msgstr "a ler opções de `%s'\n" - -#~ msgid "|[file]|make a signature" -#~ msgstr "|[ficheiro]|fazer uma assinatura" - -#, fuzzy -#~ msgid "|[FILE]|make a signature" -#~ msgstr "|[ficheiro]|fazer uma assinatura" - -#, fuzzy -#~ msgid "|[FILE]|make a clear text signature" -#~ msgstr "|[ficheiro]|fazer uma assinatura em texto puro" - -#~ msgid "use the default key as default recipient" -#~ msgstr "usar a chave por omissão como destinatário por omissão" - -#~ msgid "force v3 signatures" -#~ msgstr "forçar assinaturas v3" - -#~ msgid "always use a MDC for encryption" -#~ msgstr "sempre usar um MDC para cifrar" - -#~ msgid "add this secret keyring to the list" -#~ msgstr "adicionar este porta-chaves secreto à lista" - -#~ msgid "|FILE|load extension module FILE" -#~ msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" - -#~ msgid "|N|use compress algorithm N" -#~ msgstr "|N|usar algoritmo de compressão N" - -#, fuzzy -#~ msgid "remove key from the public keyring" -#~ msgstr "remover chaves do porta-chaves público" - -#~ msgid "" -#~ "It's up to you to assign a value here; this value will never be exported\n" -#~ "to any 3rd party. We need it to implement the web-of-trust; it has " -#~ "nothing\n" -#~ "to do with the (implicitly created) web-of-certificates." -#~ msgstr "" -#~ "Você decide que valor usar aqui; este valor nunca será exportado para\n" -#~ "terceiros. Precisamos dele implementar a rede de confiança, que não tem\n" -#~ "nada a ver com a rede de certificados (implicitamente criada)." - -#~ msgid "" -#~ "To build the Web-of-Trust, GnuPG needs to know which keys are\n" -#~ "ultimately trusted - those are usually the keys for which you have\n" -#~ "access to the secret key. Answer \"yes\" to set this key to\n" -#~ "ultimately trusted\n" -#~ msgstr "" -#~ "Para construir a Teia-de-Confiança ('Web-of-Trust'), o GnuPG precisa de\n" -#~ "saber quais são as chaves em que deposita confiança absoluta - " -#~ "normalmente\n" -#~ "estas são as chaves a que tem acesso à chave privada. Responda \"sim\" " -#~ "para\n" -#~ "que esta chave seja de confiança absoluta.\n" - -#~ msgid "If you want to use this untrusted key anyway, answer \"yes\"." -#~ msgstr "" -#~ "Se você quiser usar esta chave, não de confiança, assim mesmo, responda " -#~ "\"sim\"." - -#~ msgid "" -#~ "Enter the user ID of the addressee to whom you want to send the message." -#~ msgstr "" -#~ "Digite o ID de utilizador do destinatário para quem quer enviar a\n" -#~ "mensagem." - -#~ msgid "" -#~ "In general it is not a good idea to use the same key for signing and\n" -#~ "encryption. This algorithm should only be used in certain domains.\n" -#~ "Please consult your security expert first." -#~ msgstr "" -#~ "Em geral não é uma boa ideia utilizar a mesma chave para assinar e para\n" -#~ "cifrar. Este algoritmo só deve ser utilizado em alguns domínios.\n" -#~ "Por favor consulte primeiro o seu perito em segurança." - -#~ msgid "Enter the size of the key" -#~ msgstr "Insira o tamanho da chave" - -#~ msgid "Answer \"yes\" or \"no\"" -#~ msgstr "Responda \"sim\" ou \"não\"" - -#~ msgid "" -#~ "Enter the required value as shown in the prompt.\n" -#~ "It is possible to enter a ISO date (YYYY-MM-DD) but you won't\n" -#~ "get a good error response - instead the system tries to interpret\n" -#~ "the given value as an interval." -#~ msgstr "" -#~ "Digite o valor necessário conforme pedido.\n" -#~ "É possível digitar uma data ISO (AAAA-MM-DD) mas você não terá uma boa\n" -#~ "reacção a erros - o sistema tentará interpretar o valor dado como um " -#~ "intervalo." - -#~ msgid "Enter the name of the key holder" -#~ msgstr "Digite o nome do possuidor da chave" - -#~ msgid "please enter an optional but highly suggested email address" -#~ msgstr "por favor digite um endereço de email (opcional mas recomendado)" - -#~ msgid "Please enter an optional comment" -#~ msgstr "Por favor digite um comentário (opcional)" - -#~ msgid "" -#~ "N to change the name.\n" -#~ "C to change the comment.\n" -#~ "E to change the email address.\n" -#~ "O to continue with key generation.\n" -#~ "Q to to quit the key generation." -#~ msgstr "" -#~ "N para mudar o nome.\n" -#~ "C para mudar o comentário.\n" -#~ "E para mudar o endereço de email\n" -#~ "O para continuar a geração da chave.\n" -#~ "S para interromper a geração da chave." - -#~ msgid "" -#~ "Answer \"yes\" (or just \"y\") if it is okay to generate the sub key." -#~ msgstr "Responda \"sim\" (ou apenas \"s\") se quiser gerar a subchave." - -#~ msgid "" -#~ "When you sign a user ID on a key, you should first verify that the key\n" -#~ "belongs to the person named in the user ID. It is useful for others to\n" -#~ "know how carefully you verified this.\n" -#~ "\n" -#~ "\"0\" means you make no particular claim as to how carefully you verified " -#~ "the\n" -#~ " key.\n" -#~ "\n" -#~ "\"1\" means you believe the key is owned by the person who claims to own " -#~ "it\n" -#~ " but you could not, or did not verify the key at all. This is useful " -#~ "for\n" -#~ " a \"persona\" verification, where you sign the key of a pseudonymous " -#~ "user.\n" -#~ "\n" -#~ "\"2\" means you did casual verification of the key. For example, this " -#~ "could\n" -#~ " mean that you verified the key fingerprint and checked the user ID on " -#~ "the\n" -#~ " key against a photo ID.\n" -#~ "\n" -#~ "\"3\" means you did extensive verification of the key. For example, this " -#~ "could\n" -#~ " mean that you verified the key fingerprint with the owner of the key " -#~ "in\n" -#~ " person, and that you checked, by means of a hard to forge document " -#~ "with a\n" -#~ " photo ID (such as a passport) that the name of the key owner matches " -#~ "the\n" -#~ " name in the user ID on the key, and finally that you verified (by " -#~ "exchange\n" -#~ " of email) that the email address on the key belongs to the key " -#~ "owner.\n" -#~ "\n" -#~ "Note that the examples given above for levels 2 and 3 are *only* " -#~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" -#~ "mean to you when you sign other keys.\n" -#~ "\n" -#~ "If you don't know what the right answer is, answer \"0\"." -#~ msgstr "" -#~ "Quando assina uma chave de identificação de um utilizador, deve primeiro\n" -#~ "verificar que a chave pertence realmente à pessoa em questão. É útil " -#~ "para\n" -#~ "terceiros saberem com que cuidado é que efectuou esta verificação.\n" -#~ "\n" -#~ "\"0\" significa que não deseja declarar a forma com verificou a chave\n" -#~ "\n" -#~ "\"1\" significa que acredita que a chave pertence à pessoa em questão, " -#~ "mas\n" -#~ " não conseguiu ou não tentou verificar. Este grau é útil para quando\n" -#~ " assina a chave de uma utilizador pseudo-anónimo.\n" -#~ "\n" -#~ "\"2\" significa que efectuou uma verificação normal da chave. Por " -#~ "exemplo,\n" -#~ " isto pode significar que verificou a impressão digital da chave e\n" -#~ " verificou o identificador de utilizador da chave contra uma " -#~ "identificação\n" -#~ " fotográfica.\n" -#~ "\n" -#~ "\"3\" significa que efectuou uma verificação exaustiva da chave. Por " -#~ "exemplo,\n" -#~ " isto pode significar que efectuou a verificação pessoalmente, e que \n" -#~ " utilizou um documento, com fotografia, difícil de falsificar \n" -#~ " (como por exemplo um passaporte) que o nome do dono da chave é o\n" -#~ " mesmo do que o identificador da chave, e que, finalmente, verificou\n" -#~ " (através de troca de e-mail) que o endereço de email da chave " -#~ "pertence\n" -#~ " ao done da chave.\n" -#~ "\n" -#~ "Atenção: os exemplos dados para os níveis 2 e 3 são *apenas* exemplos.\n" -#~ "Compete-lhe a si decidir o que considera, ao assinar chaves, uma " -#~ "verificação\n" -#~ "\"normal\" e uma verificação \"exaustiva\".\n" -#~ "\n" -#~ "Se não sabe qual é a resposta correcta, responda \"0\"." - -#, fuzzy -#~ msgid "Answer \"yes\" if you want to sign ALL the user IDs" -#~ msgstr "Responda \"sim\" se quiser assinar TODOS os IDs de utilizador" - -#~ msgid "" -#~ "Answer \"yes\" if you really want to delete this user ID.\n" -#~ "All certificates are then also lost!" -#~ msgstr "" -#~ "Responda \"sim\" se quiser realmente remover este ID de utilizador.\n" -#~ "Todos os certificados também serão perdidos!" - -#~ msgid "Answer \"yes\" if it is okay to delete the subkey" -#~ msgstr "Responda \"sim\" se quiser remover a subchave" - -#~ msgid "" -#~ "This is a valid signature on the key; you normally don't want\n" -#~ "to delete this signature because it may be important to establish a\n" -#~ "trust connection to the key or another key certified by this key." -#~ msgstr "" -#~ "Esta é uma assinatura válida na chave; normalmente não é desejável\n" -#~ "remover esta assinatura porque ela pode ser importante para estabelecer\n" -#~ "uma conexão de confiança à chave ou a outra chave certificada por esta." - -#~ msgid "" -#~ "This signature can't be checked because you don't have the\n" -#~ "corresponding key. You should postpone its deletion until you\n" -#~ "know which key was used because this signing key might establish\n" -#~ "a trust connection through another already certified key." -#~ msgstr "" -#~ "Esta assinatura não pode ser verificada porque você não tem a chave\n" -#~ "correspondente. Você deve adiar sua remoção até saber que chave foi " -#~ "usada\n" -#~ "porque a chave desta assinatura pode estabelecer uma conexão de " -#~ "confiança\n" -#~ "através de outra chave já certificada." - -#~ msgid "" -#~ "The signature is not valid. It does make sense to remove it from\n" -#~ "your keyring." -#~ msgstr "" -#~ "A assinatura não é válida. Faz sentido removê-la do seu porta-chaves." - -#~ msgid "" -#~ "This is a signature which binds the user ID to the key. It is\n" -#~ "usually not a good idea to remove such a signature. Actually\n" -#~ "GnuPG might not be able to use this key anymore. So do this\n" -#~ "only if this self-signature is for some reason not valid and\n" -#~ "a second one is available." -#~ msgstr "" -#~ "Esta é uma assinatura que liga o ID de utilizador à chave. Geralmente\n" -#~ "não é uma boa idéia remover tal assinatura. É possível que o GnuPG\n" -#~ "não consiga mais usar esta chave. Faça isto apenas se por alguma\n" -#~ "razão esta auto-assinatura não for válida e há uma segunda disponível." - -#~ msgid "" -#~ "Change the preferences of all user IDs (or just of the selected ones)\n" -#~ "to the current list of preferences. The timestamp of all affected\n" -#~ "self-signatures will be advanced by one second.\n" -#~ msgstr "" -#~ "Muda as preferências de todos os identificadores de utilizadores\n" -#~ "(ou apenas dos seleccionados) para a lista actual de preferências.\n" -#~ "O 'timestamp' de todas as auto-assinaturas afectuadas será avançado\n" -#~ "em um segundo.\n" - -#~ msgid "Please enter the passphrase; this is a secret sentence \n" -#~ msgstr "Por favor digite a frase secreta \n" - -#~ msgid "" -#~ "Please repeat the last passphrase, so you are sure what you typed in." -#~ msgstr "Por favor repita a frase secreta, para ter certeza do que digitou." - -#~ msgid "Give the name of the file to which the signature applies" -#~ msgstr "Dê o nome para o ficheiro ao qual a assinatura se aplica" - -#~ msgid "Answer \"yes\" if it is okay to overwrite the file" -#~ msgstr "Responda \"sim\" se quiser escrever por cima do ficheiro" - -#~ msgid "" -#~ "Please enter a new filename. If you just hit RETURN the default\n" -#~ "file (which is shown in brackets) will be used." -#~ msgstr "" -#~ "Por favor digite um novo nome de ficheiro. Se você apenas carregar em " -#~ "RETURN\n" -#~ "o ficheiro por omissão (que é mostrado entre parênteses) será utilizado." - -#~ msgid "" -#~ "You should specify a reason for the certification. Depending on the\n" -#~ "context you have the ability to choose from this list:\n" -#~ " \"Key has been compromised\"\n" -#~ " Use this if you have a reason to believe that unauthorized persons\n" -#~ " got access to your secret key.\n" -#~ " \"Key is superseded\"\n" -#~ " Use this if you have replaced this key with a newer one.\n" -#~ " \"Key is no longer used\"\n" -#~ " Use this if you have retired this key.\n" -#~ " \"User ID is no longer valid\"\n" -#~ " Use this to state that the user ID should not longer be used;\n" -#~ " this is normally used to mark an email address invalid.\n" -#~ msgstr "" -#~ "Deve especificar uma razão para a emissão do certificado. Dependendo no\n" -#~ "contexto, pode escolher as seguintes opções desta lista:\n" -#~ " \"A chave foi comprometida\"\n" -#~ " Utilize esta opção se tem razões para acreditar que indivíduos não\n" -#~ " autorizados obtiveram acesso à sua chave secreta.\n" -#~ " \"A chave foi substituida\"\n" -#~ " Utilize esta opção se substituiu esta chave com uma mais recente.\n" -#~ " \"A chave já não é utilizada\"\n" -#~ " Utilize esta opção se já não utiliza a chave.\n" -#~ " \"O identificador do utilizador já não é válido\"\n" -#~ " Utilize esta opção para comunicar que o identificador do utilizador\n" -#~ " não deve ser mais utilizado; normalmente utilizada para indicar\n" -#~ " que um endereço de email é inválido.\n" - -#~ msgid "" -#~ "If you like, you can enter a text describing why you issue this\n" -#~ "revocation certificate. Please keep this text concise.\n" -#~ "An empty line ends the text.\n" -#~ msgstr "" -#~ "Se desejar, pode inserir uma texto descrevendo a razão pela qual criou\n" -#~ "este certificado de revogação. Por favor mantenha este texto conciso.\n" -#~ "Uma linha vazia termina o texto.\n" - -#, fuzzy -#~ msgid "can't put notation data into v3 (PGP 2.x style) signatures\n" -#~ msgstr "não pode escolher uma chave do tipo PGP 2.x como revogadora\n" - -#, fuzzy -#~ msgid "can't put notation data into v3 (PGP 2.x style) key signatures\n" -#~ msgstr "não pode escolher uma chave do tipo PGP 2.x como revogadora\n" - -#, fuzzy -#~ msgid "can't put a policy URL into v3 (PGP 2.x style) signatures\n" -#~ msgstr "não pode escolher uma chave do tipo PGP 2.x como revogadora\n" - -#, fuzzy -#~ msgid "shelll" -#~ msgstr "help" - -#, fuzzy -#~ msgid "" -#~ "please see http://www.gnupg.org/download/iconv.html for more information\n" -#~ msgstr "" -#~ "por favor veja http://www.gnupg.org/faq.html para mais informações\n" - -#, fuzzy -#~ msgid "key generation is not available from the commandline\n" -#~ msgstr "o gpg-agent não está disponível nesta sessão\n" - -#, fuzzy -#~ msgid "please use the script \"%s\" to generate a new key\n" -#~ msgstr "Por favor selecione o tipo de chave desejado:\n" - -#, fuzzy -#~ msgid "cipher extension `%s' not loaded due to unsafe permissions\n" -#~ msgstr "" -#~ "a extensão de cifra \"%s\" não foi carregada devido às suas permissões " -#~ "inseguras\n" - -#, fuzzy -#~ msgid ".\n" -#~ msgstr "%s.\n" - -#~ msgid "problem with the agent - disabling agent use\n" -#~ msgstr "problema com o agente - a desactivar a utilização deste\n" - -#, fuzzy -#~ msgid "can't query passphrase in batch mode\n" -#~ msgstr "impossível pedir senha em modo não-interactivo\n" - -#~ msgid "Repeat passphrase: " -#~ msgstr "Repita a frase secreta: " - -#~ msgid "-k[v][v][v][c] [user-id] [keyring]" -#~ msgstr "-k[v][v][v][c] [id-utilizador] [porta-chaves]" - -#~ msgid "no entropy gathering module detected\n" -#~ msgstr "nenhum módulo de recolha de entropia detectado\n" - -#, fuzzy -#~ msgid "can't lock `%s': %s\n" -#~ msgstr "impossível abrir `%s'\n" - -#~ msgid "`%s' is not a regular file - ignored\n" -#~ msgstr "`%s' não é um ficheiro normal - ignorado\n" - -#~ msgid "note: random_seed file is empty\n" -#~ msgstr "nota: random_seed está vazia\n" - -#~ msgid "can't read `%s': %s\n" -#~ msgstr "impossível ler `%s': %s\n" - -#~ msgid "note: random_seed file not updated\n" -#~ msgstr "nota: ficheiro random_seed não actualizado\n" - -#~ msgid "can't write `%s': %s\n" -#~ msgstr "impossível escrever `%s': %s\n" - -#~ msgid "can't close `%s': %s\n" -#~ msgstr "impossível fechar `%s': %s\n" - -#~ msgid "WARNING: using insecure random number generator!!\n" -#~ msgstr "AVISO: a utilizar gerador de números aleatórios inseguro!\n" - -#~ msgid "" -#~ "The random number generator is only a kludge to let\n" -#~ "it run - it is in no way a strong RNG!\n" -#~ "\n" -#~ "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n" -#~ "\n" -#~ msgstr "" -#~ "O gerador de números aleatórios é apenas um \"remendo\"\n" -#~ "para poder funcionar - não é de modo algum um bom gerador!\n" -#~ "\n" -#~ "NÃO USE NENHUM DADO GERADO POR ESTE PROGRAMA!\n" -#~ "\n" - -#~ msgid "" -#~ "\n" -#~ "Not enough random bytes available. Please do some other work to give\n" -#~ "the OS a chance to collect more entropy! (Need %d more bytes)\n" -#~ msgstr "" -#~ "\n" -#~ "Não há bytes aleatórios suficientes. Por favor, faça outro trabalho para\n" -#~ "que o sistema possa recolher mais entropia! (São necessários mais %d " -#~ "bytes)\n" - -#, fuzzy -#~ msgid "card reader not available\n" -#~ msgstr "chave secreta não disponível" - -#, fuzzy -#~ msgid "NOTE: %s is not available in this version\n" -#~ msgstr "o gpg-agent não está disponível nesta sessão\n" - -#, fuzzy -#~ msgid " algorithms on these user IDs:\n" -#~ msgstr "Assinou estes identificadores de utilizadores:\n" - -#~ msgid "general error" -#~ msgstr "erro geral" - -#~ msgid "unknown packet type" -#~ msgstr "formato de pacote desconhecido" - -#~ msgid "unknown digest algorithm" -#~ msgstr "algoritmo de \"digest\" desconhecido" - -#~ msgid "bad public key" -#~ msgstr "chave pública incorrecta" - -#~ msgid "bad secret key" -#~ msgstr "chave secreta incorrecta" - -#~ msgid "bad signature" -#~ msgstr "assinatura incorrecta" - -#~ msgid "checksum error" -#~ msgstr "erro de \"checksum\"" - -#~ msgid "unknown cipher algorithm" -#~ msgstr "algoritmo de criptografia desconhecido" - -#~ msgid "invalid packet" -#~ msgstr "pacote inválido" - -#~ msgid "no such user id" -#~ msgstr "identificador de utilizador inexistente" - -#~ msgid "secret key not available" -#~ msgstr "chave secreta não disponível" - -#~ msgid "wrong secret key used" -#~ msgstr "chave secreta incorrecta" - -#~ msgid "bad key" -#~ msgstr "chave incorrecta" - -#~ msgid "file write error" -#~ msgstr "erro de escrita" - -#~ msgid "unknown compress algorithm" -#~ msgstr "algoritmo de compressão desconhecido" - -#~ msgid "file open error" -#~ msgstr "erro na abertura do ficheiro" - -#~ msgid "file create error" -#~ msgstr "erro na criação do ficheiro" - -#~ msgid "unimplemented pubkey algorithm" -#~ msgstr "algoritmo de chave pública não implementado" - -#~ msgid "unimplemented cipher algorithm" -#~ msgstr "algoritmo de criptografia não implementado" - -#~ msgid "unknown signature class" -#~ msgstr "classe de assinatura desconhecida" - -#~ msgid "trust database error" -#~ msgstr "erro na base de dados de confiança" - -#~ msgid "resource limit" -#~ msgstr "limite de recursos" - -#~ msgid "invalid keyring" -#~ msgstr "porta-chaves inválido" - -#~ msgid "malformed user id" -#~ msgstr "identificador de utilizador malformado" - -#~ msgid "file close error" -#~ msgstr "erro ao fechar ficheiro" - -#~ msgid "file rename error" -#~ msgstr "erro na renomeação do ficheiro" - -#~ msgid "file delete error" -#~ msgstr "erro na remoção do ficheiro" - -#~ msgid "timestamp conflict" -#~ msgstr "conflito de \"timestamp\"" - -#~ msgid "unusable pubkey algorithm" -#~ msgstr "algoritmo de chave pública inutilizável" - -#~ msgid "file exists" -#~ msgstr "o ficheiro já existe" - -#~ msgid "weak key" -#~ msgstr "chave fraca" - -#~ msgid "bad URI" -#~ msgstr "URI incorrecto" - -#~ msgid "not processed" -#~ msgstr "não processado" - -#~ msgid "unusable public key" -#~ msgstr "chave pública não utilizável" - -#~ msgid "unusable secret key" -#~ msgstr "chave secreta não utilizável" - -#~ msgid "keyserver error" -#~ msgstr "erro do servidor de chaves" - -#, fuzzy -#~ msgid "no card" -#~ msgstr "não cifrado" - -#, fuzzy -#~ msgid "no data" -#~ msgstr "não há dados assinados\n" - -#~ msgid "... this is a bug (%s:%d:%s)\n" -#~ msgstr "... isto é um bug (%s:%d:%s)\n" - -#~ msgid "operation is not possible without initialized secure memory\n" -#~ msgstr "a operação não é possível sem memória segura inicializada\n" - -#~ msgid "(you may have used the wrong program for this task)\n" -#~ msgstr "(você pode ter usado o programa errado para esta tarefa)\n" - -#~ msgid "" -#~ "please see http://www.gnupg.org/why-not-idea.html for more information\n" -#~ msgstr "veja http://www.gnupg.org/why-not-idea.html para mais informações\n" - -#, fuzzy -#~ msgid "all export-clean-* options from above" -#~ msgstr "ler opções do ficheiro" - -#, fuzzy -#~ msgid "all import-clean-* options from above" -#~ msgstr "ler opções do ficheiro" - -#, fuzzy -#~ msgid "expired: %s)" -#~ msgstr "[expira: %s]" - -#, fuzzy -#~ msgid "key %s: expired signature from key %s - skipped\n" -#~ msgstr "chave %08lX: classe de assinatura inesperada (%02x) - ignorada\n" - -#, fuzzy -#~ msgid "Unable to clean `%s'\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid "No user IDs are removable.\n" -#~ msgstr "o utilizador com o id \"%s\" já está revocado\n" - -#, fuzzy -#~ msgid "bad passphrase or unknown cipher algorithm (%d)\n" -#~ msgstr "algoritmo de criptografia desconhecido" - -#~ msgid "can't set client pid for the agent\n" -#~ msgstr "não consegui colocar o pid do cliente no agente\n" - -#~ msgid "can't get server read FD for the agent\n" -#~ msgstr "não consigo obter FD de leitura no servidor para o agente\n" - -#~ msgid "can't get server write FD for the agent\n" -#~ msgstr "não consigo obter FD de escrita no servidor para o agente\n" - -#~ msgid "select secondary key N" -#~ msgstr "seleciona chave secundária N" - -#~ msgid "list signatures" -#~ msgstr "lista assinaturas" - -#~ msgid "sign the key" -#~ msgstr "assina a chave" - -#~ msgid "add a secondary key" -#~ msgstr "adiciona nova chave secundária" - -#~ msgid "delete signatures" -#~ msgstr "remove assinaturas" - -#~ msgid "updated preferences" -#~ msgstr "preferências actualizadas" - -#~ msgid "No secondary key with index %d\n" -#~ msgstr "Nenhuma chave secundária com índice %d\n" - -#~ msgid "--nrsign-key user-id" -#~ msgstr "--nrsign-key id-utilizador" - -#~ msgid "--nrlsign-key user-id" -#~ msgstr "--nrlsign-key id-utilizador" - -#~ msgid "sign the key non-revocably" -#~ msgstr "assina a chave de forma não-revogável" - -#~ msgid "sign the key locally and non-revocably" -#~ msgstr "assinar a chave localmente e de forma não revogável" - -#~ msgid "q" -#~ msgstr "q" - -#~ msgid "list" -#~ msgstr "list" - -#~ msgid "l" -#~ msgstr "l" - -#~ msgid "debug" -#~ msgstr "debug" - -#, fuzzy -#~ msgid "name" -#~ msgstr "enable" - -#, fuzzy -#~ msgid "login" -#~ msgstr "lsign" - -#, fuzzy -#~ msgid "cafpr" -#~ msgstr "fpr" - -#, fuzzy -#~ msgid "forcesig" -#~ msgstr "revsig" - -#, fuzzy -#~ msgid "generate" -#~ msgstr "erro geral" - -#~ msgid "passwd" -#~ msgstr "passwd" - -#~ msgid "save" -#~ msgstr "save" - -#~ msgid "fpr" -#~ msgstr "fpr" - -#~ msgid "uid" -#~ msgstr "uid" - -#~ msgid "check" -#~ msgstr "check" - -#~ msgid "c" -#~ msgstr "c" - -#~ msgid "sign" -#~ msgstr "sign" - -#~ msgid "s" -#~ msgstr "s" - -#, fuzzy -#~ msgid "tsign" -#~ msgstr "sign" - -#~ msgid "lsign" -#~ msgstr "lsign" - -#~ msgid "nrsign" -#~ msgstr "nrsign" - -#~ msgid "nrlsign" -#~ msgstr "nrlsign" - -#~ msgid "adduid" -#~ msgstr "adduid" - -#~ msgid "addphoto" -#~ msgstr "addphoto" - -#~ msgid "deluid" -#~ msgstr "deluid" - -#~ msgid "delphoto" -#~ msgstr "delphoto" - -#, fuzzy -#~ msgid "addcardkey" -#~ msgstr "addkey" - -#~ msgid "delkey" -#~ msgstr "delkey" - -#~ msgid "addrevoker" -#~ msgstr "addrevoker" - -#~ msgid "delsig" -#~ msgstr "delsig" - -#~ msgid "expire" -#~ msgstr "expire" - -#~ msgid "primary" -#~ msgstr "primary" - -#~ msgid "toggle" -#~ msgstr "toggle" - -#~ msgid "t" -#~ msgstr "t" - -#~ msgid "pref" -#~ msgstr "pref" - -#~ msgid "showpref" -#~ msgstr "showpref" - -#~ msgid "setpref" -#~ msgstr "setpref" - -#~ msgid "updpref" -#~ msgstr "updpref" - -#, fuzzy -#~ msgid "keyserver" -#~ msgstr "erro do servidor de chaves" - -#~ msgid "trust" -#~ msgstr "trust" - -#~ msgid "revsig" -#~ msgstr "revsig" - -#~ msgid "revuid" -#~ msgstr "revuid" - -#~ msgid "revkey" -#~ msgstr "revkey" - -#~ msgid "disable" -#~ msgstr "disable" - -#~ msgid "enable" -#~ msgstr "enable" - -#~ msgid "showphoto" -#~ msgstr "showphoto" - -#~ msgid "" -#~ "About to generate a new %s keypair.\n" -#~ " minimum keysize is 768 bits\n" -#~ " default keysize is 1024 bits\n" -#~ " highest suggested keysize is 2048 bits\n" -#~ msgstr "" -#~ "Prestes a gerar um novo par de chaves %s.\n" -#~ " tamanho mínimo é 768 bits\n" -#~ " tamanho por omissão é 1024 bits\n" -#~ " tamanho máximo sugerido é 2048 bits\n" - -#~ msgid "DSA only allows keysizes from 512 to 1024\n" -#~ msgstr "DSA permite apenas tamanhos de 512 a 1024\n" - -#~ msgid "keysize too small; 1024 is smallest value allowed for RSA.\n" -#~ msgstr "tamanho muito pequeno; 1024 é o valor mínimo permitido para RSA.\n" - -#~ msgid "keysize too small; 768 is smallest value allowed.\n" -#~ msgstr "tamanho muito pequeno; 768 é o valor mínimo permitido.\n" - -#~ msgid "keysize too large; %d is largest value allowed.\n" -#~ msgstr "tamanho muito grande; %d é o valor máximo permitido.\n" - -#~ msgid "" -#~ "Keysizes larger than 2048 are not suggested because\n" -#~ "computations take REALLY long!\n" -#~ msgstr "" -#~ "Tamanhos de chave maiores que 2048 não são recomendados\n" -#~ "porque o tempo de computação é REALMENTE longo!\n" - -#, fuzzy -#~ msgid "Are you sure that you want this keysize? (y/N) " -#~ msgstr "Você tem certeza de que quer este tamanho de chave? " - -#~ msgid "" -#~ "Okay, but keep in mind that your monitor and keyboard radiation is also " -#~ "very vulnerable to attacks!\n" -#~ msgstr "" -#~ "Tudo bem, mas não se esqueça que a radiação do seu monitor e teclado " -#~ "também é extremamente vulnerável a ataques!\n" - -#~ msgid "Experimental algorithms should not be used!\n" -#~ msgstr "Algoritmos experimentais não devem ser usados!\n" - -#~ msgid "" -#~ "this cipher algorithm is deprecated; please use a more standard one!\n" -#~ msgstr "" -#~ "este algoritmo de criptografia está desctualizado; por favor use um " -#~ "algoritmo mais standard!x\n" - -#, fuzzy -#~ msgid "sorry, can't do this in batch mode\n" -#~ msgstr "impossível fazer isso em modo não-interativo\n" - -#, fuzzy -#~ msgid "can't open file `%s': %s\n" -#~ msgstr "impossível abrir %s: %s\n" - -#~ msgid "key %08lX: key has been revoked!\n" -#~ msgstr "chave %08lX: a chave foi revogada!\n" - -#~ msgid "key %08lX: subkey has been revoked!\n" -#~ msgstr "chave %08lX: a subchave foi revogada!\n" - -#~ msgid "%08lX: key has expired\n" -#~ msgstr "%08lX: a chave expirou\n" - -#~ msgid "%08lX: We do NOT trust this key\n" -#~ msgstr "%08lX: Nós NÃO confiamos nesta chave\n" - -#, fuzzy -#~ msgid " (%d) RSA (auth only)\n" -#~ msgstr " (%d) RSA (apenas assinatura)\n" - -#, fuzzy -#~ msgid " (%d) RSA (sign and auth)\n" -#~ msgstr " (%d) RSA (assinatura e cifragem)\n" - -#, fuzzy -#~ msgid " (%d) RSA (encrypt and auth)\n" -#~ msgstr " (%d) RSA (apenas cifragem)\n" - -#, fuzzy -#~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (assinatura e cifragem)\n" - -#~ msgid "%s: can't open: %s\n" -#~ msgstr "%s: impossível abrir: %s\n" - -#~ msgid "%s: WARNING: empty file\n" -#~ msgstr "%s: AVISO: ficheiro vazio\n" - -#, fuzzy -#~ msgid " (%d) I trust marginally\n" -#~ msgstr " %d = Confio moderadamente\n" - -#, fuzzy -#~ msgid " (%d) I trust fully\n" -#~ msgstr " %d = Confio plenamente\n" - -#, fuzzy -#~ msgid "expires" -#~ msgstr "expire" - -#, fuzzy -#~ msgid "" -#~ "\"\n" -#~ "locally signed with your key %s at %s\n" -#~ msgstr "" -#~ "\"\n" -#~ "assinada localmente com a sua chave %08lX em %s\n" - -#~ msgid "%s: can't create lock\n" -#~ msgstr "%s: impossível criar tranca\n" - -#~ msgid "%s: can't make lock\n" -#~ msgstr "%s: impossível criar tranca\n" - -#~ msgid "%s: can't create: %s\n" -#~ msgstr "%s: impossível criar: %s\n" - -#~ msgid "If you want to use this revoked key anyway, answer \"yes\"." -#~ msgstr "" -#~ "Se você quiser usar esta chave revogada assim mesmo, responda \"sim\"." - -#, fuzzy -#~ msgid "Unable to open photo \"%s\": %s\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid "error: no ownertrust value\n" -#~ msgstr "exportar os valores de confiança" - -#~ msgid " (main key ID %08lX)" -#~ msgstr " (ID principal da chave %08lX)" - -#~ msgid "rev! subkey has been revoked: %s\n" -#~ msgstr "rev! subchave foi revogada: %s\n" - -#~ msgid "rev- faked revocation found\n" -#~ msgstr "rev- revogação falsa encontrada\n" - -#, fuzzy -#~ msgid " [expired: %s]" -#~ msgstr "[expira: %s]" - -#~ msgid " [expires: %s]" -#~ msgstr "[expira: %s]" - -#, fuzzy -#~ msgid " [revoked: %s]" -#~ msgstr "revkey" - -#~ msgid "|[files]|encrypt files" -#~ msgstr "|[ficheiros]|cifrar ficheiros" - -#~ msgid "store only" -#~ msgstr "apenas armazenar" - -#~ msgid "|[files]|decrypt files" -#~ msgstr "|[ficheiros]|decifrar ficheiros" - -#~ msgid "sign a key non-revocably" -#~ msgstr "assinar uma chave de forma não revocável" - -#~ msgid "sign a key locally and non-revocably" -#~ msgstr "assinar uma chave localmente e de forma não revocável" - -#~ msgid "list only the sequence of packets" -#~ msgstr "listar apenas as sequências de pacotes" - -#~ msgid "export the ownertrust values" -#~ msgstr "exportar os valores de confiança" - -#~ msgid "unattended trust database update" -#~ msgstr "actualizar automaticamente a base de dados de confiança" - -#~ msgid "fix a corrupted trust database" -#~ msgstr "consertar uma base de dados de confiança" - -#~ msgid "De-Armor a file or stdin" -#~ msgstr "retirar armadura de um ficheiro ou do \"stdin\"" - -#~ msgid "En-Armor a file or stdin" -#~ msgstr "criar armadura para um ficheiro ou \"stdin\"" - -#~ msgid "do not force v3 signatures" -#~ msgstr "não forçar assinaturas v3" - -#~ msgid "force v4 key signatures" -#~ msgstr "forçar assinaturas v4" - -#~ msgid "do not force v4 key signatures" -#~ msgstr "não forçar assinaturas v4" - -#~ msgid "never use a MDC for encryption" -#~ msgstr "nunca usar um MDC para cifrar" - -#~ msgid "|[file]|write status info to file" -#~ msgstr "|[ficheiro]|escrever ifnroamções de estado para o ficheiro" - -#~ msgid "|KEYID|ultimately trust this key" -#~ msgstr "|KEYID|confiar totalmente nesta chave" - -#~ msgid "emulate the mode described in RFC1991" -#~ msgstr "emular o modo descrito no RFC1991" - -#~ msgid "set all packet, cipher and digest options to OpenPGP behavior" -#~ msgstr "" -#~ "configurar todas as opções de pacote, cifragem e \"digest\"\n" -#~ "para comportamento OpenPGP" - -#~ msgid "set all packet, cipher and digest options to PGP 2.x behavior" -#~ msgstr "" -#~ "configurar todas as opções de pacote, cifragem e \"digest\"\n" -#~ "para comportamento PGP 2.x" - -#~ msgid "|NAME|use message digest algorithm NAME for passphrases" -#~ msgstr "" -#~ "|NOME|usar algoritmo de \"digest\" de mensagens NOME\n" -#~ "para frases secretas" - -#~ msgid "throw keyid field of encrypted packets" -#~ msgstr "eliminar campo keyid dos pacotes cifrados" - -#~ msgid "Show Photo IDs" -#~ msgstr "Mostrar IDs Fotográficos" - -#~ msgid "Don't show Photo IDs" -#~ msgstr "Não mostrar IDs Fotográficos" - -#~ msgid "Set command line to view Photo IDs" -#~ msgstr "Configurar linha de comandos para ver fotografias" - -#, fuzzy -#~ msgid "compress algorithm `%s' is read-only in this release\n" -#~ msgstr "o algoritmo de compressão deve estar na faixa %d..%d\n" - -#~ msgid "compress algorithm must be in range %d..%d\n" -#~ msgstr "o algoritmo de compressão deve estar na faixa %d..%d\n" - -#~ msgid "" -#~ "%08lX: It is not sure that this key really belongs to the owner\n" -#~ "but it is accepted anyway\n" -#~ msgstr "" -#~ "%08lX: Não se tem certeza de que esta chave realmente pertence ao dono,\n" -#~ "mas é aceite de qualquer modo\n" - -#~ msgid "preference %c%lu is not valid\n" -#~ msgstr "preferência %c%lu não é válida\n" - -#~ msgid "key %08lX: not a rfc2440 key - skipped\n" -#~ msgstr "chave %08lX: não é uma chave rfc2440 - ignorada\n" - -#~ msgid "" -#~ "NOTE: Elgamal primary key detected - this may take some time to import\n" -#~ msgstr "" -#~ "NOTA: Chave primária Elgamal detectada - pode demorar algum tempo a " -#~ "importar\n" - -#~ msgid "%s%c %4u%c/%08lX created: %s expires: %s" -#~ msgstr "%s%c %4u%c/%08lX criada: %s expira: %s" - -#~ msgid "can't get key from keyserver: %s\n" -#~ msgstr "não consigo obter chave do servidor: %s\n" - -#~ msgid "success sending to `%s' (status=%u)\n" -#~ msgstr "sucesso ao enviar para `%s' (estado=%u)\n" - -#~ msgid "failed sending to `%s': status=%u\n" -#~ msgstr "erro ao enviar para `%s': estado=%u\n" - -#~ msgid "can't search keyserver: %s\n" -#~ msgstr "não consigo procurar no servidor de chaves: %s\n" - -#~ msgid "" -#~ "key %08lX: this is a PGP generated ElGamal key which is NOT secure for " -#~ "signatures!\n" -#~ msgstr "" -#~ "chave: %08lX: esta é uma chave ElGamal gerada pelo PGP que NÃO é segura " -#~ "para assinaturas!\n" - -#~ msgid "" -#~ "key %08lX has been created %lu second in future (time warp or clock " -#~ "problem)\n" -#~ msgstr "" -#~ "a chave %08lX foi criada %lu segundo no futuro\n" -#~ "(viagem no tempo ou problema no relógio)\n" - -#~ msgid "" -#~ "key %08lX has been created %lu seconds in future (time warp or clock " -#~ "problem)\n" -#~ msgstr "" -#~ "a chave %08lX foi criada %lu segundos no futuro\n" -#~ "(viagem no tempo ou problema no relógio)\n" - -#~ msgid "key %08lX marked as ultimately trusted\n" -#~ msgstr "chave %08lX marcada como de confiança absoluta\n" - -#~ msgid "checking at depth %d signed=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n" -#~ msgstr "" -#~ "a verificar à profundidade %d assinado=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/" -#~ "%d\n" - -#~ msgid "" -#~ "Select the algorithm to use.\n" -#~ "\n" -#~ "DSA (aka DSS) is the digital signature algorithm which can only be used\n" -#~ "for signatures. This is the suggested algorithm because verification of\n" -#~ "DSA signatures are much faster than those of ElGamal.\n" -#~ "\n" -#~ "ElGamal is an algorithm which can be used for signatures and encryption.\n" -#~ "OpenPGP distinguishs between two flavors of this algorithms: an encrypt " -#~ "only\n" -#~ "and a sign+encrypt; actually it is the same, but some parameters must be\n" -#~ "selected in a special way to create a safe key for signatures: this " -#~ "program\n" -#~ "does this but other OpenPGP implementations are not required to " -#~ "understand\n" -#~ "the signature+encryption flavor.\n" -#~ "\n" -#~ "The first (primary) key must always be a key which is capable of " -#~ "signing;\n" -#~ "this is the reason why the encryption only ElGamal key is not available " -#~ "in\n" -#~ "this menu." -#~ msgstr "" -#~ "Seleccione o algoritmo a ser usado.\n" -#~ "\n" -#~ "DSA (ou DSS) é o algoritmo de assinatura digital que pode ser usado " -#~ "apenas\n" -#~ "para assinaturas. Este é o algoritmo recomendado porque a verificação de\n" -#~ "assinaturas DSA é muito mais rápida que a verificação de ElGamal.\n" -#~ "\n" -#~ "ElGamal é um algoritmo que pode ser usado para assinatura e cifragem.\n" -#~ "O OpenPGP distingue dois tipos deste algoritmo: um apenas para cifragem\n" -#~ "e outro para assinatura+cifragem; na verdade são iguais, mas alguns\n" -#~ "parâmetros precisam ser escolhidos de modo especial para criar uma chave\n" -#~ "segura para assinatura: este programa faz isso, mas algumas outras\n" -#~ "implementações do OpenPGP não vão necessariamente entender o tipo\n" -#~ "assinatura+cifragem.\n" -#~ "\n" -#~ "A chave primária precisa sempre ser uma chave capaz de fazer " -#~ "assinaturas;\n" -#~ "este é o motivo pelo qual a chave ElGamal apenas para cifragem não está\n" -#~ "disponível neste menu." - -#~ msgid "" -#~ "Although these keys are defined in RFC2440 they are not suggested\n" -#~ "because they are not supported by all programs and signatures created\n" -#~ "with them are quite large and very slow to verify." -#~ msgstr "" -#~ "Apesar de estas chaves estarem definidas no RFC2440, elas não são " -#~ "recomendadas\n" -#~ "porque não são suportadas por todos os programas e assinaturas criadas " -#~ "com\n" -#~ "elas são grandes e sua verificação é lenta." - -#~ msgid "%lu keys so far checked (%lu signatures)\n" -#~ msgstr "%lu chaves verificadas até agora (%lu assinaturas)\n" - -#, fuzzy -#~ msgid "key %08lX incomplete\n" -#~ msgstr "chave %08lX: sem ID de utilizador\n" - -#, fuzzy -#~ msgid "quit|quit" -#~ msgstr "sair" - -#~ msgid "" -#~ "The use of this algorithm is only supported by GnuPG. You will not be\n" -#~ "able to use this key to communicate with PGP users. This algorithm is " -#~ "also\n" -#~ "very slow, and may not be as secure as the other choices.\n" -#~ msgstr "" -#~ "A utilização deste algoritmo só é suportada pelo GnuPG. Não poderá " -#~ "utilizar\n" -#~ "esta chave para comunicar com utilizadores do PGP. Este algoritmo é " -#~ "para\n" -#~ "além disto muito lento, e pode não ser tão seguro como as outras opções.\n" - -#~ msgid "invalid symkey algorithm detected (%d)\n" -#~ msgstr "algoritmo de 'symkey' inválido detectado (%d)\n" - -#~ msgid "this keyserver is not fully HKP compatible\n" -#~ msgstr "o servidor de chaves não é totalmente compatível com HKP\n" +msgstr "gerir o histórico de comandos" From 548d4aad5fb0f8c8e2207326413b6cc7eb791169 Mon Sep 17 00:00:00 2001 From: Daniel Cerqueira Date: Wed, 29 Nov 2023 13:54:47 +0000 Subject: [PATCH 265/869] po: Update Portuguese Translation. -- Cherry-picked from 2.4 branch of commit: a14f73a1921e6cd002a58ff8a5ba3d39129729f3 This commit log (with no ChangeLog entry) is written by gniibe, following the practice; Translation update don't need a ChangeLog entry in a commit log. Signed-off-by: Daniel Cerqueira --- doc/help.pt.txt | 413 ++- po/pt.po | 8886 +++++++++++++++++------------------------------ 2 files changed, 3531 insertions(+), 5768 deletions(-) diff --git a/doc/help.pt.txt b/doc/help.pt.txt index da9a18153..95bd3f650 100644 --- a/doc/help.pt.txt +++ b/doc/help.pt.txt @@ -1,4 +1,4 @@ -# help.pt.txt - pt GnuPG online help +# help.pt.txt - Portuguese GnuPG online help # Copyright (C) 2007 Free Software Foundation, Inc. # # This file is part of GnuPG. @@ -7,247 +7,436 @@ # 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 . +# Note that this help file needs to be UTF-8 encoded. When looking +# for a help item, GnuPG scans the help files in the following order +# (assuming a GNU or Unix system): +# +# /etc/gnupg/help.LL_TT.txt +# /etc/gnupg/help.LL.txt +# /etc/gnupg/help.txt +# /usr/share/gnupg/help.LL_TT.txt +# /usr/share/gnupg/help.LL.txt +# /usr/share/gnupg/help.txt +# +# Here LL_TT denotes the full name of the current locale with the +# territory (.e.g. "de_DE"), LL denotes just the locale name +# (e.g. "de"). The first matching item is returned. To put a dot or +# a hash mark at the beginning of a help text line, it needs to be +# prefixed with ". ". A single dot may be used to terminated a help +# entry. + +.pinentry.qualitybar.tooltip +# [remove the hash mark from the key to enable this text] +# This entry is just an example on how to customize the tooltip shown +# when hovering over the quality bar of the pinentry. We don't +# install this text so that the hardcoded translation takes +# precedence. An administrator should write up a short help to tell +# the users about the configured passphrase constraints and save that +# to /etc/gnupg/help.txt. The help text should not be longer than +# about 800 characters. +Esta barra indica a qualidade da frase-secreta introduzida acima. + +Enquanto a barra estiver vermelha, o GnuPG considera a frase-secreta +demasiada fraca para a aceitar. Peça ao seu administrador detalhes +sobre as restrições de frase-secreta configuradas. +. + +.pinentry.constraints.hint.short +# [remove the hash mark from the key to enable this hint] +# This entry is used by some pinentries to display a hint about +# enabled passphrase constraints. These constraints are configurable +# and the admin may give a hint about them by using this help entry. +Use letras e dígitos. +. + +.pinentry.constraints.hint.long +# [remove the hash mark from the key to enable this hint] +# This entry is used by some pinentries to show a tooltip with more +# information about the configured passphrase constraints. +Use letras e dígitos. +Restrições extras são impostas, por exemplo +o uso de matrículas comuns de veículos. +. + +.pinentry.formatted_passphrase.hint", +# [remove the hash mark from the key to enable this hint] +# If this entry is not set a standard text is shown +Nota: Os espaços em branco não fazem parte da frase-secreta. +. + +.gnupg.agent-problem +# There was a problem accessing or starting the agent. +Não foi possível conectar-se a um Gpg-Agent em execução ou +ocorreu um problema de comunicação com um agent em execução. + +O sistema usa um processo em segundo plano, chamado Gpg-Agent, para +procestamento chaves privadas e pedir frase-secretas. O agent +geralmente é iniciado quando o utilizador faz login e é executado, +enquanto o utilizador estiver logado. Caso nenhum agent esteja +disponível, o sistema tenta iniciar um em tempo real mas esta versão +do agent é um pouco limitada em funcionalidade e assim, pode levar a +pequenos problemas. + +Você provavelmente precisa perguntar ao seu administrador sobre como +resolver o problema. Como solução alternativa, você pode tentar sair +e entrar na sua sessão e ver se isso ajuda. Se isso ajudar, por +favor, informe mesmo assim o administrador, porque isto indica um bug +no software. +. + +.gnupg.dirmngr-problem +# There was a problen accessing the dirmngr. +Não foi possível conectar-se a um Dirmngr em execução ou ocorreu um +problema de comunicação com um Dirmngr em execução. + +Para pesquisar listas de revogação de certificados (CRLs), executar +validação OCSP e para pesquisar chaves através de servidores LDAP, o +sistema usa um programa de serviço externo chamado Dirmngr. O Dirmngr +geralmente está em execução como um serviço do sistema (daemon) e não +precisa de qualquer atenção por parte do utilizador. Em caso de +problemas, o sistema poderá iniciar sua própria cópia do Dirmngr tendo +por base uma requisição; esta é a solução alternativa e produz +desempenho limitado. + +Se você encontrar este problema, você deve perguntar ao seu +administrador de sistema como proceder. Como uma solução provisória, +você pode tentar desabilitar a verificação de CRL na configuração do +gpgsm. +. + .gpg.edit_ownertrust.value -Você decide que valor usar aqui; este valor nunca será exportado para -terceiros. Precisamos dele implementar a rede de confiança, que não tem -nada a ver com a rede de certificados (implicitamente criada). +# The help identies prefixed with "gpg." used to be hard coded in gpg +# but may now be overridden by help texts from this file. +Cabe a você atribuir um valor aqui; este valor nunca será exportado a +quaisquer terceiros. Precisamos dele para implementar a +Rede-da-Confiança; que tem nada a ver com a rede-de-certificados +(criada implicitamente). . .gpg.edit_ownertrust.set_ultimate.okay -Para construir a Teia-de-Confiança ('Web-of-Trust'), o GnuPG precisa de -saber quais são as chaves em que deposita confiança absoluta - normalmente -estas são as chaves a que tem acesso à chave privada. Responda "sim" para -que esta chave seja de confiança absoluta. - +Para construir a Rede-da-Confiança, o GnuPG precisa saber quais são as +chaves plenamente confiáveis - essas são geralmente as chaves +para as quais você tem acesso à chave secreta. Responder "sim" para +definir esta chave como plenamente confiável. . .gpg.untrusted_key.override -Se você quiser usar esta chave, não de confiança, assim mesmo, responda "sim". +Se você, mesmo assim, quiser usar esta chave não confiável, responder +"sim". . .gpg.pklist.user_id.enter -Digite o ID de utilizador do destinatário para quem quer enviar a -mensagem. +Introduzir a ID de utilizador do destinatário para quem você deseja +enviar a mensagem. . -.#gpg.keygen.algo -# fixme: Please translate and remove the hash mark from the key line. -Select the algorithm to use. +.gpg.keygen.algo +Selecionar o algoritmo a ser usado. -DSA (aka DSS) is the Digital Signature Algorithm and can only be used -for signatures. +DSA (aka DSS) é o Algoritmo de Assinatura Digital e só pode ser usado +para assinaturas. -Elgamal is an encrypt-only algorithm. +Elgamal é um algoritmo só para cifração. -RSA may be used for signatures or encryption. +O RSA pode ser usado para assinaturas ou cifração. -The first (primary) key must always be a key which is capable of signing. +A primeira chave (principal) deve ser sempre uma chave capaz de +assinar. . .gpg.keygen.algo.rsa_se -Em geral não é uma boa ideia utilizar a mesma chave para assinar e para -cifrar. Este algoritmo só deve ser utilizado em alguns domínios. -Por favor consulte primeiro o seu perito em segurança. +De modo geral, não é uma boa ideia usar a mesma chave para assinar e +cifrar. Este algoritmo só deve ser usado em determinados domínios. +Consulte primeiro o seu especialista em segurança. +. + +.gpg.keygen.cardkey +Selecionar qual chave do cartão será utilizada. + +A listagem mostra o índice de seleção, o keygrip (uma string de +dígitos hex), a referência da chave específica do cartão, o algoritmo +que foi usado para esta chave, e, entre parênteses, a utilização da +chave (cert, sign, auth, encr). Se conhecida, a utilização padrão de +uma chave está marcada com um asterisco. +. + +.gpg.keygen.keygrip +Introduzir o keygrip da chave a ser adicionada. + +O keygrip é uma string de 40 dígitos hex que identifica uma chave. +Ele deve pertencer a uma chave secreta ou a uma subchave secreta +armazenada no seu porta-chaves. +. + +.gpg.keygen.flags +Alterne as capacidades da chave. + +Só é possível alternar as capacidades que são possíveis para o +algoritmo selecionado. + +Para definir rapidamente os recursos de uma só vez, é possível inserir +um '=' como primeiro caractere seguido de uma lista de letras +indicando a capacidade a definir: 's' para assinatura, 'e' para +cifração e 'a' para autenticação. Letras inválidas e capacidades +impossíveis são ignoradas. Este submenu é imediatamente fechado +depois de usar este atalho. . .gpg.keygen.size -Insira o tamanho da chave +Introduzir o tamanho da chave. + +A pré-definição sugerida geralmente é uma boa escolha. + +Se você quiser usar um tamanho de chave grande, por exemplo, 4096 bit, +pense novamente se realmente faz sentido para você. Você poderá +querer ver a página web https://www.xkcd.com/538/ . . .gpg.keygen.size.huge.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keygen.size.large.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keygen.valid -Digite o valor necessário conforme pedido. -É possível digitar uma data ISO (AAAA-MM-DD) mas você não terá uma boa -reacção a erros - o sistema tentará interpretar o valor dado como um intervalo. +Introduzir o valor exigido, conforme mostrado no prompt. +É possível inserir uma data ISO (AAAA-MM-DD), mas você não vai obter +uma boa resposta de erro - em vez disso, o sistema tenta interpretar o +valor dado como um intervalo. . .gpg.keygen.valid.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keygen.name -Digite o nome do possuidor da chave +Introduzir o nome do titular da chave. +Os caracteres "<" e ">" não são permitidos. +Exemplo: Heinrich Heine . .gpg.keygen.email -por favor digite um endereço de email (opcional mas recomendado) +Introduza um endereço de email opcional, mas altamente sugerido. +Exemplo: heinrichh@duesteldorf.de . .gpg.keygen.comment -Por favor digite um comentário (opcional) +Introduza um comentário opcional. +Os caracteres "(" e ")" não são permitidos. +De modo geral, não há necessidade de comentários. . .gpg.keygen.userid.cmd -N para mudar o nome. -C para mudar o comentário. -E para mudar o endereço de email -O para continuar a geração da chave. -S para interromper a geração da chave. +# (Keep a leading empty line) + +N para alterar o nome. +C para alterar o comentário. +E para alterar o endereço de email. +O para continuar com a geração de chaves. +Q para sair da geração de chaves. . .gpg.keygen.sub.okay -Responda "sim" (ou apenas "s") se quiser gerar a subchave. +Responder "sim" (ou apenas "s") se não houver problema em gerar a +subchave. . .gpg.sign_uid.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.sign_uid.class -Quando assina uma chave de identificação de um utilizador, deve primeiro -verificar que a chave pertence realmente à pessoa em questão. É útil para -terceiros saberem com que cuidado é que efectuou esta verificação. +Ao assinar uma ID de utilizador de uma chave, você deve primeiro +verificar que a chave pertence à pessoa correta da ID de utilizador. +É útil para os outros saber com que cuidado você verificou isso. -"0" significa que não deseja declarar a forma com verificou a chave +"0" significa que você faz nenhuma reivindicação específica sobre o + quão cuidadosamente você verificou o chave. -"1" significa que acredita que a chave pertence à pessoa em questão, mas - não conseguiu ou não tentou verificar. Este grau é útil para quando - assina a chave de uma utilizador pseudo-anónimo. +"1" significa que você acredita que a pessoa é dona da chave que + afirma possuí-la mas você não pôde, ou não verificou a chave. + Isto é útil para uma verificação de "persona", onde você assina a + chave de um utilizador pseudónimo. -"2" significa que efectuou uma verificação normal da chave. Por exemplo, - isto pode significar que verificou a impressão digital da chave e - verificou o identificador de utilizador da chave contra uma identificação - fotográfica. +"2" significa que você fez uma verificação casual da chave. Por + exemplo, isso poderia significar que você verificou a impressão + digital da chave e verificou a ID de utilizador da chave em + relação a uma ID fotográfica. -"3" significa que efectuou uma verificação exaustiva da chave. Por exemplo, - isto pode significar que efectuou a verificação pessoalmente, e que - utilizou um documento, com fotografia, difícil de falsificar - (como por exemplo um passaporte) que o nome do dono da chave é o - mesmo do que o identificador da chave, e que, finalmente, verificou - (através de troca de e-mail) que o endereço de email da chave pertence - ao done da chave. +"3" significa que você fez uma verificação completa da chave. Por + exemplo, isto poderia significa que você verificou a impressão + digital da chave com o dono da chave em pessoa, e que você + verificou, por meio de um documento difícil de falsificar com uma + ID fotográfica (como um passaporte) que o nome do dono da chave + corresponde ao na ID de utilizador na chave e, finalmente, que + você verificou (por troca de email) que o endereço de email na + chave pertence ao dono da chave. -Atenção: os exemplos dados para os níveis 2 e 3 são *apenas* exemplos. -Compete-lhe a si decidir o que considera, ao assinar chaves, uma verificação -"normal" e uma verificação "exaustiva". +Note que os exemplos dados acima para os níveis 2 e 3 são *apenas* +exemplos. No final, cabe a você decidir o que "casual" e "completo" +significa para você quando você assina outras chaves. -Se não sabe qual é a resposta correcta, responda "0". +Se você não sabe qual é a resposta certa, responda "0". . .gpg.change_passwd.empty.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keyedit.save.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . .gpg.keyedit.cancel.okay -Responda "sim" ou "não" +Responder "sim" ou "não". . -.#gpg.keyedit.sign_all.okay -# fixme: Please translate and remove the hash mark from the key line. -Answer "yes" if you want to sign ALL the user IDs +.gpg.keyedit.sign_all.okay +Responder "sim" se quiser assinar TODAS as IDs de utilizador. . .gpg.keyedit.remove.uid.okay -Responda "sim" se quiser realmente remover este ID de utilizador. -Todos os certificados também serão perdidos! +Responda "sim" se tem a certeza que você quer apagar esta ID de +utilizador. Todos os certificados também são perdidos! . .gpg.keyedit.remove.subkey.okay -Responda "sim" se quiser remover a subchave +Responder "sim" se não houver problema em apagar a subchave. . .gpg.keyedit.delsig.valid -Esta é uma assinatura válida na chave; normalmente não é desejável -remover esta assinatura porque ela pode ser importante para estabelecer -uma conexão de confiança à chave ou a outra chave certificada por esta. +Esta é uma assinatura válida na chave; você normalmente não quer +apagar esta assinatura porque pode ser importante para estabelecer uma +conexão de confiança com a chave ou com outra chave certificada por +esta chave. . .gpg.keyedit.delsig.unknown Esta assinatura não pode ser verificada porque você não tem a chave -correspondente. Você deve adiar sua remoção até saber que chave foi usada -porque a chave desta assinatura pode estabelecer uma conexão de confiança -através de outra chave já certificada. +correspondente. Você deve adiar apagar, até quando você souber qual +chave foi usada, porque esta chave de assinatura pode estabelecer uma +conexão de confiança por meio de outra chave já certificada. . .gpg.keyedit.delsig.invalid -A assinatura não é válida. Faz sentido removê-la do seu porta-chaves. +A assinatura não é válida. Faz sentido removê-la de seu porta-chaves. . .gpg.keyedit.delsig.selfsig -Esta é uma assinatura que liga o ID de utilizador à chave. Geralmente -não é uma boa idéia remover tal assinatura. É possível que o GnuPG -não consiga mais usar esta chave. Faça isto apenas se por alguma -razão esta auto-assinatura não for válida e há uma segunda disponível. +Esta é uma assinatura que vincula a ID de utilizador à chave. +Geralmente não é uma boa ideia remover tal assinatura. Até porque o +GnuPG pode deixar de ser capaz de usar esta chave. Por isso, faça +isso só se, por algum motivo, esta auto-assinatura não for válida e +uma segunda assinatura estiver disponível. . .gpg.keyedit.updpref.okay -Muda as preferências de todos os identificadores de utilizadores -(ou apenas dos seleccionados) para a lista actual de preferências. -O 'timestamp' de todas as auto-assinaturas afectuadas será avançado -em um segundo. - +Alterar as preferências de todas as IDs de utilizador (ou apenas das +selecionadas) para a lista atual de preferências. O timestamp de todas +as auto-assinaturas afetadas serão adiantadas em um segundo. . .gpg.passphrase.enter -Por favor digite a frase secreta +# (keep a leading empty line) +Introduza a frase-secreta; esta é uma frase que é secreta. . .gpg.passphrase.repeat -Por favor repita a frase secreta, para ter certeza do que digitou. +Repita a última frase-secreta, para ter certeza da que introduziu. . .gpg.detached_signature.filename -Dê o nome para o ficheiro ao qual a assinatura se aplica +Fornecer o nome do ficheiro ao qual a assinatura se aplica. . .gpg.openfile.overwrite.okay -Responda "sim" se quiser escrever por cima do ficheiro +# openfile.c (overwrite_filep) +Responder "sim" se não houver problema em sobrescrever o ficheiro. . .gpg.openfile.askoutname -Por favor digite um novo nome de ficheiro. Se você apenas carregar em RETURN -o ficheiro por omissão (que é mostrado entre parênteses) será utilizado. +# openfile.c (ask_outfile_name) +Introduza um novo nome de ficheiro. Se você apenas carregar RETURN o +ficheiro pré-definido (que está entre parênteses) será usado. . .gpg.ask_revocation_reason.code -Deve especificar uma razão para a emissão do certificado. Dependendo no -contexto, pode escolher as seguintes opções desta lista: - "A chave foi comprometida" - Utilize esta opção se tem razões para acreditar que indivíduos não - autorizados obtiveram acesso à sua chave secreta. - "A chave foi substituida" - Utilize esta opção se substituiu esta chave com uma mais recente. - "A chave já não é utilizada" - Utilize esta opção se já não utiliza a chave. - "O identificador do utilizador já não é válido" - Utilize esta opção para comunicar que o identificador do utilizador - não deve ser mais utilizado; normalmente utilizada para indicar - que um endereço de email é inválido. +# revoke.c (ask_revocation_reason) +Você deve especificar um motivo para a revogação. Dependendo do +contexto que você pode escolher a partir desta lista: + "Chave foi comprometida" + Usar isto se você tiver um motivo para acreditar que pessoas não + autorizadas tiveram acesso à sua chave secreta. + "Chave foi substituída" + Usar isto se você tiver substituído esta chave por uma mais + recente. + "Chave não é mais usada" + Usar isto se você tiver desativado esta chave. + "ID de utilizador não é mais válido" + Usar isto para declarar que a ID de utilizador não deve ser mais + utilizada; isto normalmente é usado para marcar um endereço de + email como inválido. . .gpg.ask_revocation_reason.text -Se desejar, pode inserir uma texto descrevendo a razão pela qual criou -este certificado de revogação. Por favor mantenha este texto conciso. +# revoke.c (ask_revocation_reason) +Se desejar, você pode introduzir um texto descrevendo porque você emite +este certificado de revogação. Mantenha este texto conciso. Uma linha vazia termina o texto. +. +.gpg.tofu.conflict +# tofu.c +TOFU detetou outra chave com o mesmo endereço de email (ou um muito +semelhante). Pode ser que o utilizador tenha criado uma nova +chave. Neste caso, você pode confiar com segurança na nova chave (mas +confirme perguntando à pessoa). No entanto, também pode ser que a +chave seja uma falsificação ou esteja a occorrer um ataque de +Man-in-the-Middle (MitM). Neste caso, você deve marcar a chave como +sendo incorreta, para que não seja confiável. Marcar uma chave como +sendo não confiável significa que quaisquer assinaturas serão +consideradas incorretas e que as tentativas de cifrar para a chave +serão sinalizadas. Se você tem dúvidas e não pode verificar de +momento, você deve ou aceitar uma vez ou rejeitar uma vez. +. + +.gpgsm.root-cert-not-trusted +# This text gets displayed by the audit log if +# a root certificates was not trusted. +O certificado raiz (a âncora-de-confiança) não é confiável. Dependendo +da configuração, você poderá aparecer-lhe um prompt, para marcar esse +certificado raiz como confiável ou você poderá precisar de dizer +manualmente ao GnuPG para confiar nesse certificado. Os certificados +confiáveis são configurados no ficheiro trustlist.txt da pasta home do +GnuPG. Em caso de dúvida, pergunte ao seu administrador de sistema se +deve confiar neste certificado. +. + +.gpgsm.crl-problem +# This text is displayed by the audit log for problems with +# the CRL or OCSP checking. +Dependendo da sua configuração, ocorreu um problema ao obter a CRL ou +a realizar de uma verificação OCSP. Há uma grande variedade de razões +pelas quais isto não funcionou. Verifique o manual para possíveis +soluções. . - # Local variables: -# mode: fundamental +# mode: default-generic # coding: utf-8 # End: diff --git a/po/pt.po b/po/pt.po index e7ba4118c..cf440b3a3 100644 --- a/po/pt.po +++ b/po/pt.po @@ -1,25 +1,80 @@ # pt messages for gnupg -# Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -# Pedro Morais +# Copyright (C) 1999, 2000, 2001, 2002, 2023 Free Software Foundation, Inc. +# Daniel Cerqueira # # Based on pt_PT work done by: +# Pedro Morais # Thiago Jung Bauermann # Rafael Caetano dos Santos +# +# +# GnuPG glossary for Portuguese translators +# +# English | Portuguese +# ----------------------------------+-------------------------------------- +# cryptography | cifragem +# encryption | cifração +# (to) encrypt | cifrar +# decryption | decifração +# (to) decrypt | decifrar +# cipher | a cifra +# passphrase(s) | frase-secreta(s) +# password | senha +# socket | socket +# directory | pasta +# handler | handler +# string | string +# batch mode | modo batch +# delete | apagar +# request | pedido +# armor | blindagem +# compression | compressão +# ownership | ownership +# self-sign | auto-assinar +# keyring | porta-chaves +# enter | introduzir +# prompt | perguntar +# agent | agent +# smartcard | smartcard +# primary | principal +# digest | digest +# deprecated | depreciado +# stale | obsoleto +# photo ID | ID fotográfica +# subject | entidade +# chain | corrente +# write | escrever +# a record | um registo +# timestamp | timestamp +# S-expression | S-expression +# keyflag | keyflag +# flag | flag +# (to) flag | marcar +# merge | fundir +# homedir | homedir +# overwrite | sobrescrever +# (conjugation) please enter (verb) | introduza +# (conjugation) enter (verb) | introduzir +# usage: | uso: +# usage | utilização +# +# msgid "" msgstr "" "Project-Id-Version: gnupg\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2015-02-11 19:17+0100\n" -"Last-Translator: Pedro Morais \n" -"Language-Team: pt \n" +"PO-Revision-Date: 2023-11-29 13:11+0000\n" +"Last-Translator: Daniel Cerqueira \n" +"Language-Team: pt \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#, fuzzy, c-format +#, c-format msgid "failed to acquire the pinentry lock: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao adquirir o bloqueio pinentry: %s\n" #. TRANSLATORS: These are labels for buttons etc as used in #. * Pinentries. In your translation copy the text before the @@ -28,42 +83,39 @@ msgstr "falha ao inicializar a base de dados de confiança: %s\n" #. * used as an accelerator. Double the underscore to have #. * pinentry display a literal underscore. msgid "|pinentry-label|_OK" -msgstr "" +msgstr "|pinentry-label|_OK" msgid "|pinentry-label|_Cancel" -msgstr "" +msgstr "|pinentry-label|_Cancelar" msgid "|pinentry-label|_Yes" -msgstr "" +msgstr "|pinentry-label|_Sim" msgid "|pinentry-label|_No" -msgstr "" +msgstr "|pinentry-label|_Não" msgid "|pinentry-label|PIN:" -msgstr "" +msgstr "|pinentry-label|PIN:" msgid "|pinentry-label|_Save in password manager" -msgstr "" +msgstr "|pinentry-label|_Guardar no gestor de senhas" -#, fuzzy msgid "Do you really want to make your passphrase visible on the screen?" -msgstr "Você quer realmente remover as chaves selecionadas? " +msgstr "De certeza que você deseja tornar sua frase-secreta visível no ecrã?" msgid "|pinentry-tt|Make passphrase visible" -msgstr "" +msgstr "|pinentry-tt|Tornar a frase-secreta visível" -#, fuzzy -#| msgid "invalid passphrase" msgid "|pinentry-tt|Hide passphrase" -msgstr "frase-secreta inválida" +msgstr "|pinentry-tt|Esconder frase-secreta" msgid "Caps Lock is on" -msgstr "" +msgstr "Caps Lock está ativado" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for generating a passphrase. msgid "Suggest" -msgstr "" +msgstr "Sugerir" #. TRANSLATORS: This string is a tooltip, shown by pinentry when #. hovering over the generate button. Please use an appropriate @@ -73,25 +125,24 @@ msgstr "" #. will be used. The strcmp thingy is there to detect a #. non-translated string. msgid "pinentry.genpin.tooltip" -msgstr "" +msgstr "Sugerir uma frase-secreta aleatória." #. TRANSLATORS: This is a text shown by pinentry if the option #. for formatted passphrase is enabled. The length is #. limited to about 900 characters. msgid "Note: The blanks are not part of the passphrase." -msgstr "" +msgstr "Nota: Os espaços em branco não fazem parte da frase-secreta." #. TRANSLATORS: This is a text shown by pinentry as title of a dialog #. telling the user that the entered new passphrase does not satisfy #. the passphrase constraints. Please keep it short. -#, fuzzy msgid "Passphrase Not Allowed" -msgstr "frase secreta demasiado longa\n" +msgstr "Frase-secreta Não Permitida" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for the quality bar. msgid "Quality:" -msgstr "" +msgstr "Qualidade:" #. TRANSLATORS: This string is a tooltip, shown by pinentry when #. hovering over the quality bar. Please use an appropriate @@ -101,528 +152,510 @@ msgstr "" #. will be used. msgid "pinentry.qualitybar.tooltip" msgstr "" +"A qualidade do texto inserido acima.\n" +"Peça ao administrador detalhes sobre\n" +"os critérios." msgid "" "Please enter your PIN, so that the secret key can be unlocked for this " "session" msgstr "" +"Introduza o seu PIN, para que a chave secreta possa ser desbloqueada para " +"esta sessão" -#, fuzzy msgid "" "Please enter your passphrase, so that the secret key can be unlocked for " "this session" -msgstr "Por favor digite a frase secreta \n" +msgstr "" +"Introduza a sua frase-secreta, para que a chave secreta possa ser " +"desbloqueada para esta sessão" msgid "PIN:" -msgstr "" +msgstr "PIN:" -#, fuzzy msgid "Passphrase:" -msgstr "frase secreta incorrecta" +msgstr "Frase-secreta:" msgid "does not match - try again" -msgstr "" +msgstr "não corresponde - tente novamente" -#, fuzzy msgid "Passphrases match." -msgstr "frase secreta incorrecta" +msgstr "Frase-secretas correspondem." #. TRANSLATORS: The string is appended to an error message in #. the pinentry. The %s is the actual error message, the #. two %d give the current and maximum number of tries. #, c-format msgid "SETERROR %s (try %d of %d)" -msgstr "" +msgstr "SETERROR %s (tentativa %d de %d)" msgid "Repeat:" -msgstr "" +msgstr "Repetir:" -#, fuzzy msgid "PIN too long" -msgstr "frase secreta demasiado longa\n" +msgstr "PIN muito longo" -#, fuzzy msgid "Passphrase too long" -msgstr "frase secreta demasiado longa\n" +msgstr "Frase-secreta muito longa" -#, fuzzy msgid "Invalid characters in PIN" -msgstr "Caracter inválido no nome\n" +msgstr "Caracteres inválidos no PIN" msgid "PIN too short" -msgstr "" +msgstr "PIN muito curto" -#, fuzzy msgid "Bad PIN" -msgstr "MPI incorreto" +msgstr "PIN inválido" -#, fuzzy msgid "Bad Passphrase" -msgstr "frase secreta incorrecta" +msgstr "Frase-secreta inválida" msgid "Note: Request from the web browser." -msgstr "" +msgstr "Nota: Pedido do navegador da Web." msgid "Note: Request from a remote site." -msgstr "" +msgstr "Nota: Pedido de um site remoto." -#, fuzzy, c-format +#, c-format msgid "error getting serial number of card: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter o número de série do cartão: %s\n" -#, fuzzy msgid "Please re-enter this passphrase" -msgstr "muda a frase secreta" +msgstr "Re-introduza esta frase-secreta" -#, fuzzy, c-format +#, c-format msgid "" "Please enter the passphrase to protect the imported object within the %s " "system." -msgstr "Por favor digite a frase secreta \n" +msgstr "" +"Introduza a frase-secreta para proteger o objeto importado dentro do sistema " +"%s." msgid "" "This key (or subkey) is not protected with a passphrase. Please enter a new " "passphrase to export it." msgstr "" +"Esta chave (ou subchave) não está protegida com uma frase-secreta. " +"Introduza uma nova frase-secreta para exportá-la." -#, fuzzy, c-format +#, c-format msgid "ssh keys greater than %d bits are not supported\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "chaves ssh maiores que %d bits não são suportadas\n" -#, fuzzy, c-format -#| msgid "can't create `%s': %s\n" +#, c-format msgid "can't create '%s': %s\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível criar '%s': %s\n" -#, fuzzy, c-format -#| msgid "can't open `%s': %s\n" +#, c-format msgid "can't open '%s': %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "não é possível abrir '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "no suitable card key found: %s\n" -msgstr "nenhum porta-chaves secreto com permissões de escrita encontrado: %s\n" +msgstr "nenhuma chave de cartão adequada encontrada: %s\n" -#, fuzzy, c-format +#, c-format msgid "error getting list of cards: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter a lista de cartões: %s\n" #, c-format msgid "" "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want to " "allow this?" msgstr "" +"Um processo ssh pediu o uso da chave%%0A %s%%0A (%s)%%0ADeseja permitir " +"isto?" msgid "Allow" -msgstr "" +msgstr "Permitir" msgid "Deny" -msgstr "" +msgstr "Negar" -#, fuzzy, c-format +#, c-format msgid "Please enter the passphrase for the ssh key%%0A %F%%0A (%c)" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta da chave ssh%%0A %F%%0A (%c)" -#, fuzzy, c-format +#, c-format msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" -msgstr "Por favor digite a frase secreta \n" +msgstr "" +"Introduza uma frase-secreta para proteger a chave secreta recebida%%0A " +"%s%%0A %s%%0Adentro do armazenamento de chaves do gpg-agent" -#, fuzzy, c-format +#, c-format msgid "failed to create stream from socket: %s\n" -msgstr "%s: falha ao criar tabela de dispersão: %s\n" +msgstr "falha ao criar fluxo de socket: %s\n" msgid "Admin PIN" -msgstr "" +msgstr "PIN do Admin" #. TRANSLATORS: A PUK is the Personal Unblocking Code #. used to unblock a PIN. msgid "PUK" -msgstr "" +msgstr "PUK" msgid "Reset Code" -msgstr "" +msgstr "Código de Reset" msgid "Push ACK button on card/token." -msgstr "" +msgstr "Pressione o botão ACK no cartão/token." msgid "Use the reader's pinpad for input." -msgstr "" +msgstr "Usar o pinpad do leitor para entrada." -#, fuzzy msgid "Repeat this Reset Code" -msgstr "Repita a frase secreta: " +msgstr "Repetir este Código de Reset" -#, fuzzy msgid "Repeat this PUK" -msgstr "Repita a frase secreta: " +msgstr "Repetir este PUK" -#, fuzzy msgid "Repeat this PIN" -msgstr "Repita a frase secreta: " +msgstr "Repetir este PIN" -#, fuzzy msgid "Reset Code not correctly repeated; try again" -msgstr "a frase secreta não foi repetida corretamente; tente outra vez" +msgstr "Código de Reset incorretamente repetido; tente novamente" -#, fuzzy msgid "PUK not correctly repeated; try again" -msgstr "a frase secreta não foi repetida corretamente; tente outra vez" +msgstr "PUK incorretamente repetido; tente novamente" -#, fuzzy msgid "PIN not correctly repeated; try again" -msgstr "a frase secreta não foi repetida corretamente; tente outra vez" +msgstr "PIN incorretamente repetido; tente novamente" #, c-format msgid "Please enter the PIN%s%s%s to unlock the card" -msgstr "" +msgstr "Introduza o PIN%s%s%s para desbloquear o cartão" -#, fuzzy, c-format +#, c-format msgid "error writing to pipe: %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao escrever no pipe: %s\n" -#, fuzzy msgid "Enter new passphrase" -msgstr "Insira a frase secreta\n" +msgstr "Introduzir nova frase-secreta" #, c-format msgid "" "You have not entered a passphrase!%0AAn empty passphrase is not allowed." msgstr "" +"Você não introduziu uma frase-secreta!%0AUma frase-secreta vazia não é " +"permitida." #, c-format msgid "" "You have not entered a passphrase - this is in general a bad idea!%0APlease " "confirm that you do not want to have any protection on your key." msgstr "" +"Você não introduziu uma frase-secreta - isto, geralmente, é uma má ideia!" +"%0AConfirme que você quer ter nenhuma proteção em sua chave." msgid "Yes, protection is not needed" -msgstr "" +msgstr "Sim, a proteção não é necessária" -#, fuzzy, c-format -#| msgid "Name must be at least 5 characters long\n" +#, c-format msgid "A passphrase should be at least %u character long." msgid_plural "A passphrase should be at least %u characters long." -msgstr[0] "O nome deve ter pelo menos 5 caracteres\n" -msgstr[1] "O nome deve ter pelo menos 5 caracteres\n" +msgstr[0] "Uma frase-secreta deve ter pelo menos %u caracter." +msgstr[1] "Uma frase-secreta deve ter pelo menos %u caracteres." #, c-format msgid "A passphrase should contain at least %u digit or%%0Aspecial character." msgid_plural "" "A passphrase should contain at least %u digits or%%0Aspecial characters." msgstr[0] "" +"Uma frase-secreta deve conter pelo menos %u dígito ou%%0Acaracter especial." msgstr[1] "" +"Uma frase-secreta deve conter pelo menos %u dígitos ou%%0Acaracteres " +"especiais." #, c-format msgid "A passphrase may not be a known term or match%%0Acertain pattern." msgstr "" +"Uma frase-secreta não pode ser um termo conhecido ou corresponder%%0Aa um " +"determinado padrão." msgid "Warning: You have entered an insecure passphrase." -msgstr "" +msgstr "Aviso: Você introduziu uma frase-secreta insegura." -#, fuzzy msgid "Take this one anyway" -msgstr "Usar esta chave de qualquer modo? " +msgstr "Mesmo assim, leve esta" -#, fuzzy, c-format +#, c-format msgid "Please enter the passphrase to%0Aprotect your new key" -msgstr "" -"Você precisa de uma frase secreta para proteger a sua chave.\n" -"\n" +msgstr "Introduza a frase-secreta para%0Aproteger a sua nova chave" -#, fuzzy msgid "Please enter the new passphrase" -msgstr "muda a frase secreta" +msgstr "Introduza a nova frase-secreta" msgid "Options used for startup" -msgstr "" +msgstr "Opções usadas para inicialização" msgid "run in daemon mode (background)" -msgstr "" +msgstr "executar no modo daemon (em segundo plano)" msgid "run in server mode (foreground)" -msgstr "" +msgstr "executar no modo de servidor (primeiro plano)" msgid "do not detach from the console" -msgstr "" +msgstr "não desanexar da consola" msgid "sh-style command output" -msgstr "" +msgstr "saída de comando tipo-sh" msgid "csh-style command output" -msgstr "" +msgstr "saída de comando tipo-csh" -#, fuzzy msgid "|FILE|read options from FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|ler opções de FILE" msgid "Options controlling the diagnostic output" -msgstr "" +msgstr "Opções que controlam a saída do diagnóstico" msgid "verbose" -msgstr "detalhado" +msgstr "verboso" msgid "be somewhat more quiet" msgstr "ser mais silencioso" msgid "|FILE|write server mode logs to FILE" -msgstr "" +msgstr "|FILE|escrever logs do modo de servidor no FILE" msgid "Options controlling the configuration" -msgstr "" +msgstr "Opções que controlam a configuração" -#, fuzzy msgid "do not use the SCdaemon" -msgstr "actualizar a base de dados de confiança" +msgstr "não usar o SCdaemon" msgid "|PGM|use PGM as the SCdaemon program" -msgstr "" +msgstr "|PGM|usar PGM como o programa SCdaemon" msgid "|PGM|use PGM as the tpm2daemon program" -msgstr "" +msgstr "|PGM|usar PGM como o programa tpm2daemon" -#, fuzzy -#| msgid "|NAME|set terminal charset to NAME" msgid "|NAME|accept some commands via NAME" -msgstr "" -"|NOME|definir mapa de caracteres do terminal como\n" -"NOME" +msgstr "|NAME|aceitar alguns comandos via NAME" msgid "ignore requests to change the TTY" -msgstr "" +msgstr "ignorar pedidos para alterar o TTY" msgid "ignore requests to change the X display" -msgstr "" +msgstr "ignorar pedidos para alterar a exibição X" -#, fuzzy -#| msgid "not supported" msgid "enable ssh support" -msgstr "não suportado" +msgstr "habilitar suporte a ssh" msgid "|ALGO|use ALGO to show ssh fingerprints" -msgstr "" +msgstr "|ALGO|usar ALGO para mostrar impressões digitais ssh" -#, fuzzy -#| msgid "not supported" msgid "enable putty support" -msgstr "não suportado" +msgstr "habilitar suporte a putty" -#, fuzzy -#| msgid "not supported" msgid "enable Win32-OpenSSH support" -msgstr "não suportado" +msgstr "habilitar o suporte a Win32-OpenSSH" msgid "Options controlling the security" -msgstr "" +msgstr "Opções que controlam a segurança" msgid "|N|expire cached PINs after N seconds" -msgstr "" +msgstr "|N|expirar PINs armazenados em cache após N segundos" msgid "|N|expire SSH keys after N seconds" -msgstr "" +msgstr "|N|expirar chaves SSH após N segundos" msgid "|N|set maximum PIN cache lifetime to N seconds" -msgstr "" +msgstr "|N|definir o tempo de vida máximo da cache do PIN para N segundos" msgid "|N|set maximum SSH key lifetime to N seconds" -msgstr "" +msgstr "|N|definir o tempo de vida máximo da chave SSH para N segundos" msgid "do not use the PIN cache when signing" -msgstr "" +msgstr "não usar a cache de PIN ao assinar" -#, fuzzy msgid "disallow the use of an external password cache" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "não permitir o uso de uma cache de senhas externa" msgid "disallow clients to mark keys as \"trusted\"" -msgstr "" +msgstr "não permitir que os clientes marquem chaves como \"confiável\"" -#, fuzzy msgid "allow presetting passphrase" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "permitir pré-definir frase-secreta" msgid "Options enforcing a passphrase policy" -msgstr "" +msgstr "Opções que impõem uma política de frase-secreta" msgid "do not allow bypassing the passphrase policy" -msgstr "" +msgstr "não permitir ignorar a política de frase-secreta" msgid "|N|set minimal required length for new passphrases to N" msgstr "" +"|N|definir o comprimento mínimo necessário de N para novas frases-secretas" msgid "|N|require at least N non-alpha characters for a new passphrase" msgstr "" +"|N|exigir pelo menos N caracteres não-alfabéticos para uma nova frase-secreta" msgid "|FILE|check new passphrases against pattern in FILE" -msgstr "" +msgstr "|FILE|verificar novas frases-secretas em relação ao padrão no FILE" -#, fuzzy msgid "|N|expire the passphrase after N days" -msgstr "|N|usar mode de frase secreta N" +msgstr "|N|expirar a frase-secreta após N dias" -#, fuzzy msgid "do not allow the reuse of old passphrases" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "não permitir a reutilização de frase-secretas antigas" msgid "Options controlling the PIN-Entry" -msgstr "" +msgstr "Opções que controlam o PIN-Entry" -#, fuzzy -#| msgid "use the gpg-agent" msgid "never use the PIN-entry" -msgstr "utilizar o gpg-agent" +msgstr "nunca usar o PIN-entry" msgid "disallow caller to override the pinentry" -msgstr "" +msgstr "não permitir que o chamador sobreponha o pinentry" msgid "let PIN-Entry grab keyboard and mouse" -msgstr "" +msgstr "deixar o PIN-Entry agarrar o teclado e o rato" msgid "|PGM|use PGM as the PIN-Entry program" -msgstr "" +msgstr "|PGM|usar PGM como o programa PIN-Entry" msgid "|N|set the Pinentry timeout to N seconds" -msgstr "" +msgstr "|N|definir o tempo limite do Pinentry para N segundos" msgid "allow passphrase to be prompted through Emacs" -msgstr "" +msgstr "permitir que a frase-secreta seja perguntada pelo Emacs" #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug #. reporting address. This is so that we can change the #. reporting address without breaking the translations. -#, fuzzy msgid "Please report bugs to <@EMAIL@>.\n" -msgstr "Por favor comunique bugs para .\n" +msgstr "Reporte bugs para <@EMAIL@>.\n" -#, fuzzy msgid "Usage: @GPG_AGENT@ [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPG_AGENT@ [opções] (-h para ajuda)" msgid "" "Syntax: @GPG_AGENT@ [options] [command [args]]\n" "Secret key management for @GNUPG@\n" msgstr "" +"Sintaxe: @GPG_AGENT@ [opções] [comando [args]]\n" +"Gerir as chaves secretas para @GNUPG@\n" #, c-format msgid "invalid debug-level '%s' given\n" -msgstr "" +msgstr "fornecido debug-level inválido '%s'\n" #, c-format msgid "selected digest algorithm is invalid\n" -msgstr "o algoritmo de \"digest\" selecionado é inválido\n" +msgstr "o algoritmo de digest selecionado é inválido\n" -#, fuzzy, c-format -#| msgid "reading options from `%s'\n" +#, c-format msgid "reading options from '%s'\n" -msgstr "a ler opções de `%s'\n" +msgstr "lendo opções de '%s'\n" -#, fuzzy, c-format -#| msgid "WARNING: \"%s\" is a deprecated option\n" +#, c-format msgid "Note: '%s' is not considered an option\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "Nota: '%s' não é considerada uma opção\n" #, c-format msgid "WARNING: \"%s\" is a deprecated option\n" msgstr "AVISO: \"%s\" é uma opção depreciada\n" -#, fuzzy, c-format +#, c-format msgid "can't create socket: %s\n" -msgstr "impossível criar %s: %s\n" +msgstr "não é possível criar socket: %s\n" #, c-format msgid "socket name '%s' is too long\n" -msgstr "" +msgstr "o nome do socket '%s' é muito longo\n" #, c-format msgid "trying to steal socket from running %s\n" -msgstr "" +msgstr "tentando roubar o socket de executar %s\n" -#, fuzzy, c-format +#, c-format msgid "a gpg-agent is already running - not starting a new one\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "um gpg-agent já está em execução - não iniciando um novo\n" -#, fuzzy, c-format +#, c-format msgid "error getting nonce for the socket\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter nonce para o socket\n" -#, fuzzy, c-format +#, c-format msgid "error binding socket to '%s': %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao vincular socket a '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "can't set permissions of '%s': %s\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "não é possível definir permissões de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "listening on socket '%s'\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "ouvindo no socket '%s'\n" -#, fuzzy, c-format +#, c-format msgid "can't create directory '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "não é possível criar a pasta '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "directory '%s' created\n" -msgstr "%s: directoria criada\n" +msgstr "pasta '%s' criada\n" -#, fuzzy, c-format +#, c-format msgid "stat() failed for '%s': %s\n" -msgstr "base de dados de confiança: leitura falhou (n=%d): %s\n" +msgstr "stat() falhou para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "can't use '%s' as home directory\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "não é possível usar '%s' como pasta home\n" -#, fuzzy, c-format +#, c-format msgid "error reading nonce on fd %d: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler nonce em fd %d: %s\n" #, c-format msgid "handler 0x%lx for fd %d started\n" -msgstr "" +msgstr "handler 0x%lx para fd %d iniciado\n" #, c-format msgid "handler 0x%lx for fd %d terminated\n" -msgstr "" +msgstr "handler 0x%lx para fd %d terminado\n" #, c-format msgid "ssh handler 0x%lx for fd %d started\n" -msgstr "" +msgstr "handler ssh 0x%lx para fd %d iniciado\n" #, c-format msgid "ssh handler 0x%lx for fd %d terminated\n" -msgstr "" +msgstr "handler ssh 0x%lx para fd %d terminado\n" -#, fuzzy, c-format +#, c-format msgid "npth_pselect failed: %s - waiting 1s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "npth_pselect falhou: %s - aguardando 1s\n" -#, fuzzy, c-format +#, c-format msgid "%s %s stopped\n" -msgstr "%s: ignorado: %s\n" +msgstr "%s %s interrompido\n" -#, fuzzy, c-format +#, c-format msgid "no gpg-agent running in this session\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "nenhum gpg-agent em execução nesta sessão\n" -#, fuzzy msgid "" "@Options:\n" " " msgstr "" -"@\n" -"Opções:\n" +"@Opções:\n" " " -#, fuzzy msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: gpg-preset-passphrase [opções] KEYGRIP (-h para ajuda)\n" msgid "" "Syntax: gpg-preset-passphrase [options] KEYGRIP\n" "Password cache maintenance\n" msgstr "" +"Sintaxe: gpg-preset-passphrase [opções] KEYGRIP\n" +"Manutenção da cache de senhas\n" msgid "" "@Commands:\n" @@ -640,73 +673,75 @@ msgstr "" "Opções:\n" " " -#, fuzzy msgid "Usage: gpg-protect-tool [options] (-h for help)\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: gpg-protect-tool [opções] (-h para ajuda)\n" msgid "" "Syntax: gpg-protect-tool [options] [args]\n" "Secret key maintenance tool\n" msgstr "" +"Sintaxe: gpg-protect-tool [opções] [args]\n" +"Ferramenta de manutenção de chave secreta\n" -#, fuzzy msgid "Please enter the passphrase to unprotect the PKCS#12 object." -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para desproteger o objeto PKCS#12." -#, fuzzy msgid "Please enter the passphrase to protect the new PKCS#12 object." -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para proteger o novo objeto PKCS#12." msgid "" "Please enter the passphrase to protect the imported object within the GnuPG " "system." msgstr "" +"Introduza a frase-secreta para proteger o objeto importado dentro do sistema " +"GnuPG." -#, fuzzy msgid "" "Please enter the passphrase or the PIN\n" "needed to complete this operation." -msgstr "Por favor digite a frase secreta \n" +msgstr "" +"Introduza a frase-secreta ou o PIN\n" +"necessário para concluir esta operação." -#, fuzzy, c-format +#, c-format msgid "cancelled\n" -msgstr "cancelado pelo utilizador\n" +msgstr "cancelado\n" -#, fuzzy, c-format +#, c-format msgid "error while asking for the passphrase: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao perguntar pela frase-secreta: %s\n" -#, fuzzy, c-format +#, c-format msgid "error opening '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao abrir '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "file '%s', line %d: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "ficheiro '%s', linha %d: %s\n" -#, fuzzy, c-format +#, c-format msgid "statement \"%s\" ignored in '%s', line %d\n" -msgstr "armadura: %s\n" +msgstr "instrução \"%s\" ignorada em '%s', linha %d\n" -#, fuzzy, c-format +#, c-format msgid "system trustlist '%s' not available\n" -msgstr "partes da chave secreta não disponíveis\n" +msgstr "lista da confiança do sistema '%s' não disponível\n" -#, fuzzy, c-format +#, c-format msgid "bad fingerprint in '%s', line %d\n" -msgstr "armadura: %s\n" +msgstr "impressão digital inválida em '%s', linha %d\n" -#, fuzzy, c-format +#, c-format msgid "invalid keyflag in '%s', line %d\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "keyflag inválida em '%s', linha %d\n" -#, fuzzy, c-format +#, c-format msgid "error reading '%s', line %d: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler '%s', linha %d: %s\n" #, c-format msgid "error reading list of trusted root certificates\n" -msgstr "" +msgstr "erro ao ler lista de certificados raiz confiáveis\n" #. TRANSLATORS: This prompt is shown by the Pinentry #. and has one special property: A "%%0A" is used by @@ -721,13 +756,14 @@ msgid "" "Do you ultimately trust%%0A \"%s\"%%0Ato correctly certify user " "certificates?" msgstr "" +"Você confia plenamente em%%0A \"%s\"%%0Apara certificar corretamente " +"certificados de utilizador?" -#, fuzzy msgid "Yes" -msgstr "sim" +msgstr "Sim" msgid "No" -msgstr "" +msgstr "Não" #. TRANSLATORS: This prompt is shown by the Pinentry and has #. one special property: A "%%0A" is used by Pinentry to @@ -742,157 +778,141 @@ msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " "fingerprint:%%0A %s" msgstr "" +"Verifique que o certificado identificado como:%%0A \"%s\"%%0Atem a " +"impressão digital:%%0A %s" #. TRANSLATORS: "Correct" is the label of a button and intended #. to be hit if the fingerprint matches the one of the CA. The #. other button is "the default "Cancel" of the Pinentry. msgid "Correct" -msgstr "" +msgstr "Correta" msgid "Wrong" -msgstr "" +msgstr "Errada" #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." -msgstr "" +msgstr "Nota: Esta frase-secreta nunca foi alterada.%0AAltere-a agora." #, c-format msgid "" "This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s. Please change " "it now." msgstr "" +"Esta frase-secreta não foi alterada%%0Adesde %.4s-%.2s-%.2s. Altere-a agora." -#, fuzzy msgid "Change passphrase" -msgstr "muda a frase secreta" +msgstr "Alterar frase-secreta" msgid "I'll change it later" -msgstr "" +msgstr "Vou alterá-la mais tarde" msgid "Please insert the card with serial number" -msgstr "" +msgstr "Insira o cartão com o número de série" #, c-format msgid "Requested the use of key%%0A %s%%0A %s%%0ADo you want to allow this?" -msgstr "" +msgstr "Pediu o uso da chave%%0A %s%%0A %s%%0ADeseja permitir isso?" -#, fuzzy, c-format +#, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" -msgstr "Você quer realmente remover as chaves selecionadas? " +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" +msgstr "" +"De certeza que você deseja apagar a chave identificada por keygrip%%0A " +"%s%%0A %%C%%0A?" -#, fuzzy msgid "Delete key" -msgstr "activa uma chave" +msgstr "Apagar chave" msgid "" "Warning: This key is also listed for use with SSH!\n" "Deleting the key might remove your ability to access remote machines." msgstr "" +"Aviso: Esta chave também está listada para uso com SSH!\n" +"Apagar esta chave pode remover sua capacidade de aceder máquinas remotas." #, c-format msgid "DSA requires the hash length to be a multiple of 8 bits\n" -msgstr "" +msgstr "o DSA requer que o comprimento da hash seja um múltiplo de 8 bits\n" #, c-format msgid "%s key uses an unsafe (%u bit) hash\n" -msgstr "" +msgstr "a chave %s usa um hash inseguro (%u bit)\n" #, c-format msgid "a %zu bit hash is not valid for a %u bit %s key\n" -msgstr "" +msgstr "um hash de %zu bit não é válido para os %u bit de uma chave %s\n" #, c-format msgid "checking created signature failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "a verificação da assinatura criada falhou: %s\n" #, c-format msgid "secret key parts are not available\n" msgstr "partes da chave secreta não disponíveis\n" -#, fuzzy, c-format -#| msgid "protection algorithm %d%s is not supported\n" +#, c-format msgid "public key algorithm %d (%s) is not supported\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "o algoritmo de chave pública %d (%s) não é suportado\n" -#, fuzzy, c-format -#| msgid "protection algorithm %d%s is not supported\n" +#, c-format msgid "protection algorithm %d (%s) is not supported\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "o algoritmo de proteção %d (%s) não é suportado\n" -#, fuzzy, c-format -#| msgid "protection algorithm %d%s is not supported\n" +#, c-format msgid "protection hash algorithm %d (%s) is not supported\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "o algoritmo de proteção de hash %d (%s) não é suportado\n" -#, fuzzy, c-format +#, c-format msgid "error creating a pipe: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar um pipe: %s\n" -#, fuzzy, c-format +#, c-format msgid "error creating a stream for a pipe: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar um fluxo para um pipe: %s\n" -#, fuzzy, c-format +#, c-format msgid "error forking process: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fazer fork de processo: %s\n" #, c-format msgid "waiting for process %d to terminate failed: %s\n" -msgstr "" +msgstr "falha ao aguardar pelo encerramento do processo %d: %s\n" -#, fuzzy, c-format -msgid "error running '%s': probably not installed\n" -msgstr "erro na leitura de `%s': %s\n" +#, c-format +msgid "waiting for process to terminate failed: ec=%d\n" +msgstr "falha ao esperar que o processo terminasse: ec=%d\n" -#, fuzzy, c-format -msgid "error running '%s': exit status %d\n" -msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy, c-format -msgid "error running '%s': terminated\n" -msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy, c-format -msgid "waiting for processes to terminate failed: %s\n" -msgstr "actualização falhou: %s\n" - -#, fuzzy, c-format -msgid "error getting exit code of process %d: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" - -#, fuzzy, c-format -#| msgid "can't connect to `%s': %s\n" +#, c-format msgid "can't connect to '%s': %s\n" -msgstr "impossível ligar a `%s': %s\n" +msgstr "não é possível conectar-se a '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "problem setting the gpg-agent options\n" -msgstr "problema com o agente: o agente returnou 0x%lx\n" +msgstr "problema ao definir as opções do gpg-agent\n" #, c-format msgid "can't disable core dumps: %s\n" -msgstr "impossível desactivar core dumps: %s\n" +msgstr "não é possível desabilitar core dumps: %s\n" -#, fuzzy, c-format +#, c-format msgid "Warning: unsafe ownership on %s \"%s\"\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "Aviso: ownership não seguro em %s \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "Warning: unsafe permissions on %s \"%s\"\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "Aviso: permissões não seguras em %s \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "waiting for file '%s' to become accessible ...\n" -msgstr "actualização falhou: %s\n" +msgstr "aguardando que o ficheiro '%s' se torne acessível...\n" -#, fuzzy, c-format +#, c-format msgid "renaming '%s' to '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha ao renomear '%s' para '%s': %s\n" #. TRANSLATORS: See doc/TRANSLATE about this string. -#, fuzzy msgid "yes" msgstr "sim" @@ -915,398 +935,369 @@ msgstr "qQ" #. TRANSLATORS: See doc/TRANSLATE about this string. msgid "okay|okay" -msgstr "" +msgstr "okay|ok" #. TRANSLATORS: See doc/TRANSLATE about this string. msgid "cancel|cancel" -msgstr "" +msgstr "cancelar" msgid "oO" -msgstr "" +msgstr "oO" -#, fuzzy msgid "cC" -msgstr "c" +msgstr "cC" #, c-format msgid "out of core in secure memory while allocating %lu bytes" -msgstr "" +msgstr "fora do core na memória segura ao alocar %lu bytes" #, c-format msgid "out of core while allocating %lu bytes" -msgstr "" +msgstr "fora do core ao alocar %lu bytes" -#, fuzzy, c-format +#, c-format msgid "error allocating enough memory: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro tentando alocar memória suficiente: %s\n" #, c-format msgid "%s:%u: obsolete option \"%s\" - it has no effect\n" -msgstr "" +msgstr "%s:%u: opção obsoleta \"%s\" - não tem efeito\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "AVISO: \"%s%s\" é uma opção obsoleta - não tem efeito\n" #, c-format msgid "unknown debug flag '%s' ignored\n" -msgstr "" +msgstr "debug flag desconhecida '%s' ignorada\n" -#, fuzzy, c-format +#, c-format msgid "waiting for the dirmngr to come up ... (%ds)\n" -msgstr "actualização falhou: %s\n" +msgstr "a esperar que o dirmngr apareça... (%ds)\n" -#, fuzzy, c-format +#, c-format msgid "waiting for the keyboxd to come up ... (%ds)\n" -msgstr "actualização falhou: %s\n" +msgstr "a esperar que o keyboxd apareça... (%ds)\n" -#, fuzzy, c-format +#, c-format msgid "waiting for the agent to come up ... (%ds)\n" -msgstr "actualização falhou: %s\n" +msgstr "a esperar que o agent apareça... (%ds)\n" -#, fuzzy, c-format +#, c-format msgid "connection to the dirmngr established\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "conexão com o dirmngr estabelecida\n" -#, fuzzy, c-format +#, c-format msgid "connection to the keyboxd established\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "conexão com o keyboxd estabelecida\n" -#, fuzzy, c-format +#, c-format msgid "connection to the agent established\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "conexão com o agent estabelecida\n" -#, fuzzy, c-format +#, c-format msgid "no running %s - starting '%s'\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "sem execução de %s - iniciando '%s'\n" -#, fuzzy, c-format +#, c-format msgid "connection to the agent is in restricted mode\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "conexão com o agent está no modo restrito\n" -#, fuzzy, c-format -#| msgid "error creating keyring `%s': %s\n" +#, c-format msgid "error getting version from '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao obter a versão de '%s': %s\n" #, c-format msgid "server '%s' is older than us (%s < %s)" -msgstr "" +msgstr "o servidor '%s' é mais antigo que nós (%s < %s)" -#, fuzzy, c-format -#| msgid "WARNING: %s overrides %s\n" +#, c-format msgid "WARNING: %s\n" -msgstr "AVISO: %s sobrepõe %s\n" +msgstr "AVISO: %s\n" #, c-format msgid "Note: Outdated servers may lack important security fixes.\n" msgstr "" +"Nota: Servidores desatualizados podem não ter correções de segurança " +"importantes.\n" -#, fuzzy, c-format -#| msgid "Please use the command \"toggle\" first.\n" +#, c-format msgid "Note: Use the command \"%s\" to restart them.\n" -msgstr "Por favor utilize o comando \"toggle\" primeiro.\n" +msgstr "Nota: Usar o comando \"%s\" para reiniciá-los.\n" #. TRANSLATORS: Copy the prefix between the vertical bars #. verbatim. It will not be printed. msgid "|audit-log-result|Good" -msgstr "" +msgstr "|audit-log-result|Válido" msgid "|audit-log-result|Bad" -msgstr "" +msgstr "|audit-log-result|Inválido" msgid "|audit-log-result|Not supported" -msgstr "" +msgstr "|audit-log-result|Não suportado" -#, fuzzy msgid "|audit-log-result|No certificate" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Sem certificado" -#, fuzzy msgid "|audit-log-result|Not enabled" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Não habilitado" msgid "|audit-log-result|Error" -msgstr "" +msgstr "|audit-log-result|Erro" -#, fuzzy msgid "|audit-log-result|Not used" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Não utilizado" -#, fuzzy msgid "|audit-log-result|Okay" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Okay" -#, fuzzy msgid "|audit-log-result|Skipped" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Ignorado" -#, fuzzy msgid "|audit-log-result|Some" -msgstr "certificado incorrecto" +msgstr "|audit-log-result|Algum" -#, fuzzy msgid "Certificate chain available" -msgstr "certificado incorrecto" +msgstr "Corrente de certificados disponível" -#, fuzzy msgid "root certificate missing" -msgstr "certificado incorrecto" +msgstr "certificado raiz ausente" msgid "Data encryption succeeded" -msgstr "" +msgstr "Cifração de dados bem-sucedida" -#, fuzzy msgid "Data available" -msgstr "Nenhuma ajuda disponível" +msgstr "Dados disponíveis" -#, fuzzy msgid "Session key created" -msgstr "%s: porta-chaves criado\n" +msgstr "Chave de sessão criada" -#, fuzzy, c-format +#, c-format msgid "algorithm: %s" -msgstr "armadura: %s\n" +msgstr "algoritmo: %s" -#, fuzzy, c-format +#, c-format msgid "unsupported algorithm: %s" -msgstr "" -"\n" -"Algoritmos suportados:\n" +msgstr "algoritmo não suportado: %s" -#, fuzzy msgid "seems to be not encrypted" -msgstr "não cifrado" +msgstr "parece não estar cifrado" msgid "Number of recipients" -msgstr "" +msgstr "Número de destinatários" #, c-format msgid "Recipient %d" -msgstr "" +msgstr "Destinatário %d" msgid "Data signing succeeded" -msgstr "" +msgstr "Assinatura de dados bem-sucedida" -#, fuzzy, c-format +#, c-format msgid "data hash algorithm: %s" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash de dados: %s" -#, fuzzy, c-format +#, c-format msgid "Signer %d" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Signatário %d" -#, fuzzy, c-format +#, c-format msgid "attr hash algorithm: %s" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash attr: %s" msgid "Data decryption succeeded" -msgstr "" +msgstr "Decifração de dados bem-sucedida" -#, fuzzy msgid "Encryption algorithm supported" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "Algoritmo de cifração suportado" -#, fuzzy msgid "Data verification succeeded" -msgstr "verificação de assinatura suprimida\n" +msgstr "Verificação de dados bem-sucedida" -#, fuzzy msgid "Signature available" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Assinatura disponível" -#, fuzzy msgid "Parsing data succeeded" -msgstr "Assinatura correcta de \"" +msgstr "Processamento de dados foi bem-sucedido" -#, fuzzy, c-format +#, c-format msgid "bad data hash algorithm: %s" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash de dados inválido: %s" -#, fuzzy, c-format +#, c-format msgid "Signature %d" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Assinatura %d" -#, fuzzy msgid "Certificate chain valid" -msgstr "Esta chave expirou!" +msgstr "Corrente de certificados válida" -#, fuzzy msgid "Root certificate trustworthy" -msgstr "certificado incorrecto" +msgstr "Certificado raiz confiável" -#, fuzzy msgid "no CRL found for certificate" -msgstr "certificado incorrecto" +msgstr "nenhuma CRL encontrada para o certificado" -#, fuzzy msgid "the available CRL is too old" -msgstr "Nenhuma ajuda disponível" +msgstr "a CRL disponível é muito antiga" -#, fuzzy msgid "CRL/OCSP check of certificates" -msgstr "certificado incorrecto" +msgstr "verificação CRL/OCSP de certificados" -#, fuzzy msgid "Included certificates" -msgstr "certificado incorrecto" +msgstr "Certificados incluídos" msgid "No audit log entries." -msgstr "" +msgstr "Nenhuma entrada de log de auditoria." -#, fuzzy msgid "Unknown operation" -msgstr "versão desconhecida" +msgstr "Operação desconhecida" msgid "Gpg-Agent usable" -msgstr "" +msgstr "Gpg-Agent utilizável" msgid "Dirmngr usable" -msgstr "" +msgstr "Dirmngr utilizável" -#, fuzzy, c-format +#, c-format msgid "No help available for '%s'." -msgstr "Nenhuma ajuda disponível para `%s'" +msgstr "Nenhuma ajuda disponível para '%s'." -#, fuzzy msgid "ignoring garbage line" -msgstr "erro na última linha\n" +msgstr "ignorando linha de lixo" -#, fuzzy msgid "[none]" -msgstr "versão desconhecida" +msgstr "[nenhum]" -#, fuzzy, c-format +#, c-format msgid "invalid radix64 character %02x skipped\n" -msgstr "caracter radix64 inválido %02x ignorado\n" +msgstr "caractere radix64 inválido %02x ignorado\n" #, c-format msgid "Sorry, we are in batchmode - can't get input\n" -msgstr "" +msgstr "Desculpe, estamos em modo batch - não é possível obter a entrada\n" #, c-format msgid "Sorry, no terminal at all requested - can't get input\n" -msgstr "" +msgstr "Desculpe, nenhum terminal pedido - não é possível obter a entrada\n" #, c-format msgid "too many errors; giving up\n" -msgstr "" +msgstr "muitos erros; desistindo\n" #, c-format msgid "Control-D detected\n" -msgstr "" +msgstr "Control-D detetado\n" -#, fuzzy, c-format +#, c-format msgid "conversion from '%s' to '%s' not available\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "conversão de '%s' para '%s' não disponível\n" -#, fuzzy, c-format +#, c-format msgid "iconv_open failed: %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "iconv_open falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "conversion from '%s' to '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha na conversão de '%s' para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to create temporary file '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "falha ao criar o ficheiro temporário '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error writing to '%s': %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao escrever em '%s': %s\n" #, c-format msgid "removing stale lockfile (created by %d)\n" -msgstr "" +msgstr "removendo ficheiro de bloqueio obsoleto (criado por %d)\n" -#, fuzzy, c-format +#, c-format msgid "waiting for lock (held by %d%s) %s...\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "aguardando bloqueio (mantido por %d%s) %s...\n" msgid "(deadlock?) " -msgstr "" +msgstr "(deadlock?) " -#, fuzzy, c-format +#, c-format msgid "lock '%s' not made: %s\n" -msgstr "chave pública %08lX não encontrada: %s\n" +msgstr "bloqueio '%s' não feito: %s\n" -#, fuzzy, c-format +#, c-format msgid "waiting for lock %s...\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "aguardando bloqueio %s...\n" #, c-format msgid "%s is too old (need %s, have %s)\n" -msgstr "" +msgstr "%s é muito antigo (precisa de %s, tem %s)\n" -#, fuzzy, c-format -#| msgid "error creating `%s': %s\n" +#, c-format msgid "error creating '%s': %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "erro ao criar '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error closing '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fechar '%s': %s\n" #, c-format msgid "armor: %s\n" -msgstr "armadura: %s\n" +msgstr "blindagem: %s\n" #, c-format msgid "invalid armor header: " -msgstr "cabeçalho de armadura inválido: " +msgstr "cabeçalho da blindagem inválido: " #, c-format msgid "armor header: " -msgstr "cabeçalho de armadura: " +msgstr "cabeçalho da blindagem: " #, c-format msgid "invalid clearsig header\n" -msgstr "cabeçalho de assinatura em texto puro inválido\n" +msgstr "cabeçalho clearsig inválido\n" -#, fuzzy, c-format +#, c-format msgid "unknown armor header: " -msgstr "cabeçalho de armadura: " +msgstr "cabeçalho da blindagem desconhecido: " #, c-format msgid "nested clear text signatures\n" -msgstr "assinaturas em texto puro aninhadas\n" +msgstr "assinaturas de texto claro aninhadas\n" -#, fuzzy, c-format +#, c-format msgid "unexpected armor: " -msgstr "armadura inesperada:" +msgstr "blindagem inesperada: " #, c-format msgid "invalid dash escaped line: " -msgstr "linha com hífen inválida: " +msgstr "traço inválido escapou linha: " -#, fuzzy, c-format +#, c-format msgid "invalid radix64 character %02X skipped\n" -msgstr "caracter radix64 inválido %02x ignorado\n" +msgstr "caractere radix64 inválido %02X ignorado\n" #, c-format msgid "premature eof (no CRC)\n" -msgstr "fim de ficheiro prematuro (sem CRC)\n" +msgstr "EOF prematuro (sem CRC)\n" #, c-format msgid "premature eof (in CRC)\n" -msgstr "fim de ficheiro prematuro (no CRC)\n" +msgstr "EOF prematuro (no CRC)\n" #, c-format msgid "malformed CRC\n" msgstr "CRC malformado\n" -#, fuzzy, c-format +#, c-format msgid "CRC error; %06lX - %06lX\n" -msgstr "erro de CRC; %06lx - %06lx\n" +msgstr "erro de CRC; %06lX - %06lX\n" -#, fuzzy, c-format +#, c-format msgid "premature eof (in trailer)\n" -msgstr "fim de ficheiro prematuro (no \"Trailer\")\n" +msgstr "EOF prematuro (em rodapé)\n" #, c-format msgid "error in trailer line\n" -msgstr "erro na última linha\n" +msgstr "erro na linha de rodapé\n" #, c-format msgid "no valid OpenPGP data found.\n" @@ -1314,19 +1305,18 @@ msgstr "nenhum dado OpenPGP válido encontrado.\n" #, c-format msgid "invalid armor: line longer than %d characters\n" -msgstr "armadura inválida: linha maior que %d caracteres\n" +msgstr "blindagem inválida: linha maior que %d caracteres\n" #, c-format msgid "" "quoted printable character in armor - probably a buggy MTA has been used\n" msgstr "" -"caracter \"quoted printable\" na armadura - provavelmente um MTA com bugs " -"foi usado\n" +"caractere imprimível citado na blindagem - provavelmente uma MTA bugada foi " +"usada\n" -#, fuzzy, c-format -#| msgid "not human readable" +#, c-format msgid "[ not human readable (%zu bytes: %s%s) ]" -msgstr "não legível por humanos" +msgstr "[ não legível para humanos (%zu bytes: %s%s) ]" #, c-format msgid "" @@ -1338,28 +1328,23 @@ msgstr "" #, c-format msgid "a user notation name must contain the '@' character\n" -msgstr "um valor de notação de utilizador não deve conter o caracter '@'\n" +msgstr "um nome de notação de utilizador deve conter o caractere '@'\n" -#, fuzzy, c-format +#, c-format msgid "a notation name must not contain more than one '@' character\n" -msgstr "um valor de notação de utilizador não deve conter o caracter '@'\n" +msgstr "um nome de notação não deve conter mais de um caractere '@'\n" #, c-format msgid "a notation value must not use any control characters\n" msgstr "um valor de notação não deve usar caracteres de controle\n" -#, fuzzy, c-format +#, c-format msgid "a notation name may not contain an '=' character\n" -msgstr "um valor de notação de utilizador não deve conter o caracter '@'\n" +msgstr "um nome de notação pode não conter um caractere '='\n" -#, fuzzy, c-format -#| msgid "" -#| "a notation name must have only printable characters or spaces, and end " -#| "with an '='\n" +#, c-format msgid "a notation name must have only printable characters or spaces\n" -msgstr "" -"um nome de notação deve ter apenas caracteres imprimíveis ou espaços, e " -"terminar com um '='\n" +msgstr "um nome de notação deve ter apenas caracteres imprimíveis ou espaços\n" #, c-format msgid "WARNING: invalid notation data found\n" @@ -1367,184 +1352,173 @@ msgstr "AVISO: dados de notação inválidos encontrados\n" #, c-format msgid "failed to proxy %s inquiry to client\n" -msgstr "" +msgstr "falha ao reencaminhar inquérito %s para o cliente\n" msgid "Enter passphrase: " -msgstr "Digite a frase secreta: " +msgstr "Introduzir a frase-secreta: " -#, fuzzy, c-format +#, c-format msgid "%s is not compliant with %s mode\n" -msgstr "%s não faz sentido com %s!\n" +msgstr "%s não é compatível com o modo %s\n" -#, fuzzy, c-format +#, c-format msgid "error from TPM: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro do TPM: %s\n" -#, fuzzy, c-format +#, c-format msgid "problem with the agent: %s\n" -msgstr "problema com o agente: o agente returnou 0x%lx\n" +msgstr "problema com o agent: %s\n" -#, fuzzy, c-format +#, c-format msgid "no dirmngr running in this session\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "nenhum dirmngr em execução nesta sessão\n" -#, fuzzy, c-format -#| msgid "you may not use %s while in %s mode\n" +#, c-format msgid "keyserver option \"honor-keyserver-url\" may not be used in Tor mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "" +"opção de servidor de chaves \"honor-keyserver-url\" não pode ser usada no " +"modo Tor\n" msgid "WKD uses a cached result" -msgstr "" +msgstr "WKD usa um resultado armazenado em cache" msgid "Tor is not running" -msgstr "" +msgstr "Tor não está em execução" -#, fuzzy msgid "Tor is not properly configured" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "Tor não está configurado corretamente" -#, fuzzy msgid "DNS is not properly configured" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "DNS não está configurado corretamente" msgid "unacceptable HTTP redirect from server" -msgstr "" +msgstr "redirecionamento HTTP inaceitável do servidor" msgid "unacceptable HTTP redirect from server was cleaned up" -msgstr "" +msgstr "redirecionamento HTTP inaceitável do servidor foi limpo" -#, fuzzy -#| msgid "generate a revocation certificate" msgid "server uses an invalid certificate" -msgstr "gerar um certificado de revogação" +msgstr "servidor usa um certificado inválido" -#, fuzzy, c-format -#| msgid "armor: %s\n" +#, c-format msgid "Note: %s\n" -msgstr "armadura: %s\n" +msgstr "Nota: %s\n" -#, fuzzy, c-format +#, c-format msgid "OpenPGP card not available: %s\n" -msgstr "chave secreta não disponível" +msgstr "cartão OpenPGP não disponível: %s\n" #, c-format msgid "OpenPGP card no. %s detected\n" -msgstr "" +msgstr "cartão OpenPGP nº %s detetado\n" -#, fuzzy, c-format +#, c-format msgid "can't do this in batch mode\n" -msgstr "impossível fazer isso em modo não-interativo\n" +msgstr "não é possível fazer isso no modo batch\n" -#, fuzzy, c-format +#, c-format msgid "This command is only available for version 2 cards\n" -msgstr "Este comando não é permitido no modo %s.\n" +msgstr "Este comando só está disponível para cartões da versão 2\n" -#, fuzzy, c-format +#, c-format msgid "Reset Code not or not anymore available\n" -msgstr "partes da chave secreta não disponíveis\n" +msgstr "Código de Reset não disponível ou não está mais disponível\n" msgid "Your selection? " -msgstr "Opção? " +msgstr "Sua opção? " msgid "[not set]" -msgstr "" +msgstr "[não definido]" msgid "Mr." -msgstr "" +msgstr "Sr." msgid "Ms." -msgstr "" +msgstr "Sra." -#, fuzzy msgid "not forced" -msgstr "não processado" +msgstr "não forçado" msgid "forced" -msgstr "" +msgstr "forçado" #, c-format msgid "Please try command \"%s\" if the listing does not look correct\n" -msgstr "" +msgstr "Tente o comando \"%s\" se a listagem não parecer correta\n" msgid "Error: Only plain ASCII is currently allowed.\n" -msgstr "" +msgstr "Erro: Só ASCII simples é permitido de momento.\n" msgid "Error: The \"<\" character may not be used.\n" -msgstr "" +msgstr "Erro: O caractere \"<\" não pode ser usado.\n" msgid "Error: Double spaces are not allowed.\n" -msgstr "" +msgstr "Erro: Espaços duplos não são permitidos.\n" msgid "Cardholder's surname: " -msgstr "" +msgstr "Nome de família do titular do cartão: " msgid "Cardholder's given name: " -msgstr "" +msgstr "Nome próprio do titular do cartão: " #, c-format msgid "Error: Combined name too long (limit is %d characters).\n" -msgstr "" +msgstr "Erro: Nome combinado muito longo (limite é %d caracteres).\n" -#, fuzzy msgid "URL to retrieve public key: " -msgstr "a escrever chave pública para `%s'\n" +msgstr "URL para buscar a chave pública: " -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" +#, c-format msgid "error reading '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error writing '%s': %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao escrever '%s': %s\n" msgid "Login data (account name): " -msgstr "" +msgstr "Dados de login (nome da conta): " msgid "Private DO data: " -msgstr "" +msgstr "Dados DO privados: " -#, fuzzy msgid "Language preferences: " -msgstr "preferências actualizadas" +msgstr "Preferências de idioma: " -#, fuzzy, c-format +#, c-format msgid "Error: invalid length of preference string.\n" -msgstr "caracter inválido na cadeia de caractéres da preferência\n" +msgstr "Erro: comprimento inválido da string de preferência.\n" -#, fuzzy, c-format +#, c-format msgid "Error: invalid characters in preference string.\n" -msgstr "caracter inválido na cadeia de caractéres da preferência\n" +msgstr "Erro: caracteres inválidos na string de preferência.\n" msgid "Salutation (M = Mr., F = Ms., or space): " -msgstr "" +msgstr "Saudação (M = Sr., F = Sra., ou espaço): " -#, fuzzy msgid "Error: invalid response.\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "Erro: resposta inválida.\n" -#, fuzzy msgid "CA fingerprint: " -msgstr "mostra impressão digital" +msgstr "Impressão digital da CA: " -#, fuzzy, c-format +#, c-format msgid "Error: invalid formatted fingerprint.\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "Erro: impressão digital formatada inválida.\n" -#, fuzzy, c-format +#, c-format msgid "key operation not possible: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "operação de chave não é possível: %s\n" -#, fuzzy msgid "not an OpenPGP card" -msgstr "nenhum dado OpenPGP válido encontrado.\n" +msgstr "não é um cartão OpenPGP" -#, fuzzy, c-format +#, c-format msgid "error getting current key info: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao obter informações de chave atual: %s\n" msgid "Replace existing key? (y/N) " -msgstr "" +msgstr "Substituir chave existente? (s/N) " msgid "" "Note: There is no guarantee that the card supports the requested\n" @@ -1552,10 +1526,14 @@ msgid "" " please check the documentation of your card to see which\n" " key types and sizes are supported.\n" msgstr "" +"Nota: Não há garantia de que o cartão suporte o tipo ou tamanho de\n" +" chave pedida. Se a geração de chaves não for bem-sucedida,\n" +" verifique a documentação do seu cartão para ver quais são os\n" +" tipos e tamanhos de chaves suportados.\n" -#, fuzzy, c-format +#, c-format msgid "What keysize do you want? (%u) " -msgstr "Qual o tamanho de chave desejado? (1024) " +msgstr "Qual tamanho de chave você quer? (%u) " #, c-format msgid "rounded up to %u bits\n" @@ -1563,66 +1541,63 @@ msgstr "arredondado para %u bits\n" #, c-format msgid "%s keysizes must be in the range %u-%u\n" -msgstr "" +msgstr "%s tamanhos de chaves devem estar no intervalo %u-%u\n" msgid "Changing card key attribute for: " -msgstr "" +msgstr "Alterando o atributo de chave do cartão para: " -#, fuzzy msgid "Signature key\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Chave de assinatura\n" -#, fuzzy msgid "Encryption key\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr "Chave de cifração\n" msgid "Authentication key\n" -msgstr "" +msgstr "Chave de autenticação\n" msgid "Please select what kind of key you want:\n" -msgstr "Por favor selecione o tipo de chave desejado:\n" +msgstr "Selecione o tipo de chave desejado:\n" -#, fuzzy, c-format +#, c-format msgid " (%d) RSA\n" -msgstr " (%d) RSA (apenas assinatura)\n" +msgstr " (%d) RSA\n" -#, fuzzy, c-format +#, c-format msgid " (%d) ECC\n" -msgstr " (%d) DSA e ElGamal (por omissão)\n" +msgstr " (%d) ECC\n" msgid "Invalid selection.\n" -msgstr "Opção inválida.\n" +msgstr "Seleção inválida.\n" #, c-format msgid "The card will now be re-configured to generate a key of %u bits\n" -msgstr "" +msgstr "O cartão agora será reconfigurado para gerar uma chave de %u bits\n" #, c-format msgid "The card will now be re-configured to generate a key of type: %s\n" -msgstr "" +msgstr "O cartão agora será reconfigurado para gerar uma chave do tipo: %s\n" -#, fuzzy, c-format +#, c-format msgid "error changing key attribute for key %d: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao alterar o atributo de chave para a chave %d: %s\n" -#, fuzzy, c-format +#, c-format msgid "error getting card info: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao obter informações do cartão: %s\n" -#, fuzzy, c-format -#| msgid "This command is not allowed while in %s mode.\n" +#, c-format msgid "This command is not supported by this card\n" -msgstr "Este comando não é permitido no modo %s.\n" +msgstr "Este comando não é suportado por este cartão\n" msgid "Make off-card backup of encryption key? (Y/n) " -msgstr "" +msgstr "Fazer backup fora-do-cartão da chave de cifração? (S/n) " -#, fuzzy, c-format +#, c-format msgid "Note: keys are already stored on the card!\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "Nota: as chaves já estão armazenadas no cartão!\n" msgid "Replace existing keys? (y/N) " -msgstr "" +msgstr "Substituir chaves existentes? (s/N) " #, c-format msgid "" @@ -1630,138 +1605,121 @@ msgid "" " PIN = '%s' Admin PIN = '%s'\n" "You should change them using the command --change-pin\n" msgstr "" +"Observe que as configurações de fábrica dos PINs são\n" +" PIN = '%s' PIN do Admin = '%s'\n" +"Você deve alterá-los usando o comando --change-pin\n" -#, fuzzy msgid "Please select the type of key to generate:\n" -msgstr "Por favor selecione o tipo de chave desejado:\n" +msgstr "Selecione o tipo de chave a ser gerada:\n" -#, fuzzy msgid " (1) Signature key\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr " (1) Chave de assinatura\n" -#, fuzzy msgid " (2) Encryption key\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (2) Chave de cifração\n" msgid " (3) Authentication key\n" -msgstr "" +msgstr " (3) Chave de autenticação\n" -#, fuzzy msgid "Please select where to store the key:\n" -msgstr "motivo da revocação: " +msgstr "Selecione onde armazenar a chave:\n" -#, fuzzy, c-format +#, c-format msgid "KEYTOCARD failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "Falha no KEYTOCARD: %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: This command destroys all keys stored on the card!\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "Nota: Este comando destrói todas as chaves armazenadas no cartão!\n" -#, fuzzy msgid "Continue? (y/N) " -msgstr "Realmente assinar? " +msgstr "Continuar? (s/N) " msgid "Really do a factory reset? (enter \"yes\") " -msgstr "" +msgstr "De certeza que deseja fazer um reset de fábrica? (introduzir \"sim\") " -#, fuzzy, c-format +#, c-format msgid "error for setup KDF: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro para a configuração KDF: %s\n" -#, fuzzy, c-format +#, c-format msgid "error for setup UIF: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro para a configuração UIF: %s\n" msgid "quit this menu" msgstr "sair deste menu" -#, fuzzy msgid "show admin commands" -msgstr "comandos em conflito\n" +msgstr "mostrar comandos de admin" msgid "show this help" msgstr "mostra esta ajuda" -#, fuzzy msgid "list all available data" -msgstr "Nenhuma ajuda disponível" +msgstr "listar todos os dados disponíveis" msgid "change card holder's name" -msgstr "" +msgstr "alterar o nome do titular do cartão" msgid "change URL to retrieve key" -msgstr "" +msgstr "alterar URL para buscar a chave" msgid "fetch the key specified in the card URL" -msgstr "" +msgstr "buscar a chave especificada na URL do cartão" -#, fuzzy msgid "change the login name" -msgstr "muda a data de validade" +msgstr "alterar o nome de login" -#, fuzzy msgid "change the language preferences" -msgstr "muda os valores de confiança" +msgstr "alterar as preferências de idioma" msgid "change card holder's salutation" -msgstr "" +msgstr "alterar a saudação do titular do cartão" -#, fuzzy msgid "change a CA fingerprint" -msgstr "mostra impressão digital" +msgstr "alterar uma impressão digital da CA" msgid "toggle the signature force PIN flag" -msgstr "" +msgstr "alternar a flag de PIN forçado de assinatura" -#, fuzzy msgid "generate new keys" -msgstr "gerar um novo par de chaves" +msgstr "gerar novas chaves" msgid "menu to change or unblock the PIN" -msgstr "" +msgstr "menu para alterar ou desbloquear o PIN" msgid "verify the PIN and list all data" -msgstr "" +msgstr "verificar o PIN e listar todos os dados" msgid "unblock the PIN using a Reset Code" -msgstr "" +msgstr "desbloquear o PIN usando um Código de Reset" msgid "destroy all keys and data" -msgstr "" +msgstr "destruir todas as chaves e dados" -#, fuzzy -#| msgid "|NAME|use NAME as default recipient" msgid "setup KDF for PIN authentication (on/single/off)" -msgstr "|NOME|usar NOME como destinatário por omissão" +msgstr "configurar o KDF para autenticação por PIN (on/single/off)" -#, fuzzy -#| msgid "change the ownertrust" msgid "change the key attribute" -msgstr "muda os valores de confiança" +msgstr "alterar o atributo da chave" -#, fuzzy -#| msgid "change the ownertrust" msgid "change the User Interaction Flag" -msgstr "muda os valores de confiança" +msgstr "alterar a Flag User Interaction" msgid "switch to the OpenPGP app" -msgstr "" +msgstr "mudar para a app OpenPGP" msgid "gpg/card> " -msgstr "" +msgstr "gpg/cartão> " -#, fuzzy msgid "Admin-only command\n" -msgstr "comandos em conflito\n" +msgstr "Comando só-de-Admin\n" -#, fuzzy msgid "Admin commands are allowed\n" -msgstr "comandos em conflito\n" +msgstr "Comandos de Admin são permitidos\n" -#, fuzzy msgid "Admin commands are not allowed\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "Comandos de Admin não são permitidos\n" #, c-format msgid "Invalid command (try \"help\")\n" @@ -1771,74 +1729,70 @@ msgstr "Comando inválido (tente \"help\")\n" msgid "--output doesn't work for this command\n" msgstr "--output não funciona para este comando\n" -#, fuzzy, c-format -#| msgid "can't open `%s'\n" +#, c-format msgid "can't open '%s'\n" -msgstr "impossível abrir `%s'\n" +msgstr "não é possível abrir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "key \"%s\" not found: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave \"%s\" não encontrada: %s\n" #, c-format msgid "error reading keyblock: %s\n" -msgstr "erro na leitura do bloco de chave: %s\n" +msgstr "erro ao ler keyblock: %s\n" -#, fuzzy, c-format +#, c-format msgid "key \"%s\" not found\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave \"%s\" não encontrada\n" -#, fuzzy, c-format +#, c-format msgid "can't do this in batch mode without \"--yes\"\n" -msgstr "impossível fazer isso em modo não-interactivo sem utilizar \"--yes\"\n" +msgstr "não é possível fazer isso no modo batch sem \"--yes\"\n" #, c-format msgid "(unless you specify the key by fingerprint)\n" -msgstr "(a não ser que escolha a chave pela sua impressão digital)\n" +msgstr "(a menos que você especifique a chave por impressão digital)\n" msgid "Note: The public primary key and all its subkeys will be deleted.\n" msgstr "" +"Nota: A chave pública principal e todas as suas subchaves serão apagadas.\n" msgid "Note: Only the shown public subkey will be deleted.\n" -msgstr "" +msgstr "Nota: Só a subchave pública mostrada será apagada.\n" msgid "Note: Only the secret part of the shown primary key will be deleted.\n" -msgstr "" +msgstr "Nota: Só a parte secreta da chave principal mostrada será apagada.\n" msgid "Note: Only the secret part of the shown subkey will be deleted.\n" -msgstr "" +msgstr "Nota: Só a parte secreta da subchave mostrada será apagada.\n" -#, fuzzy msgid "Delete this key from the keyring? (y/N) " -msgstr "Remover esta chave do porta-chaves?" +msgstr "Apagar esta chave do porta-chaves? (s/N) " -#, fuzzy msgid "This is a secret key! - really delete? (y/N) " -msgstr "Esta chave é secreta! - apagar de qualquer modo? " +msgstr "Esta é uma chave secreta! - de certeza que deseja apagar? (s/N) " -#, fuzzy, c-format +#, c-format msgid "deleting secret %s failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao apagar %s secreta: %s\n" msgid "key" -msgstr "key" +msgstr "chave" -#, fuzzy -#| msgid "Pubkey: " msgid "subkey" -msgstr "Chave pública: " +msgstr "subchave" #, c-format msgid "update failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "falha ao atualizar: %s\n" #, c-format msgid "deleting keyblock failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao excluir o keyblock: %s\n" #, c-format msgid "ownertrust information cleared\n" -msgstr "informações de 'ownertrust' limpas\n" +msgstr "informação de ownertrust limpa\n" #, c-format msgid "there is a secret key for public key \"%s\"!\n" @@ -1846,84 +1800,78 @@ msgstr "há uma chave secreta para a chave pública \"%s\"!\n" #, c-format msgid "use option \"--delete-secret-keys\" to delete it first.\n" -msgstr "utilize a opção \"--delete-secret-keys\" para a apagar primeiro.\n" +msgstr "usar a opção \"--delete-secret-keys\" para apagá-la primeiro.\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n" msgstr "" -"ao forçar a cifra simétrica %s (%d) viola as preferências do destinatário\n" +"AVISO: forçar a cifra simétrica %s (%d) viola as preferências do " +"destinatário\n" -#, fuzzy, c-format +#, c-format msgid "cipher algorithm '%s' may not be used for encryption\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "o algoritmo de cifra '%s' não pode ser usado para a cifração\n" #, c-format msgid "(use option \"%s\" to override)\n" -msgstr "" +msgstr "(use a opção \"%s\" sobrepor)\n" -#, fuzzy, c-format +#, c-format msgid "cipher algorithm '%s' may not be used in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "o algoritmo de cifra '%s' não pode ser usado no modo %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: key %s is not suitable for encryption in %s mode\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "AVISO: a chave %s não é adequada para a cifração no modo %s\n" #, c-format msgid "error creating passphrase: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar frase-secreta: %s\n" -#, fuzzy, c-format -#| msgid "can't use a symmetric ESK packet due to the S2K mode\n" +#, c-format msgid "can't use a SKESK packet due to the S2K mode\n" -msgstr "não é possível utilizar o pacote ESK simétrico devido ao modo S2K\n" +msgstr "não é possível usar um pacote SKESK devido ao modo S2K\n" -#, fuzzy, c-format +#, c-format msgid "using cipher %s.%s\n" -msgstr "assinatura falhou: %s\n" +msgstr "usando a cifra %s.%s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "%s' já comprimido\n" - -#, fuzzy, c-format -#| msgid "WARNING: `%s' is an empty file\n" +#, c-format msgid "WARNING: '%s' is an empty file\n" -msgstr "AVISO: `%s' é um ficheiro vazio\n" +msgstr "AVISO: '%s' é um ficheiro vazio\n" -#, fuzzy, c-format +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' já compresso\n" + +#, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "o algoritmo de digest '%s' não pode ser usado no modo %s\n" -#, fuzzy, c-format -#| msgid "reading from `%s'\n" +#, c-format msgid "reading from '%s'\n" -msgstr "lendo de `%s'\n" +msgstr "lendo de '%s'\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: forcing compression algorithm %s (%d) violates recipient " "preferences\n" msgstr "" -"ao forçar o algoritmo de compressão %s (%d) viola as preferências do " +"AVISO: forçar o algoritmo de compressão %s (%d) viola as preferências do " "destinatário\n" -#, fuzzy, c-format -#| msgid "%s/%s encrypted for: \"%s\"\n" +#, c-format msgid "%s/%s.%s encrypted for: \"%s\"\n" -msgstr "%s/%s cifrado para: \"%s\"\n" +msgstr "%s/%s.%s cifrado para: \"%s\"\n" -#, fuzzy, c-format -#| msgid "you may not use %s while in %s mode\n" +#, c-format msgid "option '%s' may not be used in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "a opção '%s' não pode ser usada no modo %s\n" -#, fuzzy, c-format -#| msgid "%s encrypted data\n" +#, c-format msgid "%s encrypted data\n" -msgstr "dados cifrados com %s\n" +msgstr "%s dados cifrados\n" #, c-format msgid "encrypted with unknown algorithm %d\n" @@ -1933,142 +1881,126 @@ msgstr "cifrado com algoritmo desconhecido %d\n" msgid "" "WARNING: message was encrypted with a weak key in the symmetric cipher.\n" msgstr "" -"AVISO: A mensagem foi cifrada com uma chave fraca na cifragem simétrica.\n" +"AVISO: A mensagem foi cifrada com uma chave fraca na cifra simétrica.\n" #, c-format msgid "problem handling encrypted packet\n" -msgstr "problema ao tratar pacote cifrado\n" +msgstr "problema ao lidar com pacote cifrado\n" -#, fuzzy msgid "export signatures that are marked as local-only" -msgstr "" -"\n" -"A assinatura será marcada como não-revocável.\n" +msgstr "exportar assinaturas marcadas como local-only" msgid "export attribute user IDs (generally photo IDs)" -msgstr "" +msgstr "exportar IDs de utilizador de atributo (geralmente IDs fotográficas)" msgid "export revocation keys marked as \"sensitive\"" -msgstr "" +msgstr "exportar chaves de revogação marcadas como \"sensitivo\"" -#, fuzzy msgid "remove unusable parts from key during export" -msgstr "chave secreta não utilizável" +msgstr "remover partes inutilizáveis da chave durante a exportação" msgid "remove as much as possible from key during export" -msgstr "" +msgstr "remover o máximo possível da chave durante a exportação" -#, fuzzy -#| msgid "generate a revocation certificate" msgid "export only revocation certificates" -msgstr "gerar um certificado de revogação" +msgstr "exportar apenas certificados de revogação" msgid "use the GnuPG key backup format" -msgstr "" +msgstr "usar o formato de backup de chave GnuPG" -#, fuzzy msgid "export secret keys using the GnuPG format" -msgstr "a escrever chave privada para `%s'\n" +msgstr "exportar chaves secretas usando o formato GnuPG" -#, fuzzy -#| msgid "%s: skipped: %s\n" msgid " - skipped" -msgstr "%s: ignorado: %s\n" +msgstr " - ignorada" -#, fuzzy, c-format -#| msgid "writing to `%s'\n" +#, c-format msgid "writing to '%s'\n" -msgstr "a escrever para `%s'\n" +msgstr "escrevendo em '%s'\n" -#, fuzzy, c-format +#, c-format msgid "key %s: key material on-card - skipped\n" -msgstr "chave %08lX: assintura da subchave no local errado - ignorado\n" +msgstr "chave %s: material da chave no cartão - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "exporting secret keys not allowed\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "exportação de chaves secretas não permitida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: PGP 2.x style key - skipped\n" -msgstr "chave %08lX: tipo PGP 2.x - ignorada\n" +msgstr "chave %s: chave tipo PGP 2.x - ignorada\n" #, c-format msgid "WARNING: nothing exported\n" msgstr "AVISO: nada exportado\n" -#, fuzzy msgid "[User ID not found]" -msgstr "[Utilizador não encontrado]" +msgstr "[ID de utilizador não encontrada]" -#, fuzzy, c-format +#, c-format msgid "automatically retrieved '%s' via %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "'%s' obtido automaticamente via %s\n" -#, fuzzy, c-format +#, c-format msgid "error retrieving '%s' via %s: %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "erro ao obter '%s' via %s: %s\n" -#, fuzzy msgid "No fingerprint" -msgstr "mostra impressão digital" +msgstr "Sem impressão digital" #, c-format msgid "checking for a fresh copy of an expired key via %s\n" -msgstr "" +msgstr "verificando se há uma nova cópia de uma chave expirada via %s\n" -#, fuzzy, c-format +#, c-format msgid "secret key \"%s\" not found: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave secreta \"%s\" não encontrada: %s\n" -#, fuzzy, c-format +#, c-format msgid "(check argument of option '%s')\n" -msgstr "opções de importação inválidas\n" +msgstr "(verifica argumento da opção '%s')\n" -#, fuzzy, c-format -#| msgid "|NAME|use NAME as default secret key" +#, c-format msgid "Warning: not using '%s' as default key: %s\n" -msgstr "|NOME|usar NOME como chave secreta por omissão" +msgstr "Aviso: a não usar '%s' como chave pré-definida: %s\n" -#, fuzzy, c-format -#| msgid "|NAME|use NAME as default secret key" +#, c-format msgid "using \"%s\" as default secret key for signing\n" -msgstr "|NOME|usar NOME como chave secreta por omissão" +msgstr "a usar \"%s\" como chave secreta pré-definida para assinatura\n" #, c-format msgid "all values passed to '%s' ignored\n" -msgstr "" +msgstr "todos os valores passados para '%s' ignorados\n" -#, fuzzy, c-format +#, c-format msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n" -msgstr "Chave inválida %08lX tornada válida por --allow-non-selfsigned-uid\n" +msgstr "Chave inválida %s tornada válida por --allow-non-selfsigned-uid\n" -#, fuzzy, c-format +#, c-format msgid "using subkey %s instead of primary key %s\n" -msgstr "usando chave secundária %08lX ao invés de chave primária %08lX\n" +msgstr "usando a subchave %s em vez da chave principal %s\n" -#, fuzzy, c-format +#, c-format msgid "valid values for option '%s':\n" -msgstr "opções de importação inválidas\n" +msgstr "valores válidos para a opção '%s':\n" -#, fuzzy msgid "make a signature" -msgstr "fazer uma assinatura separada" +msgstr "fazer uma assinatura" -#, fuzzy msgid "make a clear text signature" -msgstr "|[ficheiro]|fazer uma assinatura em texto puro" +msgstr "fazer uma assinatura de texto claro" msgid "make a detached signature" -msgstr "fazer uma assinatura separada" +msgstr "fazer uma assinatura desanexada" msgid "encrypt data" msgstr "cifrar dados" msgid "encryption only with symmetric cipher" -msgstr "cifrar apenas com cifra simétrica" +msgstr "cifração apenas com a cifra simétrica" msgid "decrypt data (default)" -msgstr "decifrar dados (acção por omissão)" +msgstr "decifrar dados (ação pré-definida)" msgid "verify a signature" msgstr "verificar uma assinatura" @@ -2079,9 +2011,8 @@ msgstr "listar as chaves" msgid "list keys and signatures" msgstr "listar as chaves e as assinaturas" -#, fuzzy msgid "list and check key signatures" -msgstr "verificar as assinaturas das chaves" +msgstr "listar e verificar assinaturas de chave" msgid "list keys and fingerprints" msgstr "listar as chaves e as impressões digitais" @@ -2092,28 +2023,20 @@ msgstr "listar as chaves secretas" msgid "generate a new key pair" msgstr "gerar um novo par de chaves" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly generate a new key pair" -msgstr "gerar um novo par de chaves" +msgstr "gerar rapidamente um novo par de chaves" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly add a new user-id" -msgstr "gerar um novo par de chaves" +msgstr "adicionar rapidamente um novo user-id" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly revoke a user-id" -msgstr "gerar um novo par de chaves" +msgstr "revogar rapidamente um user-id" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly set a new expiration date" -msgstr "gerar um novo par de chaves" +msgstr "definir rapidamente uma nova data de expiração" msgid "full featured key pair generation" -msgstr "" +msgstr "geração completa de pares de chaves" msgid "generate a revocation certificate" msgstr "gerar um certificado de revogação" @@ -2124,20 +2047,14 @@ msgstr "remover chaves do porta-chaves público" msgid "remove keys from the secret keyring" msgstr "remover chaves do porta-chaves secreto" -#, fuzzy -#| msgid "sign a key" msgid "quickly sign a key" -msgstr "assinar uma chave" +msgstr "assinar rapidamente uma chave" -#, fuzzy -#| msgid "sign a key locally" msgid "quickly sign a key locally" -msgstr "assinar uma chave localmente" +msgstr "assinar rapidamente uma chave localmente" -#, fuzzy -#| msgid "generate a new key pair" msgid "quickly revoke a key signature" -msgstr "gerar um novo par de chaves" +msgstr "revogar rapidamente uma assinatura de chave" msgid "sign a key" msgstr "assinar uma chave" @@ -2148,9 +2065,8 @@ msgstr "assinar uma chave localmente" msgid "sign or edit a key" msgstr "assinar ou editar uma chave" -#, fuzzy msgid "change a passphrase" -msgstr "muda a frase secreta" +msgstr "alterar uma frase-secreta" msgid "export keys" msgstr "exportar chaves" @@ -2162,118 +2078,104 @@ msgid "import keys from a keyserver" msgstr "importar chaves de um servidor de chaves" msgid "search for keys on a keyserver" -msgstr "procurar chaves num servidor de chaves" +msgstr "pesquisar chaves num servidor de chaves" msgid "update all keys from a keyserver" -msgstr "actualizar todas as chaves a partir de um servidor de chaves" +msgstr "atualizar todas as chaves de um servidor de chaves" msgid "import/merge keys" msgstr "importar/fundir chaves" msgid "print the card status" -msgstr "" +msgstr "mostrar o status do cartão" msgid "change data on a card" -msgstr "" +msgstr "alterar dados de um cartão" msgid "change a card's PIN" -msgstr "" +msgstr "alterar o PIN de um cartão" msgid "update the trust database" -msgstr "actualizar a base de dados de confiança" +msgstr "atualizar a base de dados da confiança" -#, fuzzy msgid "print message digests" -msgstr "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr "mostrar digests de mensagens" msgid "run in server mode" -msgstr "" +msgstr "executar no modo de servidor" msgid "|VALUE|set the TOFU policy for a key" -msgstr "" +msgstr "|VALUE|definir a política de TOFU para uma chave" msgid "|NAME|use NAME as default secret key" -msgstr "|NOME|usar NOME como chave secreta por omissão" +msgstr "|NAME|usar NAME como chave secreta pré-definida" -#, fuzzy msgid "|NAME|encrypt to user ID NAME as well" -msgstr "|NOME|cifrar para NOME" +msgstr "|NAME|cifrar também para ID de utilizador NAME" msgid "|SPEC|set up email aliases" -msgstr "" +msgstr "|SPEC|configurar aliases de email" msgid "use strict OpenPGP behavior" -msgstr "" +msgstr "usar estritamente comportamento OpenPGP" msgid "do not make any changes" -msgstr "não fazer alterações" +msgstr "não fazer quaisquer alterações" msgid "prompt before overwriting" -msgstr "perguntar antes de sobrepôr" +msgstr "perguntar antes de sobrescrever" msgid "Options controlling the input" -msgstr "" +msgstr "Opções que controlam a entrada" msgid "Options controlling the output" -msgstr "" +msgstr "Opções que controlam a saída" msgid "create ascii armored output" -msgstr "criar saída com armadura ascii" +msgstr "criar saída blindada ASCII" -#, fuzzy msgid "|FILE|write output to FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|escrever saída em FILE" msgid "use canonical text mode" -msgstr "usar modo de texto canônico" +msgstr "usar modo de texto canónico" -#, fuzzy msgid "|N|set compress level to N (0 disables)" -msgstr "" -"|N|estabelecer nível de compressão N\n" -"(0 desactiva)" +msgstr "|N|definir nível de compressão para N (0 desabilita)" msgid "Options controlling key import and export" -msgstr "" +msgstr "Opções que controlam a importação e exportação de chaves" msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address" msgstr "" +"|MECHANISMS|usar MECHANISMS para localizar chaves por endereço de email" -#, fuzzy -#| msgid "import keys from a keyserver" msgid "import missing key from a signature" -msgstr "importar chaves de um servidor de chaves" +msgstr "importar chave ausente a partir de uma assinatura" -#, fuzzy msgid "include the public key in signatures" -msgstr "verificar as assinaturas das chaves" +msgstr "incluir a chave pública nas assinaturas" msgid "disable all access to the dirmngr" -msgstr "" +msgstr "desabilitar todo o acesso ao dirmngr" msgid "Options controlling key listings" -msgstr "" +msgstr "Opções que controlam as listagens de chaves" -#, fuzzy -#| msgid "list secret keys" msgid "Options to specify keys" -msgstr "listar as chaves secretas" +msgstr "Opções para especificar chaves" -#, fuzzy msgid "|USER-ID|encrypt for USER-ID" -msgstr "|NOME|cifrar para NOME" +msgstr "|USER-ID|cifrar para USER-ID" -#, fuzzy msgid "|USER-ID|use USER-ID to sign or decrypt" -msgstr "" -"usar este identificador de utilizador para\n" -"assinar ou decifrar" +msgstr "|USER-ID|usar USER-ID para assinar ou decifrar" msgid "Options for unattended use" -msgstr "" +msgstr "Opções para uso autónomo" msgid "Other options" -msgstr "" +msgstr "Outras opções" msgid "" "@\n" @@ -2282,16 +2184,6 @@ msgstr "" "@\n" "(Veja a página man para uma lista completa de comandos e opções)\n" -#, fuzzy -#| msgid "" -#| "@\n" -#| "Examples:\n" -#| "\n" -#| " -se -r Bob [file] sign and encrypt for user Bob\n" -#| " --clear-sign [file] make a clear text signature\n" -#| " --detach-sign [file] make a detached signature\n" -#| " --list-keys [names] show keys\n" -#| " --fingerprint [names] show fingerprints\n" msgid "" "@\n" "Examples:\n" @@ -2306,29 +2198,22 @@ msgstr "" "Exemplos:\n" "\n" " -se -r Bob [ficheiro] assinar e cifrar para o utilizador Bob\n" -" --clear-sign [ficheiro] criar uma assinatura em texto puro\n" -" --detach-sign [ficheiro] criar uma assinatura separada\n" +" --clear-sign [ficheiro] fazer uma assinatura de texto claro\n" +" --detach-sign [ficheiro] fazer uma assinatura desanexada\n" " --list-keys [nomes] mostrar chaves\n" " --fingerprint [nomes] mostrar impressões digitais\n" -#, fuzzy -#| msgid "Usage: gpg [options] [files] (-h for help)" msgid "Usage: @GPG@ [options] [files] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPG@ [opções] [ficheiros] (-h para ajuda)" -#, fuzzy -#| msgid "" -#| "Syntax: gpg [options] [files]\n" -#| "sign, check, encrypt or decrypt\n" -#| "default operation depends on the input data\n" msgid "" "Syntax: @GPG@ [options] [files]\n" "Sign, check, encrypt or decrypt\n" "Default operation depends on the input data\n" msgstr "" -"Sintaxe: gpg [opções] [ficheiros]\n" -"assina, verifica, cifra ou decifra\n" -"a operação por omissão depende dos dados de entrada\n" +"Sintaxe: @GPG@ [opções] [ficheiros]\n" +"Assinar, verificar, cifrar, ou decifrar\n" +"A operação pré-definida depende dos dados de entrada\n" msgid "" "\n" @@ -2344,175 +2229,175 @@ msgid "Cipher: " msgstr "Cifra: " msgid "Hash: " -msgstr "Dispersão: " +msgstr "Hash: " msgid "Compression: " msgstr "Compressão: " -#, fuzzy, c-format +#, c-format msgid "usage: %s [options] %s\n" -msgstr "uso: gpg [opções] " +msgstr "uso: %s [opções] %s\n" #, c-format msgid "conflicting commands\n" msgstr "comandos em conflito\n" -#, fuzzy, c-format +#, c-format msgid "no = sign found in group definition '%s'\n" -msgstr "nenhum sinal = encontrada na definição de grupo \"%s\"\n" +msgstr "nenhum sinal '=' encontrado na definição de grupo '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe ownership on homedir '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro na homedir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe ownership on configuration file '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro no ficheiro de configuração '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe ownership on extension '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro na extensão '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe permissions on homedir '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras na homedir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe permissions on configuration file '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras no ficheiro de configuração '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe permissions on extension '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras na extensão '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro da pasta envolvente a homedir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: unsafe enclosing directory ownership on configuration file '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "" +"AVISO: ownership inseguro da pasta envolvente ao ficheiro de configuração " +"'%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: ownership inseguro da pasta envolvente à extensão '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras da pasta envolvente a homedir '%s'\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "" +"AVISO: permissões inseguras da pasta envolvente ao ficheiro de configuração " +"'%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n" -msgstr "AVISO: permissões pouco seguras em %s \"%s\"\n" +msgstr "AVISO: permissões inseguras da pasta envolvente à extensão '%s'\n" -#, fuzzy, c-format +#, c-format msgid "unknown configuration item '%s'\n" -msgstr "criado um novo ficheiro de configuração `%s'\n" +msgstr "item de configuração '%s' desconhecido\n" msgid "display photo IDs during key listings" -msgstr "" +msgstr "exibir IDs fotográficas durante as listagens de chaves" -#, fuzzy msgid "show key usage information during key listings" -msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" +msgstr "" +"mostrar informação de utilização da chave durante as listagens de chaves" msgid "show policy URLs during signature listings" -msgstr "" +msgstr "mostrar URLs de política durante listagens de assinaturas" -#, fuzzy msgid "show all notations during signature listings" -msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" +msgstr "mostrar todas as anotações durante as listagens de assinaturas" msgid "show IETF standard notations during signature listings" -msgstr "" +msgstr "mostrar notações da norma IETF durante listagens de assinaturas" msgid "show user-supplied notations during signature listings" -msgstr "" +msgstr "mostrar anotações user-supplied durante as listagens de assinaturas" -#, fuzzy msgid "show preferred keyserver URLs during signature listings" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "" +"mostrar URLs de servidor de chaves preferenciais durante listagens de " +"assinaturas" msgid "show user ID validity during key listings" -msgstr "" +msgstr "mostrar a validade da ID de utilizador durante as listagens de chaves" msgid "show revoked and expired user IDs in key listings" -msgstr "" +msgstr "mostrar IDs de utilizador revogadas e expiradas em listagens de chaves" msgid "show revoked and expired subkeys in key listings" -msgstr "" +msgstr "mostrar subchaves revogadas e expiradas em listagens de chaves" -#, fuzzy msgid "show signatures with invalid algorithms during signature listings" -msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" +msgstr "" +"mostrar assinaturas com algoritmos inválidos durante as listagens de " +"assinaturas" -#, fuzzy msgid "show the keyring name in key listings" -msgstr "mostrar em que porta-chave a chave está" +msgstr "mostrar o nome do porta-chaves nas listagens de chaves" -#, fuzzy msgid "show expiration dates during signature listings" -msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" +msgstr "mostrar datas de expiração durante as listagens de assinaturas" -#, fuzzy -#| msgid "set preference list" msgid "show preferences" -msgstr "configurar lista de preferências" +msgstr "mostrar preferências" -#, fuzzy, c-format +#, c-format msgid "unknown TOFU policy '%s'\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "política TOFU desconhecida '%s'\n" #, c-format msgid "(use \"help\" to list choices)\n" -msgstr "" +msgstr "(usar \"help\" para listar opções)\n" #, c-format msgid "This command is not allowed while in %s mode.\n" msgstr "Este comando não é permitido no modo %s.\n" -#, fuzzy, c-format -#| msgid "NOTE: %s is not for normal use!\n" +#, c-format msgid "Note: %s is not for normal use!\n" -msgstr "NOTA: %s não é para uso normal!\n" +msgstr "Nota: %s não é para o uso normal!\n" -#, fuzzy, c-format +#, c-format msgid "'%s' is not a valid signature expiration\n" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "'%s' não é uma expiração de assinatura válida\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" is not a proper mail address\n" -msgstr "Endereço eletrónico inválido\n" +msgstr "\"%s\" não é um endereço de email correto\n" -#, fuzzy, c-format +#, c-format msgid "invalid pinentry mode '%s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "modo de pinentry inválido '%s'\n" -#, fuzzy, c-format +#, c-format msgid "invalid request origin '%s'\n" -msgstr "opções de importação inválidas\n" +msgstr "origem de pedido inválida '%s'\n" -#, fuzzy, c-format +#, c-format msgid "'%s' is not a valid character set\n" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "'%s' não é um set de caracteres válido\n" -#, fuzzy, c-format +#, c-format msgid "could not parse keyserver URL\n" -msgstr "não consegui processar a URI do servidor de chaves\n" +msgstr "não foi possível processar a URL do servidor de chaves\n" -#, fuzzy, c-format +#, c-format msgid "%s:%d: invalid keyserver options\n" -msgstr "%s:%d: opções de exportação inválidas\n" +msgstr "%s:%d: opções inválidas do servidor de chaves\n" -#, fuzzy, c-format +#, c-format msgid "invalid keyserver options\n" -msgstr "opções de exportação inválidas\n" +msgstr "Opções inválidas do servidor de chaves\n" #, c-format msgid "%s:%d: invalid import options\n" @@ -2522,9 +2407,9 @@ msgstr "%s:%d: opções de importação inválidas\n" msgid "invalid import options\n" msgstr "opções de importação inválidas\n" -#, fuzzy, c-format +#, c-format msgid "invalid filter option: %s\n" -msgstr "opções de importação inválidas\n" +msgstr "opção de filtro inválida: %s\n" #, c-format msgid "%s:%d: invalid export options\n" @@ -2534,72 +2419,73 @@ msgstr "%s:%d: opções de exportação inválidas\n" msgid "invalid export options\n" msgstr "opções de exportação inválidas\n" -#, fuzzy, c-format +#, c-format msgid "%s:%d: invalid list options\n" -msgstr "%s:%d: opções de importação inválidas\n" +msgstr "%s:%d: opções de listagem inválidas\n" -#, fuzzy, c-format +#, c-format msgid "invalid list options\n" -msgstr "opções de importação inválidas\n" +msgstr "opções de lista inválidas\n" msgid "display photo IDs during signature verification" -msgstr "" +msgstr "exibir IDs fotográficas durante a verificação da assinatura" msgid "show policy URLs during signature verification" -msgstr "" +msgstr "mostrar URLs de política durante a verificação da assinatura" -#, fuzzy msgid "show all notations during signature verification" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "mostrar todas as anotações durante a verificação da assinatura" msgid "show IETF standard notations during signature verification" -msgstr "" +msgstr "mostrar notações da norma IETF durante a verificação da assinatura" msgid "show user-supplied notations during signature verification" -msgstr "" +msgstr "mostrar anotações user-supplied durante a verificação da assinatura" -#, fuzzy msgid "show preferred keyserver URLs during signature verification" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "" +"mostrar URLs preferenciais do servidor de chaves durante a verificação da " +"assinatura" -#, fuzzy msgid "show user ID validity during signature verification" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "" +"mostrar a validade da ID de utilizador durante a verificação da assinatura" msgid "show revoked and expired user IDs in signature verification" msgstr "" +"mostrar IDs de utilizador revogadas e expiradas na verificação da assinatura" -#, fuzzy msgid "show only the primary user ID in signature verification" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "" +"mostrar apenas a ID de utilizador principal na verificação da assinatura" -#, fuzzy, c-format +#, c-format msgid "%s:%d: invalid verify options\n" -msgstr "%s:%d: opções de exportação inválidas\n" +msgstr "%s:%d: opções de verificação inválidas\n" -#, fuzzy, c-format +#, c-format msgid "invalid verify options\n" -msgstr "opções de exportação inválidas\n" +msgstr "opções de verificação inválidas\n" #, c-format msgid "unable to set exec-path to %s\n" -msgstr "não foi possível alterar o exec-path para %s\n" +msgstr "incapaz de definir exec-path para %s\n" -#, fuzzy, c-format +#, c-format msgid "%s:%d: invalid auto-key-locate list\n" -msgstr "%s:%d: opções de exportação inválidas\n" +msgstr "%s:%d: lista auto-key-locate inválida\n" #, c-format msgid "invalid auto-key-locate list\n" -msgstr "" +msgstr "lista auto-key-locate inválida\n" -#, fuzzy, c-format +#, c-format msgid "invalid argument for option \"%.50s\"\n" -msgstr "opções de importação inválidas\n" +msgstr "argumento inválido para a opção \"%.50s\"\n" #, c-format msgid "WARNING: program may create a core file!\n" -msgstr "AVISO: O programa pode criar um ficheiro core!\n" +msgstr "AVISO: o programa poderá criar um ficheiro core!\n" #, c-format msgid "WARNING: %s overrides %s\n" @@ -2615,23 +2501,23 @@ msgstr "%s não faz sentido com %s!\n" #, c-format msgid "WARNING: running with faked system time: " -msgstr "" +msgstr "AVISO: a correr com tempo de sistema falsificado: " -#, fuzzy, c-format +#, c-format msgid "will not run with insecure memory due to %s\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "não correrei com memória insegura devido a %s\n" #, c-format msgid "selected cipher algorithm is invalid\n" -msgstr "o algoritmo de cifragem selecionado é inválido\n" +msgstr "o algoritmo de cifra selecionado é inválido\n" -#, fuzzy, c-format +#, c-format msgid "selected compression algorithm is invalid\n" -msgstr "o algoritmo de cifragem selecionado é inválido\n" +msgstr "o algoritmo de compressão selecionado é inválido\n" #, c-format msgid "selected certification digest algorithm is invalid\n" -msgstr "o algoritmo de \"digest\" de certificação selecionado é inválido\n" +msgstr "o algoritmo selecionado de digest da certificação é inválido\n" #, c-format msgid "completes-needed must be greater than 0\n" @@ -2641,289 +2527,276 @@ msgstr "completes-needed deve ser maior que 0\n" msgid "marginals-needed must be greater than 1\n" msgstr "marginals-needed deve ser maior que 1\n" -#, fuzzy, c-format +#, c-format msgid "max-cert-depth must be in the range from 1 to 255\n" -msgstr "max-cert-depth deve estar na entre 1 e 255\n" +msgstr "max-cert-depth deve estar na faixa entre 1 a 255\n" -#, fuzzy, c-format +#, c-format msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n" -msgstr "nível de verificação por omissão inválido: deve ser 0, 1, 2 ou 3\n" +msgstr "default-cert-level inválido; deve ser 0, 1, 2, ou 3\n" -#, fuzzy, c-format +#, c-format msgid "invalid min-cert-level; must be 1, 2, or 3\n" -msgstr "nível de verificação por omissão inválido: deve ser 0, 1, 2 ou 3\n" +msgstr "min-cert-level inválido; deve ser 1, 2, ou 3\n" -#, fuzzy, c-format -#| msgid "NOTE: simple S2K mode (0) is strongly discouraged\n" +#, c-format msgid "Note: simple S2K mode (0) is strongly discouraged\n" -msgstr "NOTA: o modo S2K simples (0) não é recomendável\n" +msgstr "Nota: o modo S2K simples (0) é fortemente desencorajado\n" #, c-format msgid "invalid S2K mode; must be 0, 1 or 3\n" -msgstr "modo S2K inválido: deve ser 0, 1 ou 3\n" +msgstr "modo S2K inválido: deve ser 0, 1, ou 3\n" #, c-format msgid "invalid default preferences\n" -msgstr "preferências por omissão inválidas\n" +msgstr "preferências pré-definidas inválidas\n" #, c-format msgid "invalid personal cipher preferences\n" -msgstr "preferências pessoais de cifra inválidas\n" +msgstr "preferências pessoais da cifra inválidas\n" #, c-format msgid "invalid personal digest preferences\n" -msgstr "preferências pessoais de 'digest' inválidas\n" +msgstr "preferências pessoais de digest inválidas\n" #, c-format msgid "invalid personal compress preferences\n" -msgstr "preferências pessoais de compressão inválidas\n" +msgstr "preferências pessoais da compressão inválidas\n" -#, fuzzy, c-format -#| msgid "keysize invalid; using %u bits\n" +#, c-format msgid "chunk size invalid - using %d\n" -msgstr "tamanho de chave inválido; a utilizar %u bits\n" +msgstr "tamanho do chunk inválido - usando %d\n" -#, fuzzy, c-format +#, c-format msgid "%s does not yet work with %s\n" -msgstr "%s não faz sentido com %s!\n" +msgstr "%s ainda não funciona com %s\n" -#, fuzzy, c-format +#, c-format msgid "compression algorithm '%s' may not be used in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "o algoritmo de compressão '%s' não pode ser usado no modo %s\n" #, c-format msgid "failed to initialize the TrustDB: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao inicializar a TrustDB: %s\n" #, c-format msgid "WARNING: recipients (-r) given without using public key encryption\n" msgstr "" -"AVISO: destinatários (-r) dados sem utilizar uma cifra de chave pública\n" +"AVISO: destinatários (-r) fornecidos sem usar cifração de chave pública\n" -#, fuzzy, c-format +#, c-format msgid "symmetric encryption of '%s' failed: %s\n" -msgstr "decifragem falhou: %s\n" +msgstr "falha na cifração simétrica de '%s': %s\n" #, c-format msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n" -msgstr "" +msgstr "você não pode usar --symmetric --encrypt com --s2k-mode 0\n" -#, fuzzy, c-format +#, c-format msgid "you cannot use --symmetric --encrypt in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "você não pode usar --symmetric --encrypt no modo %s\n" #, c-format msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n" -msgstr "" +msgstr "você não pode usar --symmetric --sign --encrypt com --s2k-mode 0\n" -#, fuzzy, c-format +#, c-format msgid "you cannot use --symmetric --sign --encrypt in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "você não pode usar --symmetric --sign --encrypt no modo %s\n" -#, fuzzy, c-format +#, c-format msgid "keyserver send failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou o envio ao servidor de chaves: %s\n" -#, fuzzy, c-format +#, c-format msgid "keyserver receive failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou o receber do servidor de chaves: %s\n" -#, fuzzy, c-format +#, c-format msgid "key export failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou a exportação de chaves: %s\n" -#, fuzzy, c-format +#, c-format msgid "export as ssh key failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou a exportação como chave ssh: %s\n" -#, fuzzy, c-format +#, c-format msgid "keyserver search failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "falhou a pesquisa no servidor de chaves: %s\n" -#, fuzzy, c-format +#, c-format msgid "keyserver refresh failed: %s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "falhou a atualização do servidor de chaves: %s\n" #, c-format msgid "dearmoring failed: %s\n" -msgstr "retirada de armadura falhou: %s\n" +msgstr "falhou ao desblindar: %s\n" #, c-format msgid "enarmoring failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falhou ao blindar: %s\n" -#, fuzzy, c-format -#| msgid "invalid hash algorithm `%s'\n" +#, c-format msgid "invalid hash algorithm '%s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash inválido '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error parsing key specification '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao processar a especificação de chave '%s': %s\n" #, c-format msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n" msgstr "" +"'%s' não parece ser uma ID de chave, impressão digital, ou keygrip, válidas\n" #, c-format msgid "WARNING: no command supplied. Trying to guess what you mean ...\n" msgstr "" +"AVISO: nenhum comando fornecido. A tentar adivinhar o que você quer " +"dizer...\n" #, c-format msgid "Go ahead and type your message ...\n" -msgstr "Digite a sua mensagem ...\n" +msgstr "Esteja à vontade para digitar a sua mensagem ...\n" #, c-format msgid "the given certification policy URL is invalid\n" -msgstr "a URL de política de certificação dada é inválida\n" +msgstr "a URL da política de certificação fornecida é inválida\n" #, c-format msgid "the given signature policy URL is invalid\n" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "a URL de política de assinatura fornecida é inválida\n" -#, fuzzy, c-format +#, c-format msgid "the given preferred keyserver URL is invalid\n" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "a URL fornecida do servidor de chaves preferencial é inválida\n" -#, fuzzy msgid "|FILE|take the keys from the keyring FILE" -msgstr "Remover esta chave do porta-chaves?" +msgstr "|FILE|tome as chaves do porta-chaves FILE" -#, fuzzy msgid "make timestamp conflicts only a warning" -msgstr "conflito de \"timestamp\"" +msgstr "tornar os conflitos de timestamp apenas um aviso" msgid "|FD|write status info to this FD" -msgstr "" -"|DF|escrever informações de estado para o\n" -"descritor de ficheiro DF" +msgstr "|FD|escrever informações de status para este FD" msgid "|ALGO|reject signatures made with ALGO" -msgstr "" +msgstr "|ALGO|rejeitar assinaturas feitas com ALGO" -#, fuzzy msgid "Usage: gpgv [options] [files] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: gpgv [opções] [ficheiros] (-h para ajuda)" msgid "" "Syntax: gpgv [options] [files]\n" "Check signatures against known trusted keys\n" msgstr "" +"Sintaxe: gpgv [opções] [ficheiros]\n" +"Verificar assinaturas em relação a chaves confiáveis conhecidas\n" msgid "No help available" msgstr "Nenhuma ajuda disponível" -#, fuzzy, c-format -#| msgid "No help available for `%s'" +#, c-format msgid "No help available for '%s'" -msgstr "Nenhuma ajuda disponível para `%s'" +msgstr "Nenhuma ajuda disponível para '%s'" msgid "import signatures that are marked as local-only" -msgstr "" +msgstr "importar assinaturas marcadas como local-only" msgid "repair damage from the pks keyserver during import" -msgstr "" +msgstr "reparar os danos do servidor de chaves pks durante a importação" -#, fuzzy msgid "do not clear the ownertrust values during import" -msgstr "actualizar a base de dados de confiança" +msgstr "não limpar os valores de ownertrust durante a importação" -#, fuzzy msgid "do not update the trustdb after import" -msgstr "actualizar a base de dados de confiança" +msgstr "não atualizar a trustdb após a importação" -#, fuzzy -#| msgid "not supported" msgid "enable bulk import mode" -msgstr "não suportado" +msgstr "habilitar o modo de importação em massa" -#, fuzzy msgid "show key during import" -msgstr "mostra impressão digital" +msgstr "mostrar chave durante a importação" -#, fuzzy msgid "show key but do not actually import" -msgstr "mostra impressão digital" +msgstr "mostrar chave, mas não chegar a importar" msgid "only accept updates to existing keys" -msgstr "" +msgstr "aceitar apenas atualizações para chaves existentes" -#, fuzzy msgid "remove unusable parts from key after import" -msgstr "chave secreta não utilizável" +msgstr "remover partes inutilizáveis da chave após a importação" msgid "remove as much as possible from key after import" -msgstr "" +msgstr "remover da chave o máximo possível após a importação" msgid "ignore key-signatures which are not self-signatures" -msgstr "" +msgstr "ignorar assinaturas de chave que não são auto-assinaturas" msgid "run import filters and export key immediately" -msgstr "" +msgstr "executar filtros de importação e exportar chave imediatamente" msgid "assume the GnuPG key backup format" -msgstr "" +msgstr "assumir o formato de backup de chave GnuPG" -#, fuzzy msgid "repair keys on import" -msgstr "mostra impressão digital" +msgstr "reparar chaves ao importar" #, c-format msgid "skipping block of type %d\n" msgstr "ignorando bloco do tipo %d\n" -#, fuzzy, c-format +#, c-format msgid "%lu keys processed so far\n" msgstr "%lu chaves processadas até agora\n" #, c-format msgid "Total number processed: %lu\n" -msgstr "Número total processado: %lu\n" +msgstr " Número total processado: %lu\n" -#, fuzzy, c-format -#| msgid " skipped new keys: %lu\n" +#, c-format msgid " skipped PGP-2 keys: %lu\n" -msgstr " ignorei novas chaves: %lu\n" +msgstr " chaves PGP-2 ignoradas: %lu\n" #, c-format msgid " skipped new keys: %lu\n" -msgstr " ignorei novas chaves: %lu\n" +msgstr " novas chaves ignoradas: %lu\n" #, c-format msgid " w/o user IDs: %lu\n" -msgstr " sem IDs de utilizadores: %lu\n" +msgstr " sem IDs de utilizadores: %lu\n" #, c-format msgid " imported: %lu" -msgstr " importados: %lu" +msgstr " importadas: %lu" #, c-format msgid " unchanged: %lu\n" -msgstr " não modificados: %lu\n" +msgstr " não modificadas: %lu\n" #, c-format msgid " new user IDs: %lu\n" -msgstr " novos IDs de utilizadores: %lu\n" +msgstr " novas IDs de utilizadores: %lu\n" #, c-format msgid " new subkeys: %lu\n" -msgstr " novas subchaves: %lu\n" +msgstr " novas subchaves: %lu\n" #, c-format msgid " new signatures: %lu\n" -msgstr " novas assinaturas: %lu\n" +msgstr " novas assinaturas: %lu\n" #, c-format msgid " new key revocations: %lu\n" -msgstr " novas revogações de chaves: %lu\n" +msgstr " novas revogações de chaves: %lu\n" #, c-format msgid " secret keys read: %lu\n" -msgstr " chaves secretas lidas: %lu\n" +msgstr " chaves secretas lidas: %lu\n" #, c-format msgid " secret keys imported: %lu\n" -msgstr " chaves secretas importadas: %lu\n" +msgstr " chaves secretas importadas: %lu\n" #, c-format msgid " secret keys unchanged: %lu\n" @@ -2931,162 +2804,165 @@ msgstr " chaves secretas não modificadas: %lu\n" #, c-format msgid " not imported: %lu\n" -msgstr " não importadas: %lu\n" +msgstr " não importadas: %lu\n" -#, fuzzy, c-format +#, c-format msgid " signatures cleaned: %lu\n" -msgstr " novas assinaturas: %lu\n" +msgstr " assinaturas limpas: %lu\n" -#, fuzzy, c-format +#, c-format msgid " user IDs cleaned: %lu\n" -msgstr " chaves secretas lidas: %lu\n" +msgstr " IDs de utilizador limpas: %lu\n" #, c-format msgid "" "WARNING: key %s contains preferences for unavailable\n" "algorithms on these user IDs:\n" msgstr "" +"AVISO: a chave %s contém preferências para algoritmos\n" +"indisponíveis nestas IDs de utilizador:\n" #, c-format msgid " \"%s\": preference for cipher algorithm %s\n" -msgstr "" +msgstr " \"%s\": preferência para algoritmo da cifra %s\n" -#, fuzzy, c-format +#, c-format msgid " \"%s\": preference for AEAD algorithm %s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr " \"%s\": preferência para algoritmo AEAD %s\n" -#, fuzzy, c-format +#, c-format msgid " \"%s\": preference for digest algorithm %s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr " \"%s\": preferência para algoritmo digest %s\n" #, c-format msgid " \"%s\": preference for compression algorithm %s\n" -msgstr "" +msgstr " \"%s\": preferência para algoritmo de compressão %s\n" #, c-format msgid "it is strongly suggested that you update your preferences and\n" -msgstr "" +msgstr "é altamente recomendável que você atualize suas preferências e\n" #, c-format msgid "re-distribute this key to avoid potential algorithm mismatch problems\n" msgstr "" +"redistribua esta chave para evitar possíveis problemas de incompatibilidade " +"de algoritmos\n" #, c-format msgid "you can update your preferences with: gpg --edit-key %s updpref save\n" msgstr "" +"você pode atualizar suas preferências com: gpg --edit-key %s updpref save\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no user ID\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "chave %s: sem ID de utilizador\n" -#, fuzzy, c-format +#, c-format msgid "key %s: %s\n" -msgstr "ignorado `%s': %s\n" +msgstr "chave %s: %s\n" msgid "rejected by import screener" -msgstr "" +msgstr "rejeitado pelo rastreador de importação" -#, fuzzy, c-format +#, c-format msgid "key %s: PKS subkey corruption repaired\n" -msgstr "chave %08lX: subchave HKP corrompida foi reparada\n" +msgstr "chave %s: corrupção de subchave PKS reparada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: accepted non self-signed user ID \"%s\"\n" -msgstr "chave %08lX: aceite ID de utilizador sem auto-assinatura '%s'\n" +msgstr "chave %s: foi aceite ID de utilizador não auto-assinada \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no valid user IDs\n" -msgstr "chave %08lX: sem IDs de utilizadores válidos\n" +msgstr "chave %s: sem IDs de utilizador válidas\n" #, c-format msgid "this may be caused by a missing self-signature\n" -msgstr "isto pode ser causado por falta de auto-assinatura\n" +msgstr "isto pode ser causado pela ausência de auto-assinatura\n" -#, fuzzy, c-format +#, c-format msgid "key %s: public key not found: %s\n" -msgstr "chave %08lX: chave pública não encontrada: %s\n" +msgstr "chave %s: chave pública não encontrada: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s: new key - skipped\n" -msgstr "chave %08lX: chave nova - ignorada\n" +msgstr "chave %s: nova chave - ignorada\n" #, c-format msgid "no writable keyring found: %s\n" -msgstr "não foi encontrada nenhum porta-chaves onde escrever: %s\n" +msgstr "nenhum porta-chaves com permissão de escrita encontrado: %s\n" -#, fuzzy, c-format -#| msgid "error writing keyring `%s': %s\n" +#, c-format msgid "error writing keyring '%s': %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao escrever porta-chaves '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s: public key \"%s\" imported\n" -msgstr "chave %08lX: chave pública \"%s\" importada\n" +msgstr "chave %s: chave pública \"%s\" importada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: doesn't match our copy\n" -msgstr "chave %08lX: não corresponde à nossa cópia\n" +msgstr "chave %s: não corresponde à nossa cópia\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" 1 new user ID\n" -msgstr "chave %8lX: \"%s\" 1 novo ID de utilizador\n" +msgstr "chave %s: \"%s\" 1 nova ID de utilizador\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d new user IDs\n" -msgstr "chave %08lX: \"%s\" %d novos IDs de utilizadores\n" +msgstr "chave %s: \"%s\" %d novas IDs de utilizador\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" 1 new signature\n" -msgstr "chave %08lX: \"%s\" 1 nova assinatura\n" +msgstr "chave %s: \"%s\" 1 nova assinatura\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d new signatures\n" -msgstr "chave %08lX: \"%s\" %d novas assinaturas\n" +msgstr "chave %s: \"%s\" %d novas assinaturas\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" 1 new subkey\n" -msgstr "chave %08lX: \"%s\" 1 nova subchave\n" +msgstr "chave %s: \"%s\" 1 nova subchave\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d new subkeys\n" -msgstr "chave %08lX: \"%s\" %d novas subchaves\n" +msgstr "chave %s: \"%s\" %d novas subchaves\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d signature cleaned\n" -msgstr "chave %08lX: \"%s\" %d novas assinaturas\n" +msgstr "chave %s: \"%s\" %d assinatura limpa\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d signatures cleaned\n" -msgstr "chave %08lX: \"%s\" %d novas assinaturas\n" +msgstr "chave %s: \"%s\" %d assinaturas limpas\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d user ID cleaned\n" -msgstr "chave %08lX: \"%s\" %d novos IDs de utilizadores\n" +msgstr "chave %s: \"%s\" %d ID de utilizador limpa\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" %d user IDs cleaned\n" -msgstr "chave %08lX: \"%s\" %d novos IDs de utilizadores\n" +msgstr "chave %s: \"%s\" %d IDs de utilizador limpas\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" not changed\n" -msgstr "chave %08lX: \"%s\" não modificada\n" +msgstr "chave %s: \"%s\" não alterada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: secret key imported\n" -msgstr "chave %08lX: chave secreta importada\n" +msgstr "chave %s: chave secreta importada\n" -#, fuzzy, c-format -#| msgid "skipped: secret key already present\n" +#, c-format msgid "key %s: secret key already exists\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "chave %s: chave secreta já existe\n" -#, fuzzy, c-format +#, c-format msgid "key %s: error sending to agent: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "chave %s: erro ao enviar para o agent: %s\n" #, c-format msgid "key %s: card reference is overridden by key material\n" -msgstr "" +msgstr "chave %s: a referência do cartão é sobreposta pelo material da chave\n" #. TRANSLATORS: For a smartcard, each private key on host has a #. * reference (stub) to a smartcard and actual private key data @@ -3098,25 +2974,25 @@ msgstr "" #. * again. #, c-format msgid "To migrate '%s', with each smartcard, run: %s\n" -msgstr "" +msgstr "Para migrar '%s', com cada smartcard, execute: %s\n" -#, fuzzy, c-format +#, c-format msgid "secret key %s: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave secreta %s: %s\n" -#, fuzzy, c-format +#, c-format msgid "importing secret keys not allowed\n" -msgstr "a escrever chave privada para `%s'\n" +msgstr "importação de chaves secretas não permitida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: secret key with invalid cipher %d - skipped\n" -msgstr "chave %08lX: chave secreta com cifra inválida %d - ignorada\n" +msgstr "chave %s: chave secreta com a cifra %d inválida - ignorada\n" msgid "No reason specified" msgstr "Nenhum motivo especificado" msgid "Key is superseded" -msgstr "A chave foi substituída" +msgstr "A chave foi suplantada" msgid "Key has been compromised" msgstr "A chave foi comprometida" @@ -3125,217 +3001,218 @@ msgid "Key is no longer used" msgstr "A chave já não é utilizada" msgid "User ID is no longer valid" -msgstr "O identificador do utilizador já não é válido" +msgstr "A ID de utilizador já não é válida" #, c-format msgid "reason for revocation: " -msgstr "motivo da revocação: " +msgstr "motivo da revogação: " #, c-format msgid "revocation comment: " -msgstr "comentário da revocação: " +msgstr "comentário da revogação: " -#, fuzzy, c-format +#, c-format msgid "key %s: no public key - can't apply revocation certificate\n" msgstr "" -"chave %08lX: sem chave pública - impossível aplicar certificado\n" -"de revogação\n" +"chave %s: nenhuma chave pública - não é possível aplicar certificado de " +"revogação\n" -#, fuzzy, c-format +#, c-format msgid "key %s: can't locate original keyblock: %s\n" -msgstr "chave %08lX: impossível localizar bloco de chaves original: %s\n" +msgstr "chave %s: não é possível localizar o keyblock original: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s: can't read original keyblock: %s\n" -msgstr "chave %08lX: impossível ler bloco de chaves original: %s\n" +msgstr "chave %s: não é possível ler o keyblock original: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid revocation certificate: %s - rejected\n" -msgstr "chave %08lX: certificado de revogação inválido: %s - rejeitado\n" +msgstr "chave %s: certificado de revogação inválido: %s - rejeitado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" revocation certificate imported\n" -msgstr "chave %08lX: \"%s\" certificado de revogação importado\n" +msgstr "chave %s: certificado de revogação \"%s\" importado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no user ID for signature\n" -msgstr "chave %08lX: nenhum ID de utilizador para assinatura\n" +msgstr "chave %s: nenhuma ID de utilizador para assinatura\n" -#, fuzzy, c-format +#, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"chave %08lX: algoritmo de chave pública não suportado no utilizador \"%s\"\n" +"chave %s: sem suporte a algoritmo de chave pública na ID de utilizador " +"\"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" -msgstr "chave %08lX: auto-assinatura inválida do utilizador \"%s\"\n" +msgstr "chave %s: auto-assinatura inválida na ID de utilizador \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "key %s: unsupported public key algorithm\n" -msgstr "chave %08lX: algoritmo de chave pública não suportado\n" +msgstr "chave %s: sem suporte ao algoritmo de chave pública\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid direct key signature\n" -msgstr "chave %08lX: assinatura directa de chave adicionada\n" +msgstr "chave %s: assinatura de chave direta inválida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no subkey for key binding\n" -msgstr "chave %08lX: sem subchave para ligação de chaves\n" +msgstr "chave %s: nenhuma subchave para vinculação de chave\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid subkey binding\n" -msgstr "chave %08lX: ligação de subchave inválida\n" +msgstr "chave %s: vinculação de subchave inválida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: removed multiple subkey binding\n" -msgstr "chave %08lX: apagada ligação múltipla de subchave \n" +msgstr "chave %s: vinculação de várias subchaves removida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no subkey for key revocation\n" -msgstr "chave %08lX: sem subchave para revocação de chave\n" +msgstr "chave %s: nenhuma subchave para revogação de chave\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid subkey revocation\n" -msgstr "chave %08lX: revocação de subchave inválida\n" +msgstr "chave %s: revogação de subchave inválida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: removed multiple subkey revocation\n" -msgstr "chave %08lX: removida revogação múltiplace de subchaves\n" +msgstr "chave %s: revogação de várias subchaves removida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: skipped user ID \"%s\"\n" -msgstr "chave %08lX: ignorado ID de utilizador '" +msgstr "chave %s: ID de utilizador \"%s\" ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: skipped subkey\n" -msgstr "chave %08lX: subchave ignorada\n" +msgstr "chave %s: subchave ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: non exportable signature (class 0x%02X) - skipped\n" -msgstr "chave %08lX: assinatura não exportável (classe %02x) - ignorada\n" +msgstr "chave %s: assinatura não exportável (classe 0x%02X) - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: revocation certificate at wrong place - skipped\n" -msgstr "chave %08lX: certificado de revogação no local errado - ignorado\n" +msgstr "chave %s: certificado de revogação no local errado - ignorado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: invalid revocation certificate: %s - skipped\n" -msgstr "chave %08lX: certificado de revogação inválido: %s - ignorado\n" +msgstr "Chave %s: certificado de revogação inválido: %s - ignorado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: subkey signature in wrong place - skipped\n" -msgstr "chave %08lX: assintura da subchave no local errado - ignorado\n" +msgstr "Tecla %s: assinatura de subchave no lugar errado - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: unexpected signature class (0x%02X) - skipped\n" -msgstr "chave %08lX: classe de assinatura inesperada (%02x) - ignorada\n" +msgstr "chave %s: classe de assinatura inesperada (0x%02X) - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s: duplicated user ID detected - merged\n" -msgstr "chave %08lX: detectado ID de utilizador duplicado - fundido\n" +msgstr "chave %s: detetada ID de utilizador duplicada - fundida\n" -#, fuzzy, c-format +#, c-format msgid "key %s: duplicated subkeys detected - merged\n" -msgstr "chave %08lX: detectado ID de utilizador duplicado - fundido\n" +msgstr "chave %s: detetadas subchaves duplicadas - fundidas\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: key %s may be revoked: fetching revocation key %s\n" msgstr "" -"AVISO: a chave %08lX pode estar revocada: a transferir a chave de revocação " -"%08lX\n" +"AVISO: a chave %s pode ser revogada: buscando a chave de revogação %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: key %s may be revoked: revocation key %s not present.\n" msgstr "" -"AVISO: a chave %08lX pode estar revocada: chave de revocação %08lX não " +"AVISO: a chave %s pode ser revogada: a chave de revogação %s não está " "presente.\n" -#, fuzzy, c-format +#, c-format msgid "key %s: \"%s\" revocation certificate added\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "chave %s: certificado de revogação \"%s\" adicionado\n" -#, fuzzy, c-format +#, c-format msgid "key %s: direct key signature added\n" -msgstr "chave %08lX: assinatura directa de chave adicionada\n" +msgstr "chave %s: assinatura de chave direta adicionada\n" -#, fuzzy, c-format +#, c-format msgid "error allocating memory: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao alocar memória: %s\n" -#, fuzzy, c-format +#, c-format msgid "can't check signature with unsupported public-key algorithm (%d): %s.\n" -msgstr "chave %08lX: algoritmo de chave pública não suportado\n" +msgstr "" +"não é possível verificar a assinatura com algoritmo de chave pública " +"insuportado (%d): %s.\n" -#, fuzzy, c-format +#, c-format msgid "" "can't check signature with unsupported message-digest algorithm %d: %s.\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "" +"não é possível verificar a assinatura com o algoritmo de digest de mensagens " +"insuportado %d: %s.\n" -#, fuzzy msgid " (reordered signatures follow)" -msgstr "Assinatura correcta de \"" +msgstr " (seguem-se as assinaturas reordenadas)" -#, fuzzy, c-format +#, c-format msgid "key %s:\n" -msgstr "ignorado `%s': %s\n" +msgstr "chave %s:\n" -#, fuzzy, c-format +#, c-format msgid "%d duplicate signature removed\n" msgid_plural "%d duplicate signatures removed\n" -msgstr[0] "Utilizador \"%s\" está revocado." -msgstr[1] "Utilizador \"%s\" está revocado." +msgstr[0] "%d assinatura duplicada removida\n" +msgstr[1] "%d assinaturas duplicadas removidas\n" -#, fuzzy, c-format -#| msgid "1 signature not checked due to a missing key\n" +#, c-format msgid "%d signature not checked due to a missing key\n" msgid_plural "%d signatures not checked due to missing keys\n" -msgstr[0] "1 assinatura não verificada por falta de chave\n" -msgstr[1] "1 assinatura não verificada por falta de chave\n" +msgstr[0] "%d assinatura não verificada devido a chave ausente\n" +msgstr[1] "%d assinaturas não verificadas devido a chaves ausentes\n" -#, fuzzy, c-format -#| msgid "%d bad signatures\n" +#, c-format msgid "%d bad signature\n" msgid_plural "%d bad signatures\n" -msgstr[0] "%d assinaturas incorrectas\n" -msgstr[1] "%d assinaturas incorrectas\n" +msgstr[0] "%d assinatura inválida\n" +msgstr[1] "%d assinaturas inválidas\n" -#, fuzzy, c-format +#, c-format msgid "%d signature reordered\n" msgid_plural "%d signatures reordered\n" -msgstr[0] "Assinatura correcta de \"" -msgstr[1] "Assinatura correcta de \"" +msgstr[0] "%d assinatura reordenada\n" +msgstr[1] "%d assinaturas reordenadas\n" #, c-format msgid "" "Warning: errors found and only checked self-signatures, run '%s' to check " "all signatures.\n" msgstr "" +"Aviso: erros encontrados e apenas auto-assinaturas verificadas, execute '%s' " +"para verificar todas as assinaturas.\n" -#, fuzzy, c-format +#, c-format msgid "error creating keybox '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao criar keybox '%s': %s\n" -#, fuzzy, c-format -#| msgid "error creating keyring `%s': %s\n" +#, c-format msgid "error creating keyring '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao criar porta-chaves '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "keybox '%s' created\n" -msgstr "porta-chaves `%s' criado\n" +msgstr "keybox '%s' criada\n" -#, fuzzy, c-format -#| msgid "keyring `%s' created\n" +#, c-format msgid "keyring '%s' created\n" -msgstr "porta-chaves `%s' criado\n" +msgstr "porta-chaves '%s' criado\n" -#, fuzzy, c-format +#, c-format msgid "keyblock resource '%s': %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "recurso keyblock '%s': %s\n" #, c-format msgid "failed to rebuild keyring cache: %s\n" -msgstr "falha ao criar 'cache' do porta-chaves: %s\n" +msgstr "falha ao criar a cache do porta-chaves: %s\n" msgid "[revocation]" msgstr "[revogação]" @@ -3343,87 +3220,89 @@ msgstr "[revogação]" msgid "[self-signature]" msgstr "[auto-assinatura]" -#, fuzzy msgid "" "Please decide how far you trust this user to correctly verify other users' " "keys\n" "(by looking at passports, checking fingerprints from different sources, " "etc.)\n" msgstr "" -"Por favor decida quanto confia neste utilizador para\n" -"verificar correctamente as chaves de outros utilizadores\n" -"(vendo passaportes, verificando impressões digitais...)?\n" -"\n" +"Decida até onde você confia neste utilizador para verificar\n" +"corretamente as chaves dos outros utilizadores\n" +"(olhando para passaportes, verificando impressões digitais de\n" +"diferentes fontes, etc.)\n" -#, fuzzy, c-format +#, c-format msgid " %d = I trust marginally\n" -msgstr " %d = Confio moderadamente\n" +msgstr " %d = Confio marginalmente\n" -#, fuzzy, c-format +#, c-format msgid " %d = I trust fully\n" -msgstr " %d = Confio plenamente\n" +msgstr " %d = Confio completamente\n" msgid "" "Please enter the depth of this trust signature.\n" "A depth greater than 1 allows the key you are signing to make\n" "trust signatures on your behalf.\n" msgstr "" +"Introduza a profundidade desta assinatura da confiança. Uma\n" +"profundidade maior que 1 permite que a chave que você está a assinar\n" +"faça assinaturas da confiança em seu nome.\n" msgid "Please enter a domain to restrict this signature, or enter for none.\n" msgstr "" +"Introduza um domínio para restringir essa assinatura, ou introduzir nada " +"para nenhum.\n" #, c-format msgid "Skipping user ID \"%s\", which is not a text ID.\n" -msgstr "" +msgstr "Ignorando a ID de utilizador \"%s\", que não é uma ID de texto.\n" #, c-format msgid "User ID \"%s\" is revoked." -msgstr "Utilizador \"%s\" está revocado." +msgstr "ID de utilizador \"%s\" está revogada." msgid "Are you sure you still want to sign it? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem certeza de que ainda deseja assiná-la? (s/N) " msgid " Unable to sign.\n" -msgstr " Não foi possível assinar.\n" +msgstr " Não é possível assinar.\n" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\" is expired." -msgstr "Utilizador \"%s\" está revocado." +msgstr "A ID de utilizador \"%s\" expirou." -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\" is not self-signed." -msgstr "AVISO: o ID do utilizador \"%s\" não é auto-assinado.\n" +msgstr "A ID de utilizador \"%s\" não é auto-assinada." -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\" is signable. " -msgstr "AVISO: o ID do utilizador \"%s\" não é auto-assinado.\n" +msgstr "A ID de utilizador \"%s\" é assinável. " -#, fuzzy msgid "Sign it? (y/N) " -msgstr "Realmente assinar? " +msgstr "Assiná-la? (s/N) " #, c-format msgid "" "The self-signature on \"%s\"\n" "is a PGP 2.x-style signature.\n" msgstr "" -"A sua auto-assinatura em \"%s\"\n" +"A auto-assinatura em \"%s\"\n" "é uma assinatura do tipo PGP 2.x.\n" msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) " msgstr "Quer promovê-la a uma auto-assinatura OpenPGP? (s/N) " -#, fuzzy, c-format +#, c-format msgid "" "Your current signature on \"%s\"\n" "has expired.\n" msgstr "" -"A sua assinatura actual em \"%s\"\n" -"é uma assinatura local.\n" +"A sua assinatura atual em \"%s\"\n" +"expirou.\n" -#, fuzzy msgid "Do you want to issue a new signature to replace the expired one? (y/N) " -msgstr "Quer que a sua assinatura expire na mesma altura? (S/n) " +msgstr "Deseja emitir uma nova assinatura para substituir a expirada? (s/N) " #, c-format msgid "" @@ -3434,23 +3313,22 @@ msgstr "" "é uma assinatura local.\n" msgid "Do you want to promote it to a full exportable signature? (y/N) " -msgstr "Quer promovê-la a uma assinatura exportável? (s/N)" +msgstr "Quer promovê-la a uma assinatura exportável? (s/N) " -#, fuzzy, c-format +#, c-format msgid "\"%s\" was already locally signed by key %s\n" -msgstr "\"%s\" já foi assinado localmente pela chave %08lX\n" +msgstr "\"%s\" já estava assinado localmente pela chave %s\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" was already signed by key %s\n" -msgstr "\"%s\" já foi assinado pela chave %08lX\n" +msgstr "\"%s\" já estava assinado pela chave %s\n" -#, fuzzy msgid "Do you want to sign it again anyway? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Mesmo assim, quer voltar a assinar de novo? (s/N) " -#, fuzzy, c-format +#, c-format msgid "Nothing to sign with key %s\n" -msgstr "Nada para assinar com a chave %08lX\n" +msgstr "Nada a assinar com a chave %s\n" msgid "This key has expired!" msgstr "Esta chave expirou!" @@ -3467,13 +3345,13 @@ msgid "" "belongs\n" "to the person named above? If you don't know what to answer, enter \"0\".\n" msgstr "" -"Com que cuidado é que verificou que chave que está prestes a assinar " -"pertence\n" -"à pessoa correcta? Se não sabe o que responder, escolha \"0\".\n" +"Com que cuidado é que verificou que chave que está prestes a assinar\n" +"pertence à pessoa correta? Se não souber o que responder, introduzir\n" +"\"0\".\n" #, c-format msgid " (0) I will not answer.%s\n" -msgstr " (0) Não vou responder.%s\n" +msgstr " (0) Não irei responder.%s\n" #, c-format msgid " (1) I have not checked at all.%s\n" @@ -3487,240 +3365,198 @@ msgstr " (2) Verifiquei por alto.%s\n" msgid " (3) I have done very careful checking.%s\n" msgstr " (3) Verifiquei com bastante cuidado.%s\n" -#, fuzzy msgid "Your selection? (enter '?' for more information): " -msgstr " i = mostrar mais informações\n" +msgstr "A sua seleção? (introduzir '?' para mais informações): " -#, fuzzy, c-format +#, c-format msgid "" "Are you sure that you want to sign this key with your\n" "key \"%s\" (%s)\n" msgstr "" -"Você tem certeza de que quer assinar esta chave com\n" -"a sua chave: \"" +"Tem certeza de que deseja assinar esta chave com a sua\n" +"chave \"%s\" (%s)\n" -#, fuzzy msgid "This will be a self-signature.\n" -msgstr "" -"\n" -"Isto será uma auto-assinatura.\n" +msgstr "Isto será uma auto-assinatura.\n" -#, fuzzy msgid "WARNING: the signature will not be marked as non-exportable.\n" -msgstr "" -"\n" -"AVISO: a assinatura não será marcada como não-exportável.\n" +msgstr "AVISO: a assinatura não será marcada como não-exportável.\n" -#, fuzzy msgid "WARNING: the signature will not be marked as non-revocable.\n" -msgstr "" -"\n" -"AVISO: a assinatura não será marcada como não-revocável.\n" +msgstr "AVISO: a assinatura não será marcada como não-revogável.\n" -#, fuzzy msgid "The signature will be marked as non-exportable.\n" -msgstr "" -"\n" -"A assinatura será marcada como não-exportável.\n" +msgstr "A assinatura será marcada como não-exportável.\n" -#, fuzzy msgid "The signature will be marked as non-revocable.\n" -msgstr "" -"\n" -"A assinatura será marcada como não-revocável.\n" +msgstr "A assinatura será marcada como não-revogável.\n" -#, fuzzy msgid "I have not checked this key at all.\n" -msgstr "" -"\n" -"Não verifiquei esta chave.\n" +msgstr "Eu não cheguei a verificar esta chave.\n" -#, fuzzy msgid "I have checked this key casually.\n" -msgstr "" -"\n" -"Verifiquei por alto esta chave.\n" +msgstr "Eu verifiquei esta chave por alto.\n" -#, fuzzy msgid "I have checked this key very carefully.\n" -msgstr "" -"\n" -"Verifiquei esta chave com muito cuidado.\n" +msgstr "Eu verifiquei esta chave com muito cuidado.\n" -#, fuzzy msgid "Really sign? (y/N) " -msgstr "Realmente assinar? " +msgstr "De certeza que deseja assinar? (s/N) " #, c-format msgid "signing failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "falha ao assinar: %s\n" msgid "Key has only stub or on-card key items - no passphrase to change.\n" msgstr "" +"A chave apenas tem os itens de chave stub ou dentro-do-cartão -\n" +"nenhuma frase-secreta para alterar.\n" -#, fuzzy, c-format -#| msgid "error creating passphrase: %s\n" +#, c-format msgid "key %s: error changing passphrase: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "chave %s: erro ao alterar a frase-secreta: %s\n" msgid "save and quit" msgstr "gravar e sair" -#, fuzzy msgid "show key fingerprint" -msgstr "mostra impressão digital" +msgstr "mostrar impressão digital da chave" -#, fuzzy msgid "show the keygrip" -msgstr "Notação de assinatura: " +msgstr "mostrar o keygrip" msgid "list key and user IDs" -msgstr "lista chave e identificadores de utilizadores" +msgstr "listar chave e IDs de utilizador" msgid "select user ID N" -msgstr "seleciona ID de utilizador N" +msgstr "selecionar ID de utilizador N" -#, fuzzy msgid "select subkey N" -msgstr "seleciona ID de utilizador N" +msgstr "selecionar subchave N" -#, fuzzy msgid "check signatures" -msgstr "revoga assinaturas" +msgstr "verificar assinaturas" msgid "sign selected user IDs [* see below for related commands]" msgstr "" +"assinar IDs de utilizador selecionadas [* veja abaixo os comandos " +"relacionados]" -#, fuzzy msgid "sign selected user IDs locally" -msgstr "assina a chave localmente" +msgstr "assinar localmente IDs de utilizador selecionadas" -#, fuzzy msgid "sign selected user IDs with a trust signature" -msgstr "Sugestão: Selecione os IDs de utilizador para assinar\n" +msgstr "assinar IDs de utilizador selecionadas com uma assinatura da confiança" msgid "sign selected user IDs with a non-revocable signature" msgstr "" +"assinar IDs de utilizador selecionadas com uma assinatura não-revogável" msgid "add a user ID" -msgstr "adiciona um novo ID de utilizador" +msgstr "adicionar uma ID de utilizador" msgid "add a photo ID" -msgstr "adiciona um identificador fotográfico" +msgstr "adicionar uma ID fotográfica" -#, fuzzy msgid "delete selected user IDs" -msgstr "remove ID de utilizador" +msgstr "apagar IDs de utilizador selecionadas" -#, fuzzy msgid "add a subkey" -msgstr "addkey" +msgstr "adicionar uma subchave" msgid "add a key to a smartcard" -msgstr "" +msgstr "adicionar uma chave a um smartcard" msgid "move a key to a smartcard" -msgstr "" +msgstr "mover uma chave para um smartcard" msgid "convert a key to TPM form using the local TPM" -msgstr "" +msgstr "converter uma chave para a forma TPM usando o TPM local" msgid "move a backup key to a smartcard" -msgstr "" +msgstr "mover uma chave de backup para um smartcard" -#, fuzzy msgid "delete selected subkeys" -msgstr "remove uma chave secundária" +msgstr "apagar subchaves selecionadas" msgid "add a revocation key" -msgstr "adiciona uma chave de revocação" +msgstr "adicionar uma chave de revogação" msgid "add an additional decryption subkey" -msgstr "" +msgstr "adicionar uma subchave adicional de decifração" -#, fuzzy msgid "delete signatures from the selected user IDs" -msgstr "" -"Realmente actualizar as preferências para os utilizadores seleccionados?" +msgstr "apagar assinaturas das IDs de utilizador selecionadas" -#, fuzzy msgid "change the expiration date for the key or selected subkeys" -msgstr "Você não pode modificar a data de validade de uma chave v3\n" +msgstr "alterar a data de expiração da chave ou das subchaves selecionadas" -#, fuzzy msgid "flag the selected user ID as primary" -msgstr "seleccionar o identificador do utilizador como primário" +msgstr "marcar a ID de utilizador selecionada como principal" msgid "list preferences (expert)" -msgstr "lista preferências (perito)" +msgstr "listar preferências (perito)" msgid "list preferences (verbose)" -msgstr "lista preferências (detalhadamente)" +msgstr "listar preferências (verboso)" -#, fuzzy msgid "set preference list for the selected user IDs" -msgstr "" -"Realmente actualizar as preferências para os utilizadores seleccionados?" +msgstr "definir lista de preferências para as IDs de utilizador selecionadas" -#, fuzzy msgid "set the preferred keyserver URL for the selected user IDs" -msgstr "não consegui processar a URI do servidor de chaves\n" - -#, fuzzy -msgid "set a notation for the selected user IDs" msgstr "" -"Realmente actualizar as preferências para os utilizadores seleccionados?" +"definir a URL preferencial do servidor de chaves para as IDs de utilizador " +"selecionadas" + +msgid "set a notation for the selected user IDs" +msgstr "definir uma notação para as IDs de utilizador selecionadas" msgid "change the passphrase" -msgstr "muda a frase secreta" +msgstr "alterar a frase-secreta" msgid "change the ownertrust" -msgstr "muda os valores de confiança" +msgstr "alterar o ownertrust" -#, fuzzy msgid "revoke signatures on the selected user IDs" -msgstr "Realmente revocar todos os IDs de utilizador seleccionados? " +msgstr "revogar assinaturas nas IDs de utilizador selecionadas" -#, fuzzy msgid "revoke selected user IDs" -msgstr "revocar um ID de utilizador" +msgstr "revogar IDs de utilizador selecionadas" -#, fuzzy msgid "revoke key or selected subkeys" -msgstr "revoga uma chave secundária" +msgstr "revogar chave ou subchaves selecionadas" -#, fuzzy msgid "enable key" -msgstr "activa uma chave" +msgstr "habilitar chave" -#, fuzzy msgid "disable key" -msgstr "desactiva uma chave" +msgstr "desabilitar chave" -#, fuzzy msgid "show selected photo IDs" -msgstr "mostrar identificador fotográfico" +msgstr "mostrar IDs fotográficas selecionadas" msgid "compact unusable user IDs and remove unusable signatures from key" msgstr "" +"compactar IDs de utilizador inutilizáveis e remover assinaturas " +"inutilizáveis da chave" msgid "compact unusable user IDs and remove all signatures from key" msgstr "" +"compactar IDs de utilizador inutilizáveis e remover todas as assinaturas da " +"chave" msgid "Secret key is available.\n" -msgstr "Chave secreta disponível.\n" +msgstr "Chave secreta está disponível.\n" -#, fuzzy -#| msgid "Secret key is available.\n" msgid "Secret subkeys are available.\n" -msgstr "Chave secreta disponível.\n" +msgstr "Subchaves secretas estão disponíveis.\n" msgid "" "Note: the local copy of the secret key will only be deleted with \"save\".\n" -msgstr "" +msgstr "Nota: a cópia local da chave secreta só será apagada com \"save\".\n" msgid "Need the secret key to do this.\n" -msgstr "A chave secreta é necessária para fazer isto.\n" +msgstr "É preciso a chave secreta para fazer isto.\n" msgid "" "* The 'sign' command may be prefixed with an 'l' for local signatures " @@ -3728,290 +3564,273 @@ msgid "" " a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures\n" " (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n" msgstr "" +"* O comando 'sign' pode ter como prefixo com um 'l' para assinaturas\n" +" locais (lsign), um 't' para assinaturas da confiança (tsign), um\n" +" 'nr' para assinaturas não-revogáveis (nrsign), ou qualquer\n" +" combinação destes (ltsign, tnrsign, etc.).\n" msgid "Key is revoked." msgstr "A chave está revogada." -#, fuzzy msgid "Really sign all text user IDs? (y/N) " -msgstr "Realmente assinar todos os IDs de utilizador? " +msgstr "" +"De certeza que deseja assinar todas as IDs de utilizador de texto? (s/N) " -#, fuzzy msgid "Really sign all user IDs? (y/N) " -msgstr "Realmente assinar todos os IDs de utilizador? " +msgstr "De certeza que deseja assinar todas as IDs de utilizador? (s/N) " msgid "Hint: Select the user IDs to sign\n" -msgstr "Sugestão: Selecione os IDs de utilizador para assinar\n" +msgstr "Dica: Selecione as IDs de utilizador para assinar\n" -#, fuzzy, c-format +#, c-format msgid "Unknown signature type '%s'\n" -msgstr "classe de assinatura desconhecida" +msgstr "Tipo de assinatura desconhecido '%s'\n" msgid "You must select at least one user ID.\n" -msgstr "Você precisa selecionar pelo menos um ID de utilizador.\n" +msgstr "Você precisa selecionar pelo menos uma ID de utilizador.\n" #, c-format msgid "(Use the '%s' command.)\n" -msgstr "" +msgstr "(Usar o comando '%s'.)\n" msgid "You can't delete the last user ID!\n" -msgstr "Você não pode remover o último ID de utilizador!\n" +msgstr "Você não pode apagar a última ID de utilizador!\n" -#, fuzzy msgid "Really remove all selected user IDs? (y/N) " -msgstr "Realmente remover todos os IDs de utilizador seleccionados? " +msgstr "" +"De certeza que deseja remover todas as IDs de utilizador selecionadas? (s/N) " -#, fuzzy msgid "Really remove this user ID? (y/N) " -msgstr "Realmente remover este ID de utilizador? " +msgstr "De certeza que deseja remover esta ID de utilizador? (s/N) " #. TRANSLATORS: Please take care: This is about #. moving the key and not about removing it. -#, fuzzy msgid "Really move the primary key? (y/N) " -msgstr "Realmente remover este ID de utilizador? " +msgstr "De certeza que deseja mover a chave principal? (s/N) " -#, fuzzy msgid "You must select exactly one key.\n" -msgstr "Você deve selecionar pelo menos uma chave.\n" +msgstr "Você deve selecionar exatamente uma chave.\n" msgid "Command expects a filename argument\n" -msgstr "" +msgstr "Comando espera como argumento um nome de ficheiro\n" -#, fuzzy, c-format +#, c-format msgid "Can't open '%s': %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "Não é possível abrir '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "Error reading backup key from '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "Erro ao ler a chave de backup a partir de '%s': %s\n" msgid "You must select at least one key.\n" msgstr "Você deve selecionar pelo menos uma chave.\n" -#, fuzzy msgid "Do you really want to delete the selected keys? (y/N) " -msgstr "Você quer realmente remover as chaves selecionadas? " +msgstr "De certeza que você deseja apagar as chaves selecionadas? (s/N) " -#, fuzzy msgid "Do you really want to delete this key? (y/N) " -msgstr "Você quer realmente remover esta chave? " +msgstr "De certeza que você deseja apagar esta chave? (s/N) " -#, fuzzy msgid "Really revoke all selected user IDs? (y/N) " -msgstr "Realmente revocar todos os IDs de utilizador seleccionados? " +msgstr "" +"De certeza que deseja revogar todas as IDs de utilizador selecionadas? (s/N) " -#, fuzzy msgid "Really revoke this user ID? (y/N) " -msgstr "Realmente revocar este ID de utilizador? " +msgstr "De certeza que deseja revogar esta ID de utilizador? (s/N) " -#, fuzzy msgid "Do you really want to revoke the entire key? (y/N) " -msgstr "Você quer realmente revogar esta chave? " +msgstr "De certeza que você deseja revogar a chave inteira? (s/N) " -#, fuzzy msgid "Do you really want to revoke the selected subkeys? (y/N) " -msgstr "Você quer realmente revogar as chaves selecionadas? " +msgstr "De certeza que você deseja revogar as subchaves selecionadas? (s/N) " -#, fuzzy msgid "Do you really want to revoke this subkey? (y/N) " -msgstr "Você quer realmente revogar esta chave? " +msgstr "De certeza que você deseja revogar esta subchave? (s/N) " msgid "Owner trust may not be set while using a user provided trust database\n" msgstr "" +"Owner trust não pode ser definida ao usar uma base de dados da\n" +"confiança fornecido pelo utilizador\n" -#, fuzzy msgid "Set preference list to:\n" -msgstr "configurar lista de preferências" +msgstr "Defina a lista de preferências para:\n" -#, fuzzy msgid "Really update the preferences for the selected user IDs? (y/N) " msgstr "" -"Realmente actualizar as preferências para os utilizadores seleccionados?" +"De certeza que deseja atualizar as preferências para as IDs de utilizador " +"selecionadas? (s/N) " -#, fuzzy msgid "Really update the preferences? (y/N) " -msgstr "Realmente actualizar as preferências?" +msgstr "De certeza que deseja atualizar as preferências? (s/N) " -#, fuzzy msgid "Save changes? (y/N) " -msgstr "Gravar alterações? " +msgstr "Gravar alterações? (s/N) " -#, fuzzy msgid "Quit without saving? (y/N) " -msgstr "Sair sem gravar? " +msgstr "Sair sem gravar? (s/N) " -#, fuzzy, c-format +#, c-format msgid "deleting copy of secret key failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao apagar cópia da chave secreta: %s\n" #, c-format msgid "Key not changed so no update needed.\n" -msgstr "Chave não alterada, nenhuma actualização é necessária.\n" +msgstr "Chave não alterada, por isso, é necessária nenhuma atualização.\n" -#, fuzzy, c-format -#| msgid "You can't delete the last user ID!\n" +#, c-format msgid "cannot revoke the last valid user ID.\n" -msgstr "Você não pode remover o último ID de utilizador!\n" +msgstr "não é possível revogar a última ID de utilizador válida.\n" -#, fuzzy, c-format +#, c-format msgid "revoking the user ID failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao revogar a ID de utilizador: %s\n" -#, fuzzy, c-format +#, c-format msgid "setting the primary user ID failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao definir a ID de utilizador principal: %s\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" is not a fingerprint\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "\"%s\" não é uma impressão digital\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" is not the primary fingerprint\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "\"%s\" não é a impressão digital principal\n" -#, fuzzy, c-format -#| msgid "invalid value\n" +#, c-format msgid "Invalid user ID '%s': %s\n" -msgstr "valor inválido\n" +msgstr "ID de utilizador '%s' inválida: %s\n" -#, fuzzy -#| msgid "No such user ID.\n" msgid "No matching user IDs." -msgstr "Identificador de utilizador inexistente.\n" +msgstr "Não há IDs de utilizador correspondentes." -#, fuzzy msgid "Nothing to sign.\n" -msgstr "Nada para assinar com a chave %08lX\n" +msgstr "Nada a assinar.\n" -#, fuzzy, c-format +#, c-format msgid "Not signed by you.\n" -msgstr " assinado por %08lX em %s%s\n" +msgstr "Não assinado por você.\n" -#, fuzzy, c-format -#| msgid "checking created signature failed: %s\n" +#, c-format msgid "revoking the key signature failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao revogar a assinatura da chave: %s\n" -#, fuzzy, c-format +#, c-format msgid "'%s' is not a valid expiration time\n" -msgstr "%s não é um conjunto de caracteres válido\n" +msgstr "'%s' não é um tempo de expiração válido\n" -#, fuzzy, c-format +#, c-format msgid "\"%s\" is not a proper fingerprint\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "\"%s\" não é propriamente uma impressão digital\n" -#, fuzzy, c-format +#, c-format msgid "subkey \"%s\" not found\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "subchave \"%s\" não encontrada\n" msgid "Preferred keyserver: " -msgstr "" +msgstr "Servidor de chaves preferido: " -#, fuzzy msgid "Notations: " -msgstr "Notação: " +msgstr "Notações: " msgid "There are no preferences on a PGP 2.x-style user ID.\n" -msgstr "Não há preferências no ID de utilizador tipo PGP 2.x.\n" +msgstr "Não há preferências numa ID de utilizador tipo PGP 2.x.\n" -#, fuzzy, c-format +#, c-format msgid "The following key was revoked on %s by %s key %s\n" -msgstr "Esta chave pode ser revogada pela chave %s " +msgstr "A chave seguinte foi revogada em %s pela chave %s de %s\n" -#, fuzzy, c-format +#, c-format msgid "This key may be revoked by %s key %s" -msgstr "Esta chave pode ser revogada pela chave %s " +msgstr "Esta chave pode ser revogada pela chave %s de %s" -#, fuzzy msgid "(sensitive)" -msgstr " (sensível)" +msgstr "(sensitivo)" -#, fuzzy, c-format +#, c-format msgid "created: %s" -msgstr "impossível criar %s: %s\n" +msgstr "criada: %s" -#, fuzzy, c-format +#, c-format msgid "revoked: %s" -msgstr "revkey" +msgstr "revogada: %s" -#, fuzzy, c-format +#, c-format msgid "expired: %s" -msgstr "[expira: %s]" +msgstr "expirada: %s" -#, fuzzy, c-format +#, c-format msgid "expires: %s" -msgstr "[expira: %s]" +msgstr "expira: %s" -#, fuzzy, c-format +#, c-format msgid "usage: %s" -msgstr " confiança: %c/%c" +msgstr "uso: %s" msgid "card-no: " -msgstr "" +msgstr "nº do cartão: " -#, fuzzy, c-format +#, c-format msgid "trust: %s" -msgstr " confiança: %c/%c" +msgstr "confiança: %s" #, c-format msgid "validity: %s" -msgstr "" +msgstr "validade: %s" msgid "This key has been disabled" -msgstr "Esta chave foi desactivada" +msgstr "Esta chave foi desabilitada" msgid "" "Please note that the shown key validity is not necessarily correct\n" "unless you restart the program.\n" msgstr "" -"Não se esqueça que a validade de chave mostrada não é necessáriamente a\n" -"correcta a não ser que reinicie o programa.\n" +"Note que a validade da chave mostrada não é necessariamente a\n" +"correta a menos que reinicie o programa.\n" -#, fuzzy msgid "revoked" -msgstr "revkey" +msgstr "revogada" -#, fuzzy msgid "expired" -msgstr "expire" +msgstr "expirada" #, c-format msgid "" "WARNING: no user ID has been marked as primary. This command may\n" " cause a different user ID to become the assumed primary.\n" msgstr "" +"AVISO: nenhuma ID de utilizador foi marcada como principal. Este\n" +" comando pode fazer com que uma ID de utilizador diferente\n" +" se torne como a presumida principal.\n" #, c-format msgid "WARNING: Your encryption subkey expires soon.\n" -msgstr "" +msgstr "AVISO: Sua subchave de cifração expira em breve.\n" -#, fuzzy, c-format -#| msgid "You can't change the expiration date of a v3 key\n" +#, c-format msgid "You may want to change its expiration date too.\n" -msgstr "Você não pode modificar a data de validade de uma chave v3\n" +msgstr "Você pode também querer alterar sua data de expiração.\n" #, c-format msgid "WARNING: No valid encryption subkey left over.\n" -msgstr "" +msgstr "AVISO: Sobrou nenhuma subchave de cifração válida.\n" msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" " of PGP to reject this key.\n" msgstr "" -"AVISO: Esta chave é do tipo PGP2. Se adicionar um identificador fotográfico\n" -" algumas versão do PGP podem rejeitá-la.\n" +"AVISO: Esta chave é do tipo PGP2. Se adicionar uma ID fotográfica\n" +" algumas versão do PGP podem rejeitar a chave.\n" msgid "Are you sure you still want to add it? (y/N) " -msgstr "Tem a certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem a certeza de que ainda deseja adicioná-la? (s/N) " msgid "You may not add a photo ID to a PGP2-style key.\n" -msgstr "" -"Não pode adicionar um identificador fotográfico a uma chave tipo PGP2.\n" +msgstr "Não pode adicionar uma ID fotográfica a uma chave tipo PGP2.\n" msgid "Such a user ID already exists on this key!" -msgstr "" +msgstr "Esse ID de utilizador já existe nesta chave!" msgid "Delete this good signature? (y/N/q)" msgstr "Apagar esta assinatura válida? (s/N/q)" @@ -4023,201 +3842,195 @@ msgid "Delete this unknown signature? (y/N/q)" msgstr "Apagar esta assinatura desconhecida? (s/N/q)" msgid "Really delete this self-signature? (y/N)" -msgstr "Realmente remover esta auto-assinatura? (s/N)" +msgstr "De certeza que deseja apagar esta auto-assinatura? (s/N)" -#, fuzzy, c-format -#| msgid "Deleted %d signature.\n" +#, c-format msgid "Deleted %d signature.\n" msgid_plural "Deleted %d signatures.\n" -msgstr[0] "%d assinatura removida.\n" -msgstr[1] "%d assinatura removida.\n" +msgstr[0] "%d assinatura apagada.\n" +msgstr[1] "%d assinaturas apagadas.\n" msgid "Nothing deleted.\n" -msgstr "Nada removido.\n" +msgstr "Nada apagada.\n" -#, fuzzy msgid "invalid" -msgstr "armadura inválida" +msgstr "inválida" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\" compacted: %s\n" -msgstr "Utilizador \"%s\" está revocado." +msgstr "ID de utilizador \"%s\" compactada: %s\n" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\": %d signature removed\n" msgid_plural "User ID \"%s\": %d signatures removed\n" -msgstr[0] "Utilizador \"%s\" está revocado." -msgstr[1] "Utilizador \"%s\" está revocado." +msgstr[0] "ID do utilizador \"%s\": %d assinatura removida\n" +msgstr[1] "ID do utilizador \"%s\": %d assinaturas removidas\n" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\": already minimized\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "ID de utilizador \"%s\": já estava minimizada\n" -#, fuzzy, c-format +#, c-format msgid "User ID \"%s\": already clean\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "ID de utilizador \"%s\": já estava limpa\n" msgid "" "WARNING: This is a PGP 2.x-style key. Adding a designated revoker may " "cause\n" " some versions of PGP to reject this key.\n" msgstr "" -"AVISO: Esta chave é do tipo PGP 2.x. Se adicionar um revogador designado\n" -" algumas versão do PGP podem rejeitá-la.\n" +"AVISO: Esta chave é do tipo PGP 2.x. Se adicionar uma revogadora designada\n" +" algumas versão do PGP podem rejeitar esta chave.\n" msgid "You may not add a designated revoker to a PGP 2.x-style key.\n" -msgstr "Não pode adicionar um revogador designado a uma chave tipo PGP 2.x.\n" +msgstr "" +"Não pode adicionar uma revogadora designada a uma chave tipo PGP 2.x.\n" msgid "Enter the user ID of the designated revoker: " -msgstr "Insira o ID de utilizador do revogador escolhido: " +msgstr "Introduzir a ID de utilizador da revogadora designada: " #, c-format msgid "cannot appoint a PGP 2.x style key as a designated revoker\n" -msgstr "não pode escolher uma chave do tipo PGP 2.x como revogadora\n" +msgstr "não pode nomear uma chave do tipo PGP 2.x como revogadora designada\n" #, c-format msgid "you cannot appoint a key as its own designated revoker\n" -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "não pode nomear uma chave como revogadora designada de si própria\n" -#, fuzzy, c-format +#, c-format msgid "this key has already been designated as a revoker\n" -msgstr "AVISO: Esta chave foi revogada pelo seu dono!\n" +msgstr "esta chave já foi designada como revogadora\n" -#, fuzzy msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n" -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "" +"ATENÇÃO: a nomeação de uma chave como revogadora designada não pode ser " +"desfeita!\n" -#, fuzzy msgid "" "Are you sure you want to appoint this key as a designated revoker? (y/N) " -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "" +"Tem certeza de que deseja nomear esta chave como uma revogadora designada? " +"(s/N) " msgid "Enter the fingerprint of the additional decryption subkey: " -msgstr "" +msgstr "Introduzir a impressão digital da subchave de decifração adicional: " -#, fuzzy, c-format -#| msgid "(unless you specify the key by fingerprint)\n" +#, c-format msgid "Did you specify the fingerprint of a subkey?\n" -msgstr "(a não ser que escolha a chave pela sua impressão digital)\n" +msgstr "Especificou a impressão digital de uma subchave?\n" -#, fuzzy, c-format +#, c-format msgid "key \"%s\" is already on this keyblock\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "A chave \"%s\" já está neste keyblock\n" -#, fuzzy msgid "" "Are you sure you want to change the expiration time for multiple subkeys? (y/" "N) " -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "" +"Tem certeza de que deseja alterar o tempo de expiração de várias subchaves? " +"(s/N) " -#, fuzzy msgid "Changing expiration time for a subkey.\n" -msgstr "A modificar a data de validade para uma chave secundária.\n" +msgstr "Alterando o tempo de expiração de uma subchave.\n" msgid "Changing expiration time for the primary key.\n" -msgstr "Modificar a data de validade para uma chave primária.\n" +msgstr "Modificando a data de expiração para a chave principal.\n" #, c-format msgid "You can't change the expiration date of a v3 key\n" -msgstr "Você não pode modificar a data de validade de uma chave v3\n" +msgstr "Você não pode modificar a data de expiração de uma chave v3\n" -#, fuzzy msgid "Changing usage of a subkey.\n" -msgstr "A modificar a data de validade para uma chave secundária.\n" +msgstr "Alterando a utilização de uma subchave.\n" -#, fuzzy -#| msgid "Changing expiration time for the primary key.\n" msgid "Changing usage of the primary key.\n" -msgstr "Modificar a data de validade para uma chave primária.\n" +msgstr "Alterando a utilização da chave principal.\n" -#, fuzzy, c-format +#, c-format msgid "signing subkey %s is already cross-certified\n" -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "a subchave de assinatura %s já é cruzadamente certificada\n" #, c-format msgid "subkey %s does not sign and so does not need to be cross-certified\n" msgstr "" +"a subchave %s não assina e, por isso, não precisa ser cruzadamente " +"certificada\n" msgid "Please select exactly one user ID.\n" -msgstr "Seleccione exactamente um identificador de utilizador.\n" +msgstr "Selecione exatamente uma ID de utilizador.\n" -#, fuzzy, c-format +#, c-format msgid "skipping v3 self-signature on user ID \"%s\"\n" -msgstr "a ignorar auto-assinatura v3 no utilizar com o id \"%s\"\n" +msgstr "ignorando a auto-assinatura v3 na ID de utilizador \"%s\"\n" msgid "Enter your preferred keyserver URL: " -msgstr "" +msgstr "Introduzir a URL do servidor de chaves preferido: " -#, fuzzy msgid "Are you sure you want to replace it? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem certeza de que deseja substituí-la? (s/N) " -#, fuzzy msgid "Are you sure you want to delete it? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem certeza de que deseja apagá-la? (s/N) " -#, fuzzy msgid "Enter the notation: " -msgstr "Notação de assinatura: " +msgstr "Introduzir a notação: " -#, fuzzy msgid "Proceed? (y/N) " -msgstr "Escrever por cima (s/N)? " +msgstr "Prosseguir? (s/N) " #, c-format msgid "No user ID with index %d\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma ID de utilizador com índice %d\n" -#, fuzzy, c-format +#, c-format msgid "No user ID with hash %s\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma ID de utilizador com hash %s\n" -#, fuzzy, c-format +#, c-format msgid "No subkey with key ID '%s'.\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma subchave com ID de chave '%s'.\n" -#, fuzzy, c-format +#, c-format msgid "No subkey with index %d\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma subchave com índice %d\n" -#, fuzzy, c-format +#, c-format msgid "user ID: \"%s\"\n" -msgstr "ID de utilizador: \"" +msgstr "ID de utilizador: \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "signed by your key %s on %s%s%s\n" -msgstr " assinado por %08lX em %s%s%s\n" +msgstr "assinado pela sua chave %s em %s%s%s\n" msgid " (non-exportable)" -msgstr " (não-exportável)" +msgstr " (não-exportável)" #, c-format msgid "This signature expired on %s.\n" msgstr "Esta assinatura expirou em %s.\n" msgid "Are you sure you still want to revoke it? (y/N) " -msgstr "Tem a certeza de que quer revogá-la de qualquer forma? (s/N) " +msgstr "Tem a certeza de que ainda deseja revogá-la? (s/N) " msgid "Create a revocation certificate for this signature? (y/N) " -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Criar um certificado de revogação para esta assinatura? (s/N) " -#, fuzzy, c-format +#, c-format msgid "You have signed these user IDs on key %s:\n" -msgstr "Assinou estes identificadores de utilizadores:\n" +msgstr "Você assinou estas IDs de utilizador na chave %s:\n" -#, fuzzy msgid " (non-revocable)" -msgstr " (não-exportável)" +msgstr " (não-revogável)" -#, fuzzy, c-format +#, c-format msgid "revoked by your key %s on %s\n" -msgstr " revogado por %08lX em %s\n" +msgstr "revogado pela sua chave %s em %s\n" msgid "You are about to revoke these signatures:\n" msgstr "Está prestes a revogar estas assinaturas:\n" msgid "Really create the revocation certificates? (y/N) " -msgstr "Realmente criar os certificados de revogação? (s/N) " +msgstr "De certeza que deseja criar os certificados de revogação? (s/N) " #, c-format msgid "no secret key\n" @@ -4225,78 +4038,75 @@ msgstr "nenhuma chave secreta\n" #, c-format msgid "tried to revoke a non-user ID: %s\n" -msgstr "" +msgstr "tentou revogar uma ID sem-utilizador: %s\n" #, c-format msgid "user ID \"%s\" is already revoked\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "ID de utilizador \"%s\" já está revogada\n" #, c-format msgid "WARNING: a user ID signature is dated %d seconds in the future\n" -msgstr "" -"AVISO: a assintura do ID do utilizador tem data %d segundos no futuro\n" +msgstr "AVISO: a assinatura da ID do utilizador está a %d segundos no futuro\n" -#, fuzzy, c-format -#| msgid "You can't delete the last user ID!\n" +#, c-format msgid "Cannot revoke the last valid user ID.\n" -msgstr "Você não pode remover o último ID de utilizador!\n" +msgstr "Não é possível revogar a última ID de utilizador válida.\n" -#, fuzzy, c-format +#, c-format msgid "Key %s is already revoked.\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "A chave %s já está revogada.\n" -#, fuzzy, c-format +#, c-format msgid "Subkey %s is already revoked.\n" -msgstr "o utilizador com o id \"%s\" já está revocado\n" +msgstr "A subchave %s já está revogada.\n" -#, fuzzy, c-format +#, c-format msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n" -msgstr "" -"A mostrar a fotografia %s com o tamanho %ld da chave 0x%08lX (uid %d)\n" +msgstr "Exibindo ID fotográfica %s de tamanho %ld para a chave %s (uid %d)\n" -#, fuzzy, c-format +#, c-format msgid "invalid value for option '%s'\n" -msgstr "opções de importação inválidas\n" +msgstr "valor inválido para a opção '%s'\n" -#, fuzzy, c-format +#, c-format msgid "preference '%s' duplicated\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "preferência '%s' duplicada\n" -#, fuzzy, c-format +#, c-format msgid "too many cipher preferences\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiadas preferências da cifra\n" -#, fuzzy, c-format +#, c-format msgid "too many digest preferences\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiadas preferências de digest\n" -#, fuzzy, c-format +#, c-format msgid "too many compression preferences\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiadas preferências de compressão\n" -#, fuzzy, c-format +#, c-format msgid "too many AEAD preferences\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiadas preferências AEAD\n" -#, fuzzy, c-format +#, c-format msgid "invalid item '%s' in preference string\n" -msgstr "caracter inválido na cadeia de caractéres da preferência\n" +msgstr "item inválido '%s' na string de preferência\n" #, c-format msgid "writing direct signature\n" -msgstr "a escrever a assinatura directa\n" +msgstr "escrevendo a assinatura direta\n" #, c-format msgid "writing self signature\n" -msgstr "a escrever a auto-assinatura\n" +msgstr "escrevendo a auto-assinatura\n" #, c-format msgid "writing key binding signature\n" -msgstr "a escrever a assinatura ligada a uma chave\n" +msgstr "escrevendo a assinatura ligada a uma chave\n" #, c-format msgid "keysize invalid; using %u bits\n" -msgstr "tamanho de chave inválido; a utilizar %u bits\n" +msgstr "tamanho de chave inválido; usando %u bits\n" #, c-format msgid "keysize rounded up to %u bits\n" @@ -4306,20 +4116,20 @@ msgstr "tamanho da chave arredondado para %u bits\n" msgid "" "WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n" msgstr "" +"AVISO: alguns programas OpenPGP não conseguem lidar com uma chave DSA deste " +"tamanho de digest\n" -#, fuzzy msgid "Sign" -msgstr "sign" +msgstr "Assinar" msgid "Certify" -msgstr "" +msgstr "Certificar" -#, fuzzy msgid "Encrypt" -msgstr "cifrar dados" +msgstr "Cifrar" msgid "Authenticate" -msgstr "" +msgstr "Autenticar" #. TRANSLATORS: Please use only plain ASCII characters for the #. * translation. If this is not possible use single digits. The @@ -4332,143 +4142,129 @@ msgstr "" #. * q = Finish #. msgid "SsEeAaQq" -msgstr "" +msgstr "SsEeAaTt" #, c-format msgid "Possible actions for this %s key: " -msgstr "" +msgstr "Ações possíveis para esta chave %s: " msgid "Current allowed actions: " -msgstr "" +msgstr "Ações permitidas atualmente: " #, c-format msgid " (%c) Toggle the sign capability\n" -msgstr "" +msgstr " (%c) Alternar o capacidade de assinar\n" -#, fuzzy, c-format +#, c-format msgid " (%c) Toggle the encrypt capability\n" -msgstr " (%d) ElGamal (apenas cifragem)\n" +msgstr " (%c) Alternar a capacidade de cifrar\n" #, c-format msgid " (%c) Toggle the authenticate capability\n" -msgstr "" +msgstr " (%c) Alternar a capacidade de autenticação\n" #, c-format msgid " (%c) Finished\n" -msgstr "" +msgstr " (%c) Terminado\n" -#, fuzzy, c-format +#, c-format msgid " (%d) RSA and RSA%s\n" -msgstr " (%d) DSA e ElGamal (por omissão)\n" +msgstr " (%d) RSA e RSA%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) DSA and Elgamal%s\n" -msgstr " (%d) DSA e ElGamal (por omissão)\n" +msgstr " (%d) DSA e Elgamal%s\n" -#, fuzzy, c-format -#| msgid " (%d) DSA (sign only)\n" +#, c-format msgid " (%d) DSA (sign only)%s\n" -msgstr " (%d) DSA (apenas assinatura)\n" +msgstr " (%d) DSA (apenas de assinar)%s\n" -#, fuzzy, c-format -#| msgid " (%d) RSA (sign only)\n" +#, c-format msgid " (%d) RSA (sign only)%s\n" -msgstr " (%d) RSA (apenas assinatura)\n" +msgstr " (%d) RSA (apenas de assinar)%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) Elgamal (encrypt only)%s\n" -msgstr " (%d) ElGamal (apenas cifragem)\n" +msgstr " (%d) Elgamal (apenas de cifrar)%s\n" -#, fuzzy, c-format -#| msgid " (%d) RSA (encrypt only)\n" +#, c-format msgid " (%d) RSA (encrypt only)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) RSA (apenas de cifrar)%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) DSA (set your own capabilities)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) DSA (defina as suas capacidades)%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) RSA (set your own capabilities)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) RSA (defina as suas capacidades)%s\n" -#, fuzzy, c-format -#| msgid " (%d) ElGamal (sign and encrypt)\n" +#, c-format msgid " (%d) ECC (sign and encrypt)%s\n" -msgstr " (%d) ElGamal (assinatura e cifragem)\n" +msgstr " (%d) ECC (de assinar e cifrar)%s\n" -#, fuzzy -#| msgid " (default)" msgid " *default*" -msgstr " (por omissão)" +msgstr " *pré-definição*" -#, fuzzy, c-format -#| msgid " (%d) DSA (sign only)\n" +#, c-format msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (apenas assinatura)\n" +msgstr " (%d) ECC (apenas de assinar)\n" -#, fuzzy, c-format +#, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) ECC (defina as suas capacidades)%s\n" -#, fuzzy, c-format -#| msgid " (%d) RSA (encrypt only)\n" +#, c-format msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) ECC (apenas de cifrar)%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) Chave existente%s\n" -#, fuzzy, c-format +#, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) Chave do cartão existente%s\n" -#, fuzzy msgid "Enter the keygrip: " -msgstr "Notação de assinatura: " +msgstr "Introduzir o keygrip: " #, c-format msgid "Not a valid keygrip (expecting 40 hex digits)\n" -msgstr "" +msgstr "Não é um keygrip válido (à espera de 40 dígitos hex)\n" -#, fuzzy msgid "No key with this keygrip\n" -msgstr "Nenhum ID de utilizador com índice %d\n" +msgstr "Nenhuma chave com este keygrip\n" -#, fuzzy, c-format +#, c-format msgid "error reading the card: %s\n" -msgstr "%s: erro ao ler registo livre: %s\n" +msgstr "erro ao ler o cartão: %s\n" -#, fuzzy, c-format +#, c-format msgid "Serial number of the card: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "Número de série do cartão: %s\n" -#, fuzzy msgid "Available keys:\n" -msgstr "desactiva uma chave" +msgstr "Chaves disponíveis:\n" -#, fuzzy, c-format -#| msgid "rounded up to %u bits\n" +#, c-format msgid "rounded to %u bits\n" msgstr "arredondado para %u bits\n" #, c-format msgid "%s keys may be between %u and %u bits long.\n" -msgstr "" +msgstr "As chaves %s podem estar entre %u e %u bits de comprimento.\n" -#, fuzzy, c-format +#, c-format msgid "What keysize do you want for the subkey? (%u) " -msgstr "Qual o tamanho de chave desejado? (1024) " +msgstr "Qual o tamanho de chave que você deseja para a subchave? (%u) " #, c-format msgid "Requested keysize is %u bits\n" msgstr "O tamanho de chave pedido é %u bits\n" -#, fuzzy -#| msgid "Please select what kind of key you want:\n" msgid "Please select which elliptic curve you want:\n" -msgstr "Por favor selecione o tipo de chave desejado:\n" +msgstr "Selecione qual a curva elíptica que você deseja:\n" msgid "" "Please specify how long the key should be valid.\n" @@ -4478,7 +4274,7 @@ msgid "" " m = key expires in n months\n" " y = key expires in n years\n" msgstr "" -"Por favor especifique por quanto tempo a chave deve ser válida.\n" +"Especifique quando a chave expira.\n" " 0 = chave não expira\n" " = chave expira em n dias\n" " w = chave expira em n semanas\n" @@ -4493,7 +4289,7 @@ msgid "" " m = signature expires in n months\n" " y = signature expires in n years\n" msgstr "" -"Por favor especifique por quanto tempo a assinatura deve ser válida.\n" +"Especifique quando a assinatura expira.\n" " 0 = assinatura não expira\n" " = assinatura expira em n dias\n" " w = assinatura expira em n semanas\n" @@ -4501,53 +4297,52 @@ msgstr "" " y = assinatura expira em n anos\n" msgid "Key is valid for? (0) " -msgstr "A chave é valida por? (0) " +msgstr "Quando a chave expira? (0) " -#, fuzzy, c-format +#, c-format msgid "Signature is valid for? (%s) " -msgstr "A assinatura é valida por? (0) " +msgstr "Quando a assinatura expira? (%s) " msgid "invalid value\n" msgstr "valor inválido\n" -#, fuzzy msgid "Key does not expire at all\n" -msgstr "A %s não expira nunca\n" +msgstr "A chave não expira de forma alguma\n" -#, fuzzy msgid "Signature does not expire at all\n" -msgstr "A %s não expira nunca\n" +msgstr "A assinatura não expira de forma alguma\n" -#, fuzzy, c-format +#, c-format msgid "Key expires at %s\n" -msgstr "%s expira em %s\n" +msgstr "A chave expira em %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature expires at %s\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "A assinatura expira em %s\n" msgid "" "Your system can't display dates beyond 2038.\n" "However, it will be correctly handled up to 2106.\n" msgstr "" "O seu sistema não consegue mostrar datas para além de 2038.\n" -"No entanto, estas vão ser tratadas correctamente até 2106.\n" +"No entanto, será lidado corretamente até 2106.\n" -#, fuzzy msgid "Is this correct? (y/N) " -msgstr "Está correto (s/n)? " +msgstr "Isto está correto? (s/N) " msgid "" "\n" "GnuPG needs to construct a user ID to identify your key.\n" "\n" msgstr "" +"\n" +"O GnuPG precisa construir uma ID de utilizador para identificar sua chave.\n" +"\n" #. TRANSLATORS: This string is in general not anymore used #. but you should keep your existing translation. In case #. the new string is not translated this old string will #. be used. -#, fuzzy msgid "" "\n" "You need a user ID to identify your key; the software constructs the user " @@ -4557,39 +4352,37 @@ msgid "" "\n" msgstr "" "\n" -"Você precisa de um identificador de utilizador para identificar sua chave; " -"o\n" -"programa constrói o identificador a partir do Nome Completo, Comentário e\n" -"Endereço Eletrónico desta forma:\n" +"Você precisa de uma ID de utilizador para identificar sua chave; o\n" +"software constrói a ID de utilizador a partir de o Nome Verdadeiro, o\n" +"Comentário, e o Endereço de email com esta forma:\n" " \"Heinrich Heine (Der Dichter) \"\n" "\n" msgid "Real name: " -msgstr "Nome completo: " +msgstr "Nome verdadeiro: " msgid "Invalid character in name\n" -msgstr "Caracter inválido no nome\n" +msgstr "Caractere inválido no nome\n" #, c-format msgid "The characters '%s' and '%s' may not appear in name\n" -msgstr "" +msgstr "Os caracteres '%s' e '%s' não podem aparecer no nome\n" msgid "Email address: " -msgstr "Endereço de correio eletrónico: " +msgstr "Endereço de email: " msgid "Not a valid email address\n" -msgstr "Endereço eletrónico inválido\n" +msgstr "Endereço de email inválido\n" msgid "Comment: " msgstr "Comentário: " msgid "Invalid character in comment\n" -msgstr "Caracter inválido no comentário\n" +msgstr "Caractere inválido no comentário\n" -#, fuzzy, c-format -#| msgid "You are using the `%s' character set.\n" +#, c-format msgid "You are using the '%s' character set.\n" -msgstr "Você está usando o conjunto de caracteres `%s'.\n" +msgstr "Você está usando o set de caracteres '%s'.\n" #, c-format msgid "" @@ -4597,17 +4390,15 @@ msgid "" " \"%s\"\n" "\n" msgstr "" -"Você selecionou este identificador de utilizador:\n" +"Você selecionou este USER-ID:\n" " \"%s\"\n" "\n" msgid "Please don't put the email address into the real name or the comment\n" -msgstr "" -"Por favor não coloque o endereço de email no nome verdadeiro ou no " -"comentário\n" +msgstr "Não coloque o endereço de email no nome verdadeiro ou no comentário\n" msgid "Such a user ID already exists on this key!\n" -msgstr "" +msgstr "Tal ID de utilizador já existe nesta chave!\n" #. TRANSLATORS: These are the allowed answers in #. lower and uppercase. Below you will find the matching @@ -4624,23 +4415,19 @@ msgid "NnCcEeOoQq" msgstr "NnCcEeOoSs" msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? " -msgstr "Mudar (N)ome, (C)omentário, (E)mail ou (S)air? " +msgstr "Alterar (N)ome, (C)omentário, (E)mail, ou (S)air? " msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? " -msgstr "Mudar (N)ome, (C)omentário, (E)ndereço ou (O)k/(S)air? " +msgstr "Alterar (N)ome, (C)omentário, (E)ndereço, ou (O)k/(S)air? " -#, fuzzy -#| msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? " msgid "Change (N)ame, (E)mail, or (Q)uit? " -msgstr "Mudar (N)ome, (C)omentário, (E)mail ou (S)air? " +msgstr "Alterar (N)ome, (E)mail, ou (S)air? " -#, fuzzy -#| msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? " msgid "Change (N)ame, (E)mail, or (O)kay/(Q)uit? " -msgstr "Mudar (N)ome, (C)omentário, (E)ndereço ou (O)k/(S)air? " +msgstr "Alterar (N)ome, (E)mail, ou (O)k/(S)air? " msgid "Please correct the error first\n" -msgstr "Por favor corrija primeiro o erro\n" +msgstr "Corrija primeiro o erro\n" msgid "" "We need to generate a lot of random bytes. It is a good idea to perform\n" @@ -4649,13 +4436,13 @@ msgid "" "generator a better chance to gain enough entropy.\n" msgstr "" "Precisamos gerar muitos bytes aleatórios. É uma boa ideia realizar outra\n" -"actividade (escrever no teclado, mover o rato, usar os discos) durante a\n" -"geração dos números primos; isso dá ao gerador de números aleatórios\n" +"atividade (escrever no teclado, mover o rato, usar os discos) durante a\n" +"geração dos números primos; isto dá ao gerador de números aleatórios\n" "uma hipótese maior de ganhar entropia suficiente.\n" #, c-format msgid "WARNING: v4 is specified, but overridden by v5.\n" -msgstr "" +msgstr "AVISO: v4 está especificada, mas é sobreposta pela v5.\n" #, c-format msgid "Key generation failed: %s\n" @@ -4667,119 +4454,117 @@ msgid "" " \"%s\"\n" "\n" msgstr "" +"Prestes a criar uma chave para:\n" +" \"%s\"\n" +"\n" msgid "Continue? (Y/n) " -msgstr "" +msgstr "Continuar? (S/n) " -#, fuzzy, c-format +#, c-format msgid "A key for \"%s\" already exists\n" -msgstr "%s' já comprimido\n" +msgstr "Já existe uma chave para \"%s\"\n" -#, fuzzy -#| msgid "Create anyway? " msgid "Create anyway? (y/N) " -msgstr "Criar mesmo assim?" +msgstr "Mesmo assim, criar? (s/N) " -#, fuzzy, c-format -#| msgid "Create anyway? " +#, c-format msgid "creating anyway\n" -msgstr "Criar mesmo assim?" +msgstr "mesmo assim, criando\n" #, c-format msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n" msgstr "" +"Nota: Usar \"%s %s\" para uma caixa de diálogo completa de geração de " +"chave.\n" #, c-format msgid "Key generation canceled.\n" msgstr "Geração de chave cancelada.\n" -#, fuzzy, c-format +#, c-format msgid "can't create backup file '%s': %s\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível criar o ficheiro de backup '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: backup of card key saved to '%s'\n" -msgstr "NOTA: chave secreta %08lX expirou em %s\n" +msgstr "Nota: backup da chave do cartão guardada em '%s'\n" -#, fuzzy, c-format -#| msgid "writing public key to `%s'\n" +#, c-format msgid "writing public key to '%s'\n" -msgstr "a escrever chave pública para `%s'\n" +msgstr "escrevendo chave pública para '%s'\n" #, c-format msgid "no writable public keyring found: %s\n" -msgstr "nenhum porta-chaves público com permissões de escrita encontrado: %s\n" +msgstr "nenhum porta-chaves público com permissão de escrita encontrado: %s\n" -#, fuzzy, c-format -#| msgid "error writing public keyring `%s': %s\n" +#, c-format msgid "error writing public keyring '%s': %s\n" -msgstr "erro ao escrever no porta-chaves público `%s': %s\n" +msgstr "erro ao escrever o porta-chaves público '%s': %s\n" msgid "public and secret key created and signed.\n" msgstr "chaves pública e privada criadas e assinadas.\n" -#, fuzzy msgid "" "Note that this key cannot be used for encryption. You may want to use\n" "the command \"--edit-key\" to generate a subkey for this purpose.\n" msgstr "" -"Note que esta chave não pode ser usada para cifragem. Você pode usar\n" -"o comando \"--edit-key\" para gerar uma chave secundária para esse fim.\n" +"Repare que esta chave não pode ser usada para cifração. Poderá querer usar\n" +"o comando \"--edit-key\" para gerar uma subchave com esta finalidade.\n" #, c-format msgid "" "key has been created %lu second in future (time warp or clock problem)\n" msgstr "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"chave foi criada %lu segundo no futuro (deformação temporal ou problema de " +"relógio)\n" #, c-format msgid "" "key has been created %lu seconds in future (time warp or clock problem)\n" msgstr "" -"a chave foi criada %lu segundos no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"chave foi criada %lu segundos no futuro (deformação temporal ou problema de " +"relógio)\n" -#, fuzzy, c-format -#| msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n" +#, c-format msgid "Note: creating subkeys for v3 keys is not OpenPGP compliant\n" -msgstr "NOTA: a criação de sub-chave para chaves v3 não respeito o OpenPGP\n" +msgstr "" +"Nota: a criação de subchaves para chaves v3 não é compatível com OpenPGP\n" #, c-format msgid "Secret parts of primary key are not available.\n" -msgstr "Componentes secretas da chave primária não disponíveis.\n" +msgstr "Partes secretas da chave principal não disponíveis.\n" -#, fuzzy, c-format +#, c-format msgid "Secret parts of primary key are stored on-card.\n" -msgstr "Componentes secretas da chave primária não disponíveis.\n" +msgstr "Partes secretas da chave principal estão armazenadas no cartão.\n" -#, fuzzy msgid "Really create? (y/N) " -msgstr "Realmente criar? " +msgstr "De certeza que deseja criar? (s/N) " msgid "never " -msgstr "" +msgstr "nunca " msgid "AEAD: " -msgstr "" +msgstr "AEAD: " msgid "Digest: " -msgstr "'Digest': " +msgstr "Digest: " msgid "Features: " msgstr "Características: " msgid "Keyserver no-modify" -msgstr "" +msgstr "Servidor de chaves no-modify" msgid "Critical signature policy: " -msgstr "Politica de assinatura crítica: " +msgstr "Política de assinatura crítica: " msgid "Signature policy: " -msgstr "Politica de assinatura: " +msgstr "Política de assinatura: " msgid "Critical preferred keyserver: " -msgstr "" +msgstr "Servidor de chaves preferencial crítico: " msgid "Critical signature notation: " msgstr "Notação de assinatura crítica: " @@ -4787,208 +4572,200 @@ msgstr "Notação de assinatura crítica: " msgid "Signature notation: " msgstr "Notação de assinatura: " -#, fuzzy, c-format -#| msgid "%d bad signatures\n" +#, c-format msgid "%d good signature\n" msgid_plural "%d good signatures\n" -msgstr[0] "%d assinaturas incorrectas\n" -msgstr[1] "%d assinaturas incorrectas\n" +msgstr[0] "%d assinatura válida\n" +msgstr[1] "%d assinaturas válidas\n" -#, fuzzy, c-format -#| msgid "1 signature not checked due to an error\n" +#, c-format msgid "%d signature not checked due to an error\n" msgid_plural "%d signatures not checked due to errors\n" -msgstr[0] "1 assinatura não verificada devido a um erro\n" -msgstr[1] "1 assinatura não verificada devido a um erro\n" +msgstr[0] "%d assinatura não verificada devido a erro\n" +msgstr[1] "%d assinaturas não verificadas devido a erros\n" #, c-format msgid "Warning: %lu key skipped due to its large size\n" msgid_plural "Warning: %lu keys skipped due to their large sizes\n" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Aviso: %lu chave ignorada devido ao seu tamanho grande\n" +msgstr[1] "Aviso: %lu chaves ignoradas devido aos seus tamanhos grandes\n" msgid "Keyring" msgstr "Porta-chaves" msgid "Primary key fingerprint:" -msgstr "Impressão da chave primária:" +msgstr "Impressão digital da chave principal:" msgid " Subkey fingerprint:" -msgstr " Impressão da subchave:" +msgstr " Impressão digital da subchave:" #. TRANSLATORS: this should fit into 24 bytes so that the #. * fingerprint data is properly aligned with the user ID msgid " Primary key fingerprint:" -msgstr "Impressão da chave primária:" +msgstr " Impressão chave princ.:" msgid " Subkey fingerprint:" -msgstr " Impressão da subchave:" +msgstr " Impressão da subchave:" -#, fuzzy msgid " Key fingerprint =" -msgstr " Impressão da chave =" +msgstr " Impressão da chave =" msgid " Card serial no. =" -msgstr "" +msgstr "Nº de série do cartão =" -#, fuzzy, c-format +#, c-format msgid "caching keyring '%s'\n" -msgstr "a verificar o porta chaves `%s'\n" +msgstr "guardando na cache do porta-chaves '%s'\n" -#, fuzzy, c-format +#, c-format msgid "%lu keys cached so far (%lu signature)\n" msgid_plural "%lu keys cached so far (%lu signatures)\n" -msgstr[0] "%lu chave verificadas (%lu assinaturas)\n" -msgstr[1] "%lu chave verificadas (%lu assinaturas)\n" +msgstr[0] "" +"%lu chaves que, até agora, foram guardadas na cache (%lu assinatura)\n" +msgstr[1] "" +"%lu chaves que, até agora, foram guardadas na cache (%lu assinaturas)\n" #, c-format msgid "%lu key cached" msgid_plural "%lu keys cached" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lu chave guardada na cache" +msgstr[1] "%lu chaves guardadas na cache" -#, fuzzy, c-format -#| msgid "1 bad signature\n" +#, c-format msgid " (%lu signature)\n" msgid_plural " (%lu signatures)\n" -msgstr[0] "1 assinatura incorrecta\n" -msgstr[1] "1 assinatura incorrecta\n" +msgstr[0] " (%lu assinatura)\n" +msgstr[1] " (%lu assinaturas)\n" #, c-format msgid "%s: keyring created\n" msgstr "%s: porta-chaves criado\n" msgid "override proxy options set for dirmngr" -msgstr "" +msgstr "sobrepor opções de proxy definidas para dirmngr" msgid "include revoked keys in search results" -msgstr "" +msgstr "incluir chaves revogadas nos resultados da pesquisa" msgid "include subkeys when searching by key ID" -msgstr "" +msgstr "incluir subchaves ao pesquisar pela ID de chave" msgid "override timeout options set for dirmngr" -msgstr "" +msgstr "sobrepor opções de tempo limite definidas para dirmngr" msgid "automatically retrieve keys when verifying signatures" -msgstr "" +msgstr "obter chaves automaticamente quando se verifica assinaturas" -#, fuzzy msgid "honor the preferred keyserver URL set on the key" -msgstr "a URL de política de assinatura dada é inválida\n" +msgstr "honrar a URL do servidor de chaves preferencial definida na chave" -#, fuzzy msgid "disabled" -msgstr "disable" +msgstr "desabilitado" msgid "Enter number(s), N)ext, or Q)uit > " -msgstr "" +msgstr "Introduzir o(s) número(s), N)ext, ou Q)uit > " -#, fuzzy, c-format +#, c-format msgid "invalid keyserver protocol (us %d!=handler %d)\n" -msgstr "opções de exportação inválidas\n" +msgstr "protocolo de servidor de chaves inválido (nós %d!=handler %d)\n" #, c-format msgid "\"%s\" not a key ID: skipping\n" -msgstr "" +msgstr "\"%s\" não é uma ID de chave: ignorando\n" -#, fuzzy, c-format +#, c-format msgid "refreshing %d key from %s\n" msgid_plural "refreshing %d keys from %s\n" -msgstr[0] "a pedir a chave %08lX de %s\n" -msgstr[1] "a pedir a chave %08lX de %s\n" +msgstr[0] "atualizando %d chave de %s\n" +msgstr[1] "atualizando %d chaves de %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unable to refresh key %s via %s: %s\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: não é possível atualizar a chave %s via %s: %s\n" -#, fuzzy, c-format +#, c-format msgid "key \"%s\" not found on keyserver\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave \"%s\" não encontrada no servidor de chaves\n" -#, fuzzy, c-format +#, c-format msgid "key not found on keyserver\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave não encontrada no servidor de chaves\n" -#, fuzzy, c-format +#, c-format msgid "requesting key %s from %s\n" -msgstr "a pedir a chave %08lX de %s\n" +msgstr "pedindo chave %s de %s\n" -#, fuzzy, c-format +#, c-format msgid "no keyserver known\n" -msgstr "opções de exportação inválidas\n" +msgstr "nenhum servidor de chaves conhecido\n" -#, fuzzy, c-format +#, c-format msgid "skipped \"%s\": %s\n" -msgstr "ignorado `%s': %s\n" +msgstr "ignorado \"%s\": %s\n" -#, fuzzy, c-format +#, c-format msgid "sending key %s to %s\n" -msgstr "" -"\"\n" -"assinado com a sua chave %08lX em %s\n" +msgstr "enviando a chave %s para %s\n" -#, fuzzy, c-format +#, c-format msgid "requesting key from '%s'\n" -msgstr "a pedir a chave %08lX de %s\n" +msgstr "pedindo chave de '%s'\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unable to fetch URI %s: %s\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: não é possível buscar o URI %s: %s\n" #, c-format msgid "weird size for an encrypted session key (%d)\n" msgstr "tamanho estranho para uma chave de sessão cifrada (%d)\n" -#, fuzzy, c-format +#, c-format msgid "%s.%s encrypted session key\n" -msgstr "tamanho estranho para uma chave de sessão cifrada (%d)\n" +msgstr "%s.%s chave de sessão cifrada\n" -#, fuzzy, c-format -#| msgid "%s encrypted data\n" +#, c-format msgid "%s.%s encrypted data\n" -msgstr "dados cifrados com %s\n" +msgstr "%s.%s dados cifrados\n" -#, fuzzy, c-format -#| msgid "encrypted with unknown algorithm %d\n" +#, c-format msgid "encrypted with unknown algorithm %d.%s\n" -msgstr "cifrado com algoritmo desconhecido %d\n" +msgstr "cifrado com algoritmo desconhecido %d.%s\n" -#, fuzzy, c-format +#, c-format msgid "passphrase generated with unknown digest algorithm %d\n" -msgstr "cifrado com algoritmo desconhecido %d\n" +msgstr "frase-secreta gerada com algoritmo de digest desconhecido %d\n" -#, fuzzy, c-format +#, c-format msgid "public key is %s\n" -msgstr "a chave pública é %08lX\n" +msgstr "chave pública é %s\n" -#, fuzzy, c-format +#, c-format msgid "encrypted with %s key, ID %s, created %s\n" -msgstr "cifrado com chave %u-bit %s, ID %08lX, criada em %s\n" +msgstr "cifrado com chave %s, ID %s, criado em %s\n" -#, fuzzy, c-format +#, c-format msgid " \"%s\"\n" -msgstr " ou \"" +msgstr " \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "encrypted with %s key, ID %s\n" -msgstr "cifrado com chave %s, ID %08lX\n" +msgstr "cifrado com chave %s, ID %s\n" #, c-format msgid "WARNING: multiple plaintexts seen\n" -msgstr "" +msgstr "AVISO: vários textos simples vistos\n" -#, fuzzy, c-format +#, c-format msgid "encrypted with %lu passphrases\n" -msgstr "Repita a frase secreta\n" +msgstr "cifrado com %lu frase-secretas\n" -#, fuzzy, c-format +#, c-format msgid "encrypted with 1 passphrase\n" -msgstr "Repita a frase secreta\n" +msgstr "cifrado com 1 frase-secreta\n" #, c-format msgid "public key decryption failed: %s\n" -msgstr "decifragem de chave pública falhou: %s\n" +msgstr "falha ao decifrar com chave pública: %s\n" #, c-format msgid "public key encrypted data: good DEK\n" @@ -4996,34 +4773,36 @@ msgstr "dados cifrados com chave pública: DEK válido\n" #, c-format msgid "assuming %s encrypted data\n" -msgstr "a assumir dados cifrados %s\n" +msgstr "assumindo %s dados cifrados\n" #, c-format msgid "IDEA cipher unavailable, optimistically attempting to use %s instead\n" -msgstr "Cifra IDEO não disponível, a tentar utilizar %s em substituição\n" +msgstr "a cifra IDEA não está disponível, tentando utilizar %s invés\n" #, c-format msgid "WARNING: message was not integrity protected\n" -msgstr "AVISO: a mensagem não tinha a sua integridade protegida\n" +msgstr "AVISO: a mensagem não tinha proteção de integridade\n" msgid "" "Hint: If this message was created before the year 2003 it is\n" "likely that this message is legitimate. This is because back\n" "then integrity protection was not widely used.\n" msgstr "" +"Dica: Se esta mensagem foi criada antes do ano de 2003 é\n" +"provável que esta mensagem seja legítima. Isto porque dantes\n" +"a proteção da integridade não era amplamente utilizada.\n" #, c-format msgid "Use the option '%s' to decrypt anyway.\n" -msgstr "" +msgstr "Usar a opção '%s' para, mesmo assim, decifrar.\n" -#, fuzzy, c-format -#| msgid "decryption failed: %s\n" +#, c-format msgid "decryption forced to fail!\n" -msgstr "decifragem falhou: %s\n" +msgstr "decifração forçada a falhar!\n" #, c-format msgid "decryption okay\n" -msgstr "decifragem correcta\n" +msgstr "decifração ok\n" #, c-format msgid "WARNING: encrypted message has been manipulated!\n" @@ -5031,16 +4810,16 @@ msgstr "CUIDADO: a mensagem cifrada foi manipulada!\n" #, c-format msgid "decryption failed: %s\n" -msgstr "decifragem falhou: %s\n" +msgstr "decifração falhou: %s\n" #, c-format msgid "operation forced to fail due to unfulfilled compliance rules\n" msgstr "" +"operação forçada a falhar devido a regras de conformidade não cumpridas\n" -#, fuzzy, c-format -#| msgid "NOTE: sender requested \"for-your-eyes-only\"\n" +#, c-format msgid "Note: sender requested \"for-your-eyes-only\"\n" -msgstr "NOTA: o remetente solicitou \"apenas-para-seus-olhos\"\n" +msgstr "Nota: remetente pediu \"for-your-eyes-only\"\n" #, c-format msgid "original file name='%.*s'\n" @@ -5048,317 +4827,307 @@ msgstr "nome do ficheiro original='%.*s'\n" #, c-format msgid "standalone revocation - use \"gpg --import\" to apply\n" -msgstr "revocação solitária - utilize \"gpg --import\" para aplicar\n" +msgstr "revogação autónoma - usar \"gpg --import\" para aplicar\n" -#, fuzzy, c-format +#, c-format msgid "no signature found\n" -msgstr "Assinatura correcta de \"" +msgstr "nenhuma assinatura encontrada\n" -#, fuzzy, c-format +#, c-format msgid "BAD signature from \"%s\"" -msgstr "Assinatura INCORRECTA de \"" +msgstr "Assinatura INVÁLIDA de \"%s\"" -#, fuzzy, c-format +#, c-format msgid "Expired signature from \"%s\"" -msgstr "Assinatura expirada de \"" +msgstr "Assinatura expirada de \"%s\"" -#, fuzzy, c-format +#, c-format msgid "Good signature from \"%s\"" -msgstr "Assinatura correcta de \"" +msgstr "Assinatura válida de \"%s\"" #, c-format msgid "signature verification suppressed\n" msgstr "verificação de assinatura suprimida\n" -#, fuzzy, c-format +#, c-format msgid "can't handle this ambiguous signature data\n" -msgstr "não consigo tratar estas assinaturas múltiplas\n" +msgstr "não é possível lidar com esses dados de assinatura ambíguos\n" -#, fuzzy, c-format +#, c-format msgid "Signature made %s\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Assinatura feita em %s\n" -#, fuzzy, c-format +#, c-format msgid " using %s key %s\n" -msgstr " ou \"" +msgstr " usando a chave %s de %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature made %s using %s key ID %s\n" -msgstr "Assinatura feita em %.*s usando %s, ID da chave %08lX\n" +msgstr "Assinatura feita em %s usando %s com ID de chave %s\n" -#, fuzzy, c-format +#, c-format msgid " issuer \"%s\"\n" -msgstr " ou \"" +msgstr " emissor \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "Key available at: " -msgstr "Nenhuma ajuda disponível" +msgstr "Chave disponível em: " #, c-format msgid "Note: Use '%s' to make use of this info\n" -msgstr "" +msgstr "Nota: Usar '%s' para fazer uso desta info\n" msgid "[uncertain]" msgstr "[incerto]" -#, fuzzy, c-format +#, c-format msgid " aka \"%s\"" -msgstr " ou \"" +msgstr " aka \"%s\"" -#, fuzzy, c-format -#| msgid "WARNING: This key is not certified with a trusted signature!\n" +#, c-format msgid "WARNING: This key is not suitable for signing in %s mode\n" -msgstr "AVISO: Esta chave não está certificada com uma assinatura confiável!\n" +msgstr "AVISO: Esta chave não é adequada para assinar no modo %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature expired %s\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "A assinatura expirou %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature expires %s\n" -msgstr "Esta assinatura expirou em %s.\n" +msgstr "A assinatura expira %s\n" -#, fuzzy, c-format +#, c-format msgid "%s signature, digest algorithm %s%s%s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "assinatura %s, algoritmo de digest %s%s%s\n" -#, fuzzy msgid "binary" -msgstr "primary" +msgstr "binário" msgid "textmode" -msgstr "" +msgstr "modo de texto" -#, fuzzy msgid "unknown" -msgstr "versão desconhecida" +msgstr "desconhecido" -#, fuzzy -#| msgid "unknown pubkey algorithm" msgid ", key algorithm " -msgstr "algoritmo de chave pública desconhecido" +msgstr ", algoritmo da chave " #, c-format msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n" msgstr "" +"ATENÇÃO: não é uma assinatura desanexada; ficheiro '%s' NÃO foi verificado!\n" #, c-format msgid "Can't check signature: %s\n" -msgstr "Impossível verificar assinatura: %s\n" +msgstr "Não é possível verificar a assinatura: %s\n" #, c-format msgid "not a detached signature\n" -msgstr "não é uma assinatura separada\n" +msgstr "não é uma assinatura desanexada\n" #, c-format msgid "" "WARNING: multiple signatures detected. Only the first will be checked.\n" msgstr "" -"AVISO: várias assinaturas detectadas. Apenas a primeira será verificada.\n" +"AVISO: várias assinaturas detetadas. Apenas a primeira será verificada.\n" #, c-format msgid "standalone signature of class 0x%02x\n" -msgstr "assinatura de classe 0x%02x\n" +msgstr "assinatura autónoma da classe 0x%02x\n" #, c-format msgid "old style (PGP 2.x) signature\n" -msgstr "formato de assinatura antigo (PGP2.x)\n" +msgstr "tipo de assinatura antigo (PGP 2.x)\n" -#, fuzzy, c-format +#, c-format msgid "fstat of '%s' failed in %s: %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "fstat de '%s' falhou em %s: %s\n" -#, fuzzy, c-format +#, c-format msgid "fstat(%d) failed in %s: %s\n" -msgstr "base de dados de confiança: leitura falhou (n=%d): %s\n" +msgstr "fstat(%d) falhou em %s: %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: using experimental public key algorithm %s\n" -msgstr "impossível manipular algoritmo de chave pública %d\n" +msgstr "AVISO: usando o algoritmo de chave pública experimental %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n" -msgstr "" -"forçar o algoritmo de 'digest' %s (%d) viola as preferências do " -"destinatário\n" +msgstr "AVISO: chaves Elgamal de assinar+cifrar estão depreciadas\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: using experimental cipher algorithm %s\n" -msgstr "algoritmo de criptografia não implementado" +msgstr "AVISO: usando o algoritmo de cifra experimental %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: using experimental digest algorithm %s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "AVISO: usando o algoritmo de digest experimental %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: digest algorithm %s is deprecated\n" -msgstr "" -"forçar o algoritmo de 'digest' %s (%d) viola as preferências do " -"destinatário\n" +msgstr "AVISO: o algoritmo de digest %s foi depreciado\n" -#, fuzzy, c-format +#, c-format msgid "Note: signatures using the %s algorithm are rejected\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "Nota: as assinaturas que usam o algoritmo %s são rejeitadas\n" -#, fuzzy, c-format +#, c-format msgid "Note: third-party key signatures using the %s algorithm are rejected\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "" +"Nota: assinaturas de chave de terceiros usando o algoritmo %s são " +"rejeitadas\n" -#, fuzzy, c-format +#, c-format msgid "(reported error: %s)\n" -msgstr "armadura: %s\n" +msgstr "(reportado erro: %s)\n" -#, fuzzy, c-format +#, c-format msgid "(reported error: %s <%s>)\n" -msgstr "armadura: %s\n" +msgstr "(reportado erro: %s <%s>)\n" #, c-format msgid "(further info: " -msgstr "" +msgstr "(mais informações: " #, c-format msgid "%s:%d: deprecated option \"%s\"\n" -msgstr "%s:%d: opção depreciada \"%s\"\n" +msgstr "%s:%d: opção \"%s\" depreciada\n" #, c-format msgid "please use \"%s%s\" instead\n" -msgstr "por favor utilize \"%s%s\" em vez dela\n" +msgstr "use \"%s%s\" invés\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: \"%s\" is a deprecated command - do not use it\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "AVISO: \"%s\" é um comando depreciado - não o use\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "%s:%u: \"%s\" está obsoleto neste ficheiro - ele só tem efeito em %s\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n" -msgstr "AVISO: \"%s\" é uma opção depreciada\n" +msgstr "AVISO: \"%s%s\" é uma opção obsoleta - não tem efeito exceto em %s\n" -#, fuzzy msgid "Uncompressed" -msgstr "não processado" +msgstr "Descomprimido" #. TRANSLATORS: See doc/TRANSLATE about this string. -#, fuzzy msgid "uncompressed|none" -msgstr "não processado" +msgstr "descomprimido|nenhum" #, c-format msgid "this message may not be usable by %s\n" msgstr "esta mensagem poderá não ser utilizável pelo %s\n" -#, fuzzy, c-format +#, c-format msgid "ambiguous option '%s'\n" -msgstr "a ler opções de `%s'\n" +msgstr "opção ambígua '%s'\n" -#, fuzzy, c-format +#, c-format msgid "unknown option '%s'\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "opção desconhecida '%s'\n" #, c-format msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n" msgstr "" +"É esperado que a chave pública ECDSA esteja na codificação SEC múltiplo de 8 " +"bits\n" -#, fuzzy, c-format +#, c-format msgid "unknown weak digest '%s'\n" -msgstr "classe de assinatura desconhecida" +msgstr "digest '%s' fraco e desconhecido\n" -#, fuzzy, c-format -#| msgid "File `%s' exists. " +#, c-format msgid "File '%s' exists. " -msgstr "Arquivo `%s' já existe. " +msgstr "O ficheiro '%s' existe. " -#, fuzzy msgid "Overwrite? (y/N) " -msgstr "Escrever por cima (s/N)? " +msgstr "Sobrescrever? (s/N) " #, c-format msgid "%s: unknown suffix\n" msgstr "%s: sufixo desconhecido\n" msgid "Enter new filename" -msgstr "Digite novo nome de ficheiro" +msgstr "Introduzir um novo nome de ficheiro" #, c-format msgid "writing to stdout\n" -msgstr "a escrever em \"stdout\"\n" +msgstr "escrevendo para stdout\n" -#, fuzzy, c-format -#| msgid "assuming signed data in `%s'\n" +#, c-format msgid "assuming signed data in '%s'\n" -msgstr "a assumir dados assinados em `%s'\n" +msgstr "assumindo dados assinados em '%s'\n" #, c-format msgid "can't handle public key algorithm %d\n" -msgstr "impossível manipular algoritmo de chave pública %d\n" +msgstr "não é possível lidar com o algoritmo de chave pública %d\n" #, c-format msgid "WARNING: potentially insecure symmetrically encrypted session key\n" msgstr "" +"AVISO: chave de sessão simetricamente cifrada potencialmente insegura\n" -#, fuzzy, c-format -#| msgid "Critical signature notation: " +#, c-format msgid "Unknown critical signature notation: " -msgstr "Notação de assinatura crítica: " +msgstr "Notação de assinatura crítica desconhecida: " #, c-format msgid "subpacket of type %d has critical bit set\n" -msgstr "subpacote do tipo %d tem bit crítico ligado\n" +msgstr "sub-pacote do tipo %d tem bit crítico definido\n" -#, fuzzy msgid "Please enter the passphrase for decryption." -msgstr "muda a frase secreta" +msgstr "Introduza a frase-secreta para decifração." msgid "Enter passphrase\n" -msgstr "Insira a frase secreta\n" +msgstr "Introduzir a frase-secreta\n" #, c-format msgid "cancelled by user\n" -msgstr "cancelado pelo utilizador\n" +msgstr "cancelada pelo utilizador\n" -#, fuzzy, c-format +#, c-format msgid " (main key ID %s)" -msgstr " (ID principal da chave %08lX)" +msgstr " (ID da chave principal %s)" -#, fuzzy msgid "Please enter the passphrase to unlock the OpenPGP secret key:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para desbloquear a chave secreta OpenPGP:" -#, fuzzy msgid "Please enter the passphrase to import the OpenPGP secret key:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para importar a chave secreta OpenPGP:" -#, fuzzy msgid "Please enter the passphrase to export the OpenPGP secret subkey:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para exportar a subchave secreta OpenPGP:" -#, fuzzy msgid "Please enter the passphrase to export the OpenPGP secret key:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para exportar a chave secreta OpenPGP:" -#, fuzzy msgid "Do you really want to permanently delete the OpenPGP secret subkey key:" -msgstr "Você quer realmente remover as chaves selecionadas? " +msgstr "" +"De certeza que você deseja apagar permanentemente a subchave secreta OpenPGP:" -#, fuzzy msgid "Do you really want to permanently delete the OpenPGP secret key:" -msgstr "Você quer realmente remover as chaves selecionadas? " +msgstr "" +"De certeza que você deseja apagar permanentemente a chave secreta OpenPGP:" -#, fuzzy msgid "Please enter the passphrase to export the secret key with keygrip:" -msgstr "Por favor digite a frase secreta \n" +msgstr "Introduza a frase-secreta para exportar a chave secreta com keygrip:" -#, fuzzy, c-format +#, c-format msgid "" "%s\n" "\"%.*s\"\n" "%u-bit %s key, ID %s,\n" "created %s%s.\n" "%s" -msgstr "chave de %u-bit/%s, ID %08lX, criada em %s" +msgstr "" +"%s\n" +"\"%.*s\"\n" +"%u-bit chave %s, ID %s,\n" +"criada %s%s.\n" +"%s" msgid "" "\n" @@ -5367,66 +5136,74 @@ msgid "" "very large picture, your key will become very large as well!\n" "Keeping the image close to 240x288 is a good size to use.\n" msgstr "" +"\n" +"Escolha uma imagem para usar como ID fotográfica. A imagem deve ser um\n" +"ficheiro JPEG.\n" +"Lembre-se de que a imagem é armazenada dentro da sua chave pública.\n" +"Se você usar uma imagem muito grande, sua chave também se vai tornar\n" +"muito grande!\n" +"Manter a imagem perto de 240x288 é um bom tamanho para se usar.\n" msgid "Enter JPEG filename for photo ID: " -msgstr "" +msgstr "Introduzir um nome do ficheiro JPEG para a ID fotográfica: " -#, fuzzy, c-format +#, c-format msgid "unable to open JPEG file '%s': %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "não é possível abrir o ficheiro JPEG '%s': %s\n" #, c-format msgid "This JPEG is really large (%d bytes) !\n" -msgstr "" +msgstr "Este JPEG é mesmo grande (%d bytes) !\n" -#, fuzzy msgid "Are you sure you want to use it? (y/N) " -msgstr "Você tem certeza de que quer adicioná-la de qualquer forma? (s/N) " +msgstr "Tem certeza de que deseja usá-lo? (s/N) " -#, fuzzy, c-format +#, c-format msgid "'%s' is not a JPEG file\n" -msgstr "%s: não é um base de dados de confiança\n" +msgstr "'%s' não é um ficheiro JPEG\n" -#, fuzzy msgid "Is this photo correct (y/N/q)? " -msgstr "Está correto (s/n)? " +msgstr "Esta foto está correta? (s/N/q) " #, c-format msgid "no remote program execution supported\n" -msgstr "" +msgstr "não há suporte a execução de programas remotos\n" -#, fuzzy, c-format +#, c-format msgid "this platform requires temporary files when calling external programs\n" -msgstr "%s: erro ao ler registo de versão: %s\n" +msgstr "" +"esta plataforma requer ficheiros temporários ao chamar programas externos\n" -#, fuzzy, c-format +#, c-format msgid "unable to execute shell '%s': %s\n" -msgstr "não foi possível alterar o exec-path para %s\n" +msgstr "não é possível executar o shell '%s': %s\n" #, c-format msgid "unnatural exit of external program\n" -msgstr "" +msgstr "saída não natural do programa externo\n" -#, fuzzy, c-format +#, c-format msgid "system error while calling external program: %s\n" -msgstr "%s: erro ao ler registo de versão: %s\n" +msgstr "erro do sistema ao chamar o programa externo: %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: não é possível remover o ficheiro temporário (%s) '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: unable to remove temp directory '%s': %s\n" -msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" +msgstr "AVISO: não é possível remover a pasta temporária '%s': %s\n" #, c-format msgid "" "external program calls are disabled due to unsafe options file permissions\n" msgstr "" +"As chamadas de programa externo estão desativadas devido a opções não\n" +"seguras de permissões de ficheiro\n" -#, fuzzy, c-format +#, c-format msgid "unable to display photo ID!\n" -msgstr "não foi possível alterar o exec-path para %s\n" +msgstr "não é possível exibir uma ID fotográfica!\n" #. TRANSLATORS: These are the allowed answers in lower and #. uppercase. Below you will find the matching strings which @@ -5439,76 +5216,71 @@ msgstr "não foi possível alterar o exec-path para %s\n" #. q = quit #. msgid "iImMqQsS" -msgstr "iImMqQsS" +msgstr "mMvVsSiI" -#, fuzzy msgid "No trust value assigned to:\n" -msgstr "" -"Nenhum valor de confiança designado para:\n" -"%4u%c/%08lX %s \"" +msgstr "Nenhum valor da confiança atribuído a:\n" -#, fuzzy, c-format +#, c-format msgid " aka \"%s\"\n" -msgstr " ou \"" +msgstr " aka \"%s\"\n" -#, fuzzy msgid "" "How much do you trust that this key actually belongs to the named user?\n" -msgstr "Esta chave provavelmente pertence ao dono\n" +msgstr "" +"Quanto é que você confia que esta chave realmente pertence a tal " +"utilizador?\n" -#, fuzzy, c-format +#, c-format msgid " %d = I don't know or won't say\n" -msgstr " %d = Não sei\n" +msgstr " %d = Não sei ou não vou dizer\n" -#, fuzzy, c-format +#, c-format msgid " %d = I do NOT trust\n" -msgstr " %d = Eu NÃO confio\n" +msgstr " %d = NÃO confio\n" -#, fuzzy, c-format +#, c-format msgid " %d = I trust ultimately\n" -msgstr " %d = Confio de forma total\n" +msgstr " %d = Confio plenamente\n" -#, fuzzy msgid " m = back to the main menu\n" -msgstr " m = voltar ao menu principal\n" +msgstr " v = voltar ao menu principal\n" -#, fuzzy msgid " s = skip this key\n" -msgstr " s = saltar esta chave\n" +msgstr " i = ignorar esta chave\n" -#, fuzzy msgid " q = quit\n" -msgstr " q = sair\n" +msgstr " s = sair\n" #, c-format msgid "" "The minimum trust level for this key is: %s\n" "\n" msgstr "" +"O nível mínimo da confiança para esta chave é: %s\n" +"\n" msgid "Your decision? " -msgstr "Decisão? " +msgstr "Sua decisão? " -#, fuzzy msgid "Do you really want to set this key to ultimate trust? (y/N) " -msgstr "Tem a certeza que quer confiar totalmente nesta chave?" +msgstr "" +"De certeza que você deseja definir confiança plena para esta chave? (s/N) " msgid "Certificates leading to an ultimately trusted key:\n" msgstr "Certificados que levam a uma chave confiada plenamente:\n" -#, fuzzy, c-format +#, c-format msgid "%s: There is no assurance this key belongs to the named user\n" -msgstr "" -"%08lx: Não há indicação de que a assinatura pertence realmente ao dono.\n" +msgstr "%s: Não há garantia de que esta chave pertence a tal utilizador\n" -#, fuzzy, c-format +#, c-format msgid "%s: There is limited assurance this key belongs to the named user\n" -msgstr "" -"%08lx: Não há indicação de que a assinatura pertence realmente ao dono.\n" +msgstr "%s: Há garantia limitada de que esta chave pertence a tal utilizador\n" -#, fuzzy, c-format +#, c-format msgid "This key probably belongs to the named user\n" -msgstr "Esta chave provavelmente pertence ao dono\n" +msgstr "Esta chave provavelmente pertence a tal utilizador\n" #, c-format msgid "This key belongs to us\n" @@ -5516,69 +5288,64 @@ msgstr "Esta chave pertence-nos\n" #, c-format msgid "%s: This key is bad! It has been marked as untrusted!\n" -msgstr "" +msgstr "%s: Esta chave é inválida! Foi marcada como não confiável!\n" -#, fuzzy msgid "" "This key is bad! It has been marked as untrusted! If you\n" "*really* know what you are doing, you may answer the next\n" "question with yes.\n" msgstr "" -"NÃO se tem certeza de que esta chave pertence ao seu dono.\n" -"Se você *realmente* sabe o que está a fazer, pode responder\n" -"sim à próxima pergunta\n" -"\n" +"Esta chave é inválida! Foi marcada como não confiável! Se você\n" +"tem a *certeza* do que está fazendo, você pode responder à próxima\n" +"pergunta com sim.\n" -#, fuzzy msgid "" "It is NOT certain that the key belongs to the person named\n" "in the user ID. If you *really* know what you are doing,\n" "you may answer the next question with yes.\n" msgstr "" -"NÃO se tem certeza de que esta chave pertence ao seu dono.\n" -"Se você *realmente* sabe o que está a fazer, pode responder\n" -"sim à próxima pergunta\n" -"\n" +"NÃO é certo que a chave pertença à pessoa da ID de utilizador.\n" +"Se você tem a *certeza* do que está fazendo, você pode responder\n" +"à próxima pergunta com sim.\n" -#, fuzzy msgid "Use this key anyway? (y/N) " -msgstr "Usar esta chave de qualquer modo? " +msgstr "Mesmo assim, usar esta chave? (s/N) " #, c-format msgid "WARNING: Using untrusted key!\n" -msgstr "AVISO: A utilizar uma chave que não é de confiança!\n" +msgstr "AVISO: Usando chave não confiável!\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: this key might be revoked (revocation key not present)\n" msgstr "" -"AVISO: a chave %08lX pode estar revocada: chave de revocação %08lX não " -"presente.\n" +"AVISO: esta chave pode estar revogada (chave de revogação não presente)\n" -#, fuzzy, c-format +#, c-format msgid "checking User ID \"%s\"\n" -msgstr "ID de utilizador: \"" +msgstr "verificando a ID de Utilizador \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "option %s given but issuer \"%s\" does not match\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "opção %s dada, mas não corresponde ao emissor \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "issuer \"%s\" does not match any User ID\n" -msgstr "chave %08lX: não corresponde à nossa cópia\n" +msgstr "o emissor \"%s\" não corresponde a qualquer ID de Utilizador\n" -#, fuzzy, c-format +#, c-format msgid "option %s given but no matching User ID found\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "" +"opção %s dada, mas nenhuma ID de utilizador correspondente encontrada\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: This key has been revoked by its designated revoker!\n" -msgstr "AVISO: Esta chave foi revogada pelo seu dono!\n" +msgstr "AVISO: Esta chave foi revogada pela sua revogadora designada!\n" #, c-format msgid "WARNING: This key has been revoked by its owner!\n" msgstr "AVISO: Esta chave foi revogada pelo seu dono!\n" -#, fuzzy, c-format +#, c-format msgid " This could mean that the signature is forged.\n" msgstr " Isto pode significar que a assinatura é falsificada.\n" @@ -5588,16 +5355,17 @@ msgstr "AVISO: Esta subchave foi revogada pelo seu dono!\n" #, c-format msgid "Note: This key has been disabled.\n" -msgstr "Nota: Esta chave foi desactivada.\n" +msgstr "Nota: Esta chave foi desabilitada.\n" #, c-format msgid "Note: This key has expired!\n" msgstr "Nota: Esta chave expirou!\n" -#, fuzzy, c-format -#| msgid "WARNING: This key is not certified with a trusted signature!\n" +#, c-format msgid "WARNING: The key's User ID is not certified with a trusted signature!\n" -msgstr "AVISO: Esta chave não está certificada com uma assinatura confiável!\n" +msgstr "" +"AVISO: A ID de utilizador da chave não está certificada com uma assinatura " +"confiável!\n" #, c-format msgid "WARNING: This key is not certified with a trusted signature!\n" @@ -5606,7 +5374,7 @@ msgstr "AVISO: Esta chave não está certificada com uma assinatura confiável!\ #, c-format msgid "" " There is no indication that the signature belongs to the owner.\n" -msgstr " Não há indicação de que a assinatura pertence ao dono.\n" +msgstr " Não há indicação que a assinatura pertença ao dono.\n" #, c-format msgid "WARNING: We do NOT trust this key!\n" @@ -5616,137 +5384,133 @@ msgstr "AVISO: Nós NÃO confiamos nesta chave!\n" msgid " The signature is probably a FORGERY.\n" msgstr " A assinatura é provavelmente uma FALSIFICAÇÃO.\n" -#, fuzzy, c-format -#| msgid "" -#| "WARNING: This key is not certified with sufficiently trusted signatures!\n" +#, c-format msgid "" "WARNING: The key's User ID is not certified with sufficiently trusted " "signatures!\n" msgstr "" -"AVISO: Esta chave não está certificada com assinaturas suficientemente\n" -" confiáveis!\n" +"AVISO: A ID de utilizador da chave não é certificada com assinaturas " +"suficientemente confiáveis!\n" #, c-format msgid "" "WARNING: This key is not certified with sufficiently trusted signatures!\n" msgstr "" -"AVISO: Esta chave não está certificada com assinaturas suficientemente\n" -" confiáveis!\n" +"AVISO: Esta chave não está certificada com assinaturas suficientemente " +"confiáveis!\n" #, c-format msgid " It is not certain that the signature belongs to the owner.\n" -msgstr " Não se tem certeza de que a assinatura pertence ao dono.\n" +msgstr " Não há certeza que a assinatura pertença ao dono.\n" #, c-format msgid "%s: skipped: %s\n" -msgstr "%s: ignorado: %s\n" +msgstr "%s: ignorada: %s\n" #, c-format msgid "%s: skipped: public key is disabled\n" -msgstr "%s: ignorado: a chave pública está desactivada\n" +msgstr "%s: ignorada: a chave pública está desabilitada\n" #, c-format msgid "%s: skipped: public key already present\n" -msgstr "%s: ignorado: a chave pública já está presente\n" +msgstr "%s: ignorada: a chave pública já está presente\n" -#, fuzzy, c-format -#| msgid "can't connect to `%s': %s\n" +#, c-format msgid "can't encrypt to '%s'\n" -msgstr "impossível ligar a `%s': %s\n" +msgstr "não é possível cifrar para '%s'\n" -#, fuzzy, c-format +#, c-format msgid "option '%s' given, but no valid default keys given\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "opção '%s' dada, mas nenhuma chave pré-definida válida dada\n" -#, fuzzy, c-format +#, c-format msgid "option '%s' given, but option '%s' not given\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "opção '%s' dada, mas opção '%s' não foi dada\n" msgid "You did not specify a user ID. (you may use \"-r\")\n" -msgstr "Não especificou um identificador de utilizador. (pode usar \"-r\")\n" +msgstr "Não especificou uma ID de utilizador. (pode usar \"-r\")\n" msgid "Current recipients:\n" -msgstr "" +msgstr "Destinatários atuais:\n" msgid "" "\n" "Enter the user ID. End with an empty line: " msgstr "" "\n" -"Insira o identificador do utilizador. Termine com uma linha vazia: " +"Introduzir a ID do utilizador. Terminar com uma linha vazia: " msgid "No such user ID.\n" -msgstr "Identificador de utilizador inexistente.\n" +msgstr "Não existe tal ID de utilizador.\n" #, c-format msgid "skipped: public key already set as default recipient\n" -msgstr "ignorado: chave pública já colocada como destinatário por omissão\n" +msgstr "ignorada: chave pública já definida como destinatário pré-definido\n" msgid "Public key is disabled.\n" -msgstr "A chave pública está desativada.\n" +msgstr "A chave pública está desabilitada.\n" #, c-format msgid "skipped: public key already set\n" -msgstr "ignorado: a chave pública já está presente\n" +msgstr "ignorada: a chave pública já está presente\n" -#, fuzzy, c-format +#, c-format msgid "unknown default recipient \"%s\"\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "destinatário pré-definido \"%s\" desconhecido\n" #, c-format msgid "no valid addressees\n" -msgstr "nenhum endereço válido\n" +msgstr "nenhum destinatário válido\n" -#, fuzzy, c-format +#, c-format msgid "Note: key %s has no %s feature\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "Nota: a chave %s não tem a característica %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: key %s has no preference for %s\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "Nota: a chave %s não tem preferência por %s\n" #, c-format msgid "data not saved; use option \"--output\" to save it\n" msgstr "dados não gravados; use a opção \"--output\" para gravá-los\n" msgid "Detached signature.\n" -msgstr "Assinatura separada.\n" +msgstr "Assinatura desanexada.\n" msgid "Please enter name of data file: " -msgstr "Por favor digite o nome do ficheiro de dados: " +msgstr "Introduza o nome do ficheiro de dados: " #, c-format msgid "reading stdin ...\n" -msgstr "lendo do \"stdin\" ...\n" +msgstr "lendo do stdin ...\n" #, c-format msgid "no signed data\n" -msgstr "não há dados assinados\n" +msgstr "sem dados assinados\n" -#, fuzzy, c-format -#| msgid "can't open signed data `%s'\n" +#, c-format msgid "can't open signed data '%s'\n" -msgstr "impossível abrir dados assinados `%s'\n" +msgstr "não é possível abrir dados assinados '%s'\n" -#, fuzzy, c-format +#, c-format msgid "can't open signed data fd=%d: %s\n" -msgstr "impossível abrir dados assinados `%s'\n" +msgstr "não é possível abrir dados assinados fd=%d: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s is not suitable for decryption in %s mode\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "a chave %s não é adequada para decifração no modo %s\n" -#, fuzzy, c-format +#, c-format msgid "anonymous recipient; trying secret key %s ...\n" -msgstr "destinatário anónimo; a tentar chave secreta %08lX ...\n" +msgstr "destinatário anónimo; tentando chave secreta %s ...\n" -#, fuzzy, c-format +#, c-format msgid "used key is not marked for encryption use.\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "a chave usada não está marcada para uso de cifração.\n" #, c-format msgid "okay, we are the anonymous recipient.\n" -msgstr "certo, nós somos o destinatário anónimo.\n" +msgstr "ok, nós somos o destinatário anónimo.\n" #, c-format msgid "old encoding of the DEK is not supported\n" @@ -5754,68 +5518,67 @@ msgstr "codificação antiga do DEK não suportada\n" #, c-format msgid "cipher algorithm %d%s is unknown or disabled\n" -msgstr "algoritmo de cifra %d%s é desconhecido ou foi desactivado\n" +msgstr "o algoritmo de cifra %d%s é desconhecido ou foi desabilitado\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: cipher algorithm %s not found in recipient preferences\n" -msgstr "NOTA: algoritmo de cifragem %d não encontrado nas preferências\n" +msgstr "" +"AVISO: o algoritmo de cifra %s não foi encontrado nas preferências do " +"destinatário\n" -#, fuzzy, c-format +#, c-format msgid "Note: secret key %s expired at %s\n" -msgstr "NOTA: chave secreta %08lX expirou em %s\n" +msgstr "Nota: a chave secreta %s expirou em %s\n" -#, fuzzy, c-format -#| msgid "NOTE: key has been revoked" +#, c-format msgid "Note: key has been revoked" -msgstr "NOTA: a chave foi revogada" +msgstr "Nota: a chave foi revogada" -#, fuzzy, c-format +#, c-format msgid "build_packet failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "build_packet falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "key %s has no user IDs\n" -msgstr "chave %08lX: sem ID de utilizador\n" +msgstr "a chave %s não tem IDs de utilizador\n" msgid "To be revoked by:\n" -msgstr "" +msgstr "Para ser revogada por:\n" msgid "(This is a sensitive revocation key)\n" -msgstr "" +msgstr "(Esta é uma chave de revogação sensitiva)\n" -#, fuzzy -#| msgid "Secret key is available.\n" msgid "Secret key is not available.\n" -msgstr "Chave secreta disponível.\n" +msgstr "A chave secreta não está disponível.\n" -#, fuzzy msgid "Create a designated revocation certificate for this key? (y/N) " -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Criar um certificado de revogação designado para esta chave? (s/N) " msgid "ASCII armored output forced.\n" -msgstr "" +msgstr "Saída blindada ASCII forçada.\n" -#, fuzzy, c-format +#, c-format msgid "make_keysig_packet failed: %s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "make_keysig_packet falhou: %s\n" -#, fuzzy msgid "Revocation certificate created.\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "Certificado de revogação criado.\n" #, c-format msgid "no revocation keys found for \"%s\"\n" -msgstr "" +msgstr "Nenhuma chave de revogação encontrada para \"%s\"\n" -#, fuzzy msgid "This is a revocation certificate for the OpenPGP key:" -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Este é um certificado de revogação para a chave OpenPGP:" msgid "" "A revocation certificate is a kind of \"kill switch\" to publicly\n" "declare that a key shall not anymore be used. It is not possible\n" "to retract such a revocation certificate once it has been published." msgstr "" +"Um certificado de revogação é uma espécie de \"kill switch\" para\n" +"declarar publicamente que uma chave não deverá ser mais usada. Não\n" +"é possível retirar tal certificado de revogação depois de publicado." msgid "" "Use it to revoke this key in case of a compromise or loss of\n" @@ -5824,36 +5587,43 @@ msgid "" "a reason for the revocation. For details see the description of\n" "of the gpg command \"--generate-revocation\" in the GnuPG manual." msgstr "" +"Use-o para revogar esta chave caso seja comprometida ou em caso de\n" +"perda da chave secreta. No entanto, se a chave secreta ainda for\n" +"acessível, é melhor gerar um novo certificado de revogação e dar um\n" +"motivo para a revogação. Para obter detalhes, consulte a descrição do\n" +"comando gpg \"--generate-revocation\" no manual do GnuPG." msgid "" "To avoid an accidental use of this file, a colon has been inserted\n" "before the 5 dashes below. Remove this colon with a text editor\n" "before importing and publishing this revocation certificate." msgstr "" +"Para evitar o uso acidental deste ficheiro, 'dois pontos' foram\n" +"inseridos antes dos 5 traços abaixo. Remova estes 'dois pontos' com\n" +"um editor de texto antes de importar e publicar este certificado de\n" +"revogação." -#, fuzzy, c-format +#, c-format msgid "revocation certificate stored as '%s.rev'\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado de revogação armazenado como '%s.rev'\n" -#, fuzzy, c-format +#, c-format msgid "secret key \"%s\" not found\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "chave secreta \"%s\" não encontrada\n" #. TRANSLATORS: The %s prints a key specification which #. for example has been given at the command line. Several lines #. lines with secret key infos are printed after this message. #, c-format msgid "'%s' matches multiple secret keys:\n" -msgstr "" +msgstr "'%s' corresponde a várias chaves secretas:\n" -#, fuzzy, c-format -#| msgid "error creating keyring `%s': %s\n" +#, c-format msgid "error searching the keyring: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao pesquisar o porta-chaves: %s\n" -#, fuzzy msgid "Create a revocation certificate for this key? (y/N) " -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Criar um certificado de revogação para esta chave? (s/N) " msgid "" "Revocation certificate created.\n" @@ -5864,34 +5634,37 @@ msgid "" "your media become unreadable. But have some caution: The print system of\n" "your machine might store the data and make it available to others!\n" msgstr "" +"Certificado de revogação criado.\n" +"\n" +"Mova-o para um sítio em que você o possa esconder; se Mallory tiver\n" +"acesso a este certificado, ele poderá usá-lo para tornar sua chave\n" +"inutilizável. É inteligente imprimir este certificado e guardá-lo,\n" +"caso se torne ilegível em seu dispositivo. Mas tenha algum cuidado: o\n" +"sistema de impressão da sua máquina pode armazenar os dados e\n" +"disponibilizá-los para outras pessoas!\n" -#, fuzzy msgid "Please select the reason for the revocation:\n" -msgstr "motivo da revocação: " +msgstr "Selecione o motivo da revogação:\n" msgid "Cancel" -msgstr "" +msgstr "Cancelar" #, c-format msgid "(Probably you want to select %d here)\n" -msgstr "" +msgstr "(Provavelmente aqui você desejará selecionar %d)\n" -#, fuzzy msgid "Enter an optional description; end it with an empty line:\n" -msgstr "" -"\n" -"Insira o identificador do utilizador. Termine com uma linha vazia: " +msgstr "Introduzir uma descrição opcional; finalize com uma linha vazia:\n" -#, fuzzy, c-format +#, c-format msgid "Reason for revocation: %s\n" -msgstr "motivo da revocação: " +msgstr "Motivo da revogação: %s\n" msgid "(No description given)\n" -msgstr "" +msgstr "(Nenhuma descrição dada)\n" -#, fuzzy msgid "Is this okay? (y/N) " -msgstr "Usar esta chave de qualquer modo? " +msgstr "Isto está ok? (s/N) " #, c-format msgid "weak key created - retrying\n" @@ -5900,233 +5673,227 @@ msgstr "chave fraca criada - tentando novamente\n" #, c-format msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n" msgstr "" -"impossível evitar chave fraca para criptografia simétrica;\n" -"tentei %d vezes!\n" +"não pude evitar a chave fraca para a cifra simétrica; tentei %d vezes!\n" #, c-format msgid "%s key %s uses an unsafe (%zu bit) hash\n" -msgstr "" +msgstr "chave %s %s usa um hash não seguro (%zu bit)\n" #, c-format msgid "%s key %s requires a %zu bit or larger hash (hash is %s)\n" -msgstr "" +msgstr "chave %s %s requer um hash %zu bit ou maior (hash é %s)\n" -#, fuzzy, c-format -#| msgid "you may not use %s while in %s mode\n" +#, c-format msgid "key %s may not be used for signing in %s mode\n" -msgstr "não pode utilizar %s enquanto estiver no modo %s\n" +msgstr "A chave %s não pode ser usada para assinar no modo %s\n" #, c-format msgid "WARNING: signature digest conflict in message\n" -msgstr "AVISO: conflito no 'digest' de assinatura da mensagem\n" +msgstr "AVISO: conflito no digest de assinatura na mensagem\n" #, c-format msgid "WARNING: signing subkey %s is not cross-certified\n" -msgstr "" +msgstr "AVISO: a subchave de assinatura %s não é cruzadamente certificada\n" -#, fuzzy, c-format +#, c-format msgid "please see %s for more information\n" -msgstr " i = mostrar mais informações\n" +msgstr "consulte %s para mais informações\n" -#, fuzzy, c-format +#, c-format msgid "WARNING: signing subkey %s has an invalid cross-certification\n" -msgstr "não pode escolher uma chave como revogadora de si mesmo\n" +msgstr "" +"AVISO: a subchave de assinatura %s tem uma certificação cruzada inválida\n" -#, fuzzy, c-format +#, c-format msgid "public key %s is %lu second newer than the signature\n" msgid_plural "public key %s is %lu seconds newer than the signature\n" -msgstr[0] "a chave pública %08lX é %lu segundo mais nova que a assinatura\n" -msgstr[1] "a chave pública %08lX é %lu segundo mais nova que a assinatura\n" +msgstr[0] "a chave pública %s é %lu segundo mais recente que a assinatura\n" +msgstr[1] "a chave pública %s é %lu segundos mais recente que a assinatura\n" -#, fuzzy, c-format +#, c-format msgid "public key %s is %lu day newer than the signature\n" msgid_plural "public key %s is %lu days newer than the signature\n" -msgstr[0] "a chave pública %08lX é %lu segundo mais nova que a assinatura\n" -msgstr[1] "a chave pública %08lX é %lu segundo mais nova que a assinatura\n" +msgstr[0] "a chave pública %s é %lu dia mais recente que a assinatura\n" +msgstr[1] "a chave pública %s é %lu dias mais recente que a assinatura\n" -#, fuzzy, c-format +#, c-format msgid "" "key %s was created %lu second in the future (time warp or clock problem)\n" msgid_plural "" "key %s was created %lu seconds in the future (time warp or clock problem)\n" msgstr[0] "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"a chave %s foi criada %lu segundo no futuro (deformação temporal ou problema " +"de relógio)\n" msgstr[1] "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"a chave %s foi criada %lu segundos no futuro (deformação temporal ou " +"problema de relógio)\n" -#, fuzzy, c-format +#, c-format msgid "key %s was created %lu day in the future (time warp or clock problem)\n" msgid_plural "" "key %s was created %lu days in the future (time warp or clock problem)\n" msgstr[0] "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"a chave %s foi criada %lu dia no futuro (deformação temporal ou problema de " +"relógio)\n" msgstr[1] "" -"a chave foi criada %lu segundo no futuro\n" -"(viagem no tempo ou problema no relógio)\n" +"a chave %s foi criada %lu dias no futuro (deformação temporal ou problema de " +"relógio)\n" -#, fuzzy, c-format +#, c-format msgid "Note: signature key %s expired %s\n" -msgstr "NOTA: chave de assinatura %08lx expirou %s\n" +msgstr "Nota: a chave de assinatura %s expirou em %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: signature key %s has been revoked\n" -msgstr "NOTA: a chave foi revogada" +msgstr "Nota: a chave de assinatura %s foi revogada\n" -#, fuzzy, c-format -#| msgid "standalone signature of class 0x%02x\n" +#, c-format msgid "bad key signature from key %s: %s (0x%02x, 0x%x)\n" -msgstr "assinatura de classe 0x%02x\n" +msgstr "assinatura de chave inválida da chave %s: %s (0x%02x, 0x%x)\n" -#, fuzzy, c-format -#| msgid "standalone signature of class 0x%02x\n" +#, c-format msgid "bad data signature from key %s: %s (0x%02x, 0x%x)\n" -msgstr "assinatura de classe 0x%02x\n" +msgstr "assinatura de dados inválida da chave %s: %s (0x%02x, 0x%x)\n" -#, fuzzy, c-format +#, c-format msgid "assuming bad signature from key %s due to an unknown critical bit\n" msgstr "" -"assumindo assinatura incorrecta na chave %08lX devido a um bit crítico " +"assumindo assinatura inválida da chave %s devido a um bit crítico " "desconhecido\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no subkey for subkey revocation signature\n" -msgstr "chave %08lX: sem subchave para o pacote revocação de subchave\n" +msgstr "chave %s: nenhuma subchave para assinatura de revogação de subchave\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no subkey for subkey binding signature\n" -msgstr "chave %08lX: sem subchave para ligação de chaves\n" +msgstr "chave %s: nenhuma subchave para assinatura de vinculação de subchave\n" #, c-format msgid "WARNING: unable to %%-expand notation (too large). Using unexpanded.\n" msgstr "" -"AVISO: impossível expandir-%% a url de política (demasiado grande). A " -"utilizar não expandida.\n" +"AVISO: não é possível expandir-%% a notação (demasiado grande). Usando não " +"expandida.\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: unable to %%-expand policy URL (too large). Using unexpanded.\n" msgstr "" -"AVISO: impossível expandir-%% a url de política (demasiado grande).\n" -"A utilizar não expandida.\n" +"AVISO: não é possível %%-expandir a URL da política (muito grande). Usando " +"não expandida.\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: unable to %%-expand preferred keyserver URL (too large). Using " "unexpanded.\n" msgstr "" -"AVISO: impossível expandir-%% a url de política (demasiado grande).\n" -"A utilizar não expandida.\n" +"AVISO: não é possível %%-expandir a URL do servidor de chaves preferencial " +"(muito grande). Usando não expandida.\n" -#, fuzzy, c-format +#, c-format msgid "%s/%s signature from: \"%s\"\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "assinatura %s/%s de: \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "" "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n" msgstr "" -"forçar o algoritmo de 'digest' %s (%d) viola as preferências do " +"AVISO: forçar o algoritmo de digest %s (%d) viola as preferências do " "destinatário\n" #, c-format msgid "signing:" -msgstr "a assinar:" +msgstr "assinando:" -#, fuzzy, c-format -#| msgid "%s encryption will be used\n" +#, c-format msgid "%s.%s encryption will be used\n" -msgstr "será utilizada a cifragem %s\n" +msgstr "a cifração %s.%s será usada\n" #, c-format msgid "key is not flagged as insecure - can't use it with the faked RNG!\n" msgstr "" -"a chave não está marcada insegura - impossível usá-la com o RNG falso!\n" +"chave não está marcada como insegura - não pode usá-la com o RNG " +"falsificado!\n" -#, fuzzy, c-format +#, c-format msgid "skipped \"%s\": duplicated\n" -msgstr "ignorado `%s': duplicada\n" +msgstr "ignorado \"%s\": duplicada\n" #, c-format msgid "skipped: secret key already present\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "ignorada: a chave secreta já está presente\n" -#, fuzzy msgid "this is a PGP generated Elgamal key which is not secure for signatures!" msgstr "" -"ignorado `%s': esta é uma chave ElGamal gerada pelo PGP que não é segura " -"para assinaturas!\n" +"esta é uma chave Elgamal gerada por PGP que não é segura para assinaturas!" #, c-format msgid "trust record %lu, type %d: write failed: %s\n" -msgstr "registo de confiança %lu, tipo %d: escrita falhou: %s\n" +msgstr "registo da confiança %lu, tipo %d: falha ao escrever: %s\n" #, c-format msgid "" "# List of assigned trustvalues, created %s\n" "# (Use \"gpg --import-ownertrust\" to restore them)\n" msgstr "" +"# Lista de valores da confiança atribuídos, criado a %s\n" +"# (Usar \"gpg --import-ownertrust\" para restaurá-los)\n" -#, fuzzy, c-format +#, c-format msgid "error in '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro em '%s': %s\n" -#, fuzzy msgid "line too long" -msgstr "frase secreta demasiado longa\n" +msgstr "linha muito longa" msgid "colon missing" -msgstr "" +msgstr "'dois pontos' ausente" -#, fuzzy msgid "invalid fingerprint" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "impressão digital inválida" -#, fuzzy msgid "ownertrust value missing" -msgstr "importar os valores de confiança" +msgstr "valor ownertrust ausente" -#, fuzzy, c-format +#, c-format msgid "error finding trust record in '%s': %s\n" -msgstr "%s: erro ao escrever registo de diretório: %s\n" +msgstr "erro ao localizar registo da confiança em '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "read error in '%s': %s\n" -msgstr "armadura: %s\n" +msgstr "erro de leitura em '%s': %s\n" #, c-format msgid "trustdb: sync failed: %s\n" -msgstr "base de dados de confiança: sincronização falhou: %s\n" +msgstr "trustdb: falha na sincronização: %s\n" -#, fuzzy, c-format +#, c-format msgid "can't create lock for '%s'\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível criar bloqueio para '%s'\n" -#, fuzzy, c-format +#, c-format msgid "can't lock '%s'\n" -msgstr "impossível abrir `%s'\n" +msgstr "não é possível bloquear '%s'\n" #, c-format msgid "trustdb rec %lu: lseek failed: %s\n" -msgstr "base de dados de confiança rec %lu: lseek falhou: %s\n" +msgstr "registo trustdb %lu: falha no lseek: %s\n" #, c-format msgid "trustdb rec %lu: write failed (n=%d): %s\n" -msgstr "base de dados de confiança rec %lu: escrita falhou (n=%d): %s\n" +msgstr "registo trustdb %lu: falha ao escrever (n=%d): %s\n" #, c-format msgid "trustdb transaction too large\n" -msgstr "transação de base de dados de confiança muito grande\n" +msgstr "transação trustdb muito grande\n" #, c-format msgid "%s: directory does not exist!\n" -msgstr "%s: diretoria inexistente!\n" +msgstr "%s: pasta não existe!\n" -#, fuzzy, c-format +#, c-format msgid "can't access '%s': %s\n" -msgstr "impossível fechar `%s': %s\n" +msgstr "não é possível aceder '%s': %s\n" #, c-format msgid "%s: failed to create version record: %s" @@ -6134,28 +5901,27 @@ msgstr "%s: falha ao criar registo de versão: %s" #, c-format msgid "%s: invalid trustdb created\n" -msgstr "%s: base de dados de confiança inválida criada\n" +msgstr "%s: trustdb inválida criada\n" #, c-format msgid "%s: trustdb created\n" -msgstr "%s: base de dados de confiança criada\n" +msgstr "%s: trustdb criada\n" -#, fuzzy, c-format -#| msgid "NOTE: trustdb not writable\n" +#, c-format msgid "Note: trustdb not writable\n" -msgstr "NOTA: não é possível escrever na trustdb\n" +msgstr "Nota: trustdb sem permissão de escrita\n" #, c-format msgid "%s: invalid trustdb\n" -msgstr "%s: base de dados de confiança inválida\n" +msgstr "%s: trustdb inválida\n" #, c-format msgid "%s: failed to create hashtable: %s\n" -msgstr "%s: falha ao criar tabela de dispersão: %s\n" +msgstr "%s: falha ao criar hashtable: %s\n" #, c-format msgid "%s: error updating version record: %s\n" -msgstr "%s: erro a actualizar registo de versão: %s\n" +msgstr "%s: erro ao atualizar registo de versão: %s\n" #, c-format msgid "%s: error reading version record: %s\n" @@ -6167,15 +5933,15 @@ msgstr "%s: erro ao escrever registo de versão: %s\n" #, c-format msgid "trustdb: lseek failed: %s\n" -msgstr "base de dados de confiança: lseek falhou: %s\n" +msgstr "trustdb: falha no lseek: %s\n" #, c-format msgid "trustdb: read failed (n=%d): %s\n" -msgstr "base de dados de confiança: leitura falhou (n=%d): %s\n" +msgstr "trustdb: falha ao ler (n=%d): %s\n" #, c-format msgid "%s: not a trustdb file\n" -msgstr "%s: não é um base de dados de confiança\n" +msgstr "%s: não é um ficheiro trustdb\n" #, c-format msgid "%s: version record with recnum %lu\n" @@ -6191,7 +5957,7 @@ msgstr "%s: erro ao ler registo livre: %s\n" #, c-format msgid "%s: error writing dir record: %s\n" -msgstr "%s: erro ao escrever registo de diretório: %s\n" +msgstr "%s: erro ao escrever registo de pasta: %s\n" #, c-format msgid "%s: failed to zero a record: %s\n" @@ -6199,288 +5965,287 @@ msgstr "%s: falha ao zerar um registo: %s\n" #, c-format msgid "%s: failed to append a record: %s\n" -msgstr "%s: falha ao anexar um registo: %s\n" +msgstr "%s: falha ao acrescentar um registo: %s\n" -#, fuzzy, c-format +#, c-format msgid "Error: The trustdb is corrupted.\n" -msgstr "%s: base de dados de confiança criada\n" +msgstr "Erro: A trustdb está corrompida.\n" #, c-format msgid "can't handle text lines longer than %d characters\n" -msgstr "impossível manipular linhas de texto maiores que %d caracteres\n" +msgstr "não é possível lidar com linhas de texto maiores que %d caracteres\n" #, c-format msgid "input line longer than %d characters\n" msgstr "linha de entrada maior que %d caracteres\n" -#, fuzzy, c-format +#, c-format msgid "error beginning transaction on TOFU database: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao iniciar a transação na base de dados TOFU: %s\n" #, c-format msgid "error committing transaction on TOFU database: %s\n" -msgstr "" +msgstr "erro ao confirmar transação na base de dados TOFU: %s\n" #, c-format msgid "error rolling back transaction on TOFU database: %s\n" -msgstr "" +msgstr "erro ao reverter transação na base de dados TOFU: %s\n" -#, fuzzy, c-format +#, c-format msgid "unsupported TOFU database version: %s\n" -msgstr "" -"\n" -"Algoritmos suportados:\n" +msgstr "versão da base de dados TOFU sem suporte: %s\n" #, c-format msgid "TOFU DB error" -msgstr "" +msgstr "erro na base de dados TOFU" -#, fuzzy, c-format +#, c-format msgid "error reading TOFU database: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao ler a base de dados TOFU: %s\n" -#, fuzzy, c-format -#| msgid "error writing secret keyring `%s': %s\n" +#, c-format msgid "error determining TOFU database's version: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao determinar a versão da base de dados TOFU: %s\n" -#, fuzzy, c-format -#| msgid "%s: error writing dir record: %s\n" +#, c-format msgid "error initializing TOFU database: %s\n" -msgstr "%s: erro ao escrever registo de diretório: %s\n" +msgstr "erro ao inicializar a base de dados TOFU: %s\n" -#, fuzzy, c-format +#, c-format msgid "error opening TOFU database '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao abrir a base de dados TOFU '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error updating TOFU database: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao atualizar a base de dados TOFU: %s\n" #, c-format msgid "" "This is the first time the email address \"%s\" is being used with key %s." msgstr "" +"Esta é a primeira vez que o endereço de email \"%s\" está a ser usado com a " +"chave %s." #, c-format msgid "The email address \"%s\" is associated with %d key!" msgid_plural "The email address \"%s\" is associated with %d keys!" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "O endereço de email \"%s\" está associado a %d chave!" +msgstr[1] "O endereço de email \"%s\" está associado a %d chaves!" msgid " Since this binding's policy was 'auto', it has been changed to 'ask'." msgstr "" +" Como a política desta vinculação era 'auto', foi alterada para 'ask'." #, c-format msgid "" "Please indicate whether this email address should be associated with key %s " "or whether you think someone is impersonating \"%s\"." msgstr "" +"Indique se este endereço de email deve ser associado à chave %s ou se acha " +"que alguém está a fazer-se passar por \"%s\"." -#, fuzzy, c-format +#, c-format msgid "error gathering other user IDs: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao colecionar outros IDs de utilizador: %s\n" -#, fuzzy -#| msgid "list key and user IDs" msgid "This key's user IDs:\n" -msgstr "lista chave e identificadores de utilizadores" +msgstr "IDs de utilizador desta chave:\n" -#, fuzzy, c-format -#| msgid "Policy: " +#, c-format msgid "policy: %s" -msgstr "Política: " +msgstr "política: %s" -#, fuzzy, c-format +#, c-format msgid "error gathering signature stats: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao colecionar estatísticas de assinatura: %s\n" #, c-format msgid "The email address \"%s\" is associated with %d key:\n" msgid_plural "The email address \"%s\" is associated with %d keys:\n" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "O endereço de email \"%s\" está associado à chave %d:\n" +msgstr[1] "O endereço de email \"%s\" está associado às chaves %d:\n" #, c-format msgid "Statistics for keys with the email address \"%s\":\n" -msgstr "" +msgstr "Estatísticas para chaves com o endereço de email \"%s\":\n" -#, fuzzy -#| msgid "list keys" msgid "this key" -msgstr "listar as chaves" +msgstr "esta chave" -#, fuzzy, c-format +#, c-format msgid "Verified %d message." msgid_plural "Verified %d messages." -msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr[0] "Verifiquei %d mensagem." +msgstr[1] "Verifiquei %d mensagens." -#, fuzzy, c-format +#, c-format msgid "Encrypted %d message." msgid_plural "Encrypted %d messages." -msgstr[0] "Repita a frase secreta\n" -msgstr[1] "Repita a frase secreta\n" +msgstr[0] "Cifrei %d mensagem." +msgstr[1] "Cifrei %d mensagens." -#, fuzzy, c-format +#, c-format msgid "Verified %d message in the future." msgid_plural "Verified %d messages in the future." -msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr[0] "Verifiquei %d mensagem no futuro." +msgstr[1] "Verifiquei %d mensagens no futuro." -#, fuzzy, c-format +#, c-format msgid "Encrypted %d message in the future." msgid_plural "Encrypted %d messages in the future." -msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr[0] "Cifrei %d mensagem no futuro." +msgstr[1] "Cifrei %d mensagens no futuro." #, c-format msgid "Messages verified over the past %d day: %d." msgid_plural "Messages verified over the past %d days: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens verificadas no último %d dia: %d." +msgstr[1] "Mensagens verificadas nos últimos %d dias: %d." #, c-format msgid "Messages encrypted over the past %d day: %d." msgid_plural "Messages encrypted over the past %d days: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens cifradas no último %d dia: %d." +msgstr[1] "Mensagens cifradas nos últimos %d dias: %d." #, c-format msgid "Messages verified over the past %d month: %d." msgid_plural "Messages verified over the past %d months: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens verificadas no último %d mês: %d." +msgstr[1] "Mensagens verificadas nos últimos %d meses: %d." #, c-format msgid "Messages encrypted over the past %d month: %d." msgid_plural "Messages encrypted over the past %d months: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens cifradas no último %d mês: %d." +msgstr[1] "Mensagens cifradas nos últimos %d meses: %d." #, c-format msgid "Messages verified over the past %d year: %d." msgid_plural "Messages verified over the past %d years: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens verificadas no último %d ano: %d." +msgstr[1] "Mensagens verificadas nos últimos %d anos: %d." #, c-format msgid "Messages encrypted over the past %d year: %d." msgid_plural "Messages encrypted over the past %d years: %d." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Mensagens cifradas no último %d ano: %d." +msgstr[1] "Mensagens cifradas nos últimos %d anos: %d." #, c-format msgid "Messages verified in the past: %d." -msgstr "" +msgstr "Mensagens verificadas no passado: %d." -#, fuzzy, c-format +#, c-format msgid "Messages encrypted in the past: %d." -msgstr "|algo [ficheiros]|imprimir \"digests\" de mensagens" +msgstr "Mensagens cifradas no passado: %d." #. TRANSLATORS: Please translate the text found in the source #. * file below. We don't directly internationalize that text so #. * that we can tweak it without breaking translations. msgid "TOFU detected a binding conflict" -msgstr "" +msgstr "O TOFU detetou um conflito de vinculação" #. TRANSLATORS: Two letters (normally the lower and upper case #. * version of the hotkey) for each of the five choices. If #. * there is only one choice in your language, repeat it. msgid "gGaAuUrRbB" -msgstr "" +msgstr "cCaAdDrRiI" msgid "(G)ood, (A)ccept once, (U)nknown, (R)eject once, (B)ad? " msgstr "" +"(C)orreta, (A)ceitar uma vez, (D)esconhecida, (R)ejeitar uma vez, " +"(I)ncorreta? " msgid "Defaulting to unknown.\n" -msgstr "" +msgstr "Pré-definindo como desconhecido.\n" #, c-format msgid "TOFU db corruption detected.\n" -msgstr "" +msgstr "corrupção de base de dados TOFU detetada.\n" -#, fuzzy, c-format +#, c-format msgid "error changing TOFU policy: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao alterar a política de TOFU: %s\n" #, c-format msgid "%lld~year" msgid_plural "%lld~years" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~ano" +msgstr[1] "%lld~anos" #, c-format msgid "%lld~month" msgid_plural "%lld~months" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~mês" +msgstr[1] "%lld~meses" #, c-format msgid "%lld~week" msgid_plural "%lld~weeks" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~semana" +msgstr[1] "%lld~semanas" #, c-format msgid "%lld~day" msgid_plural "%lld~days" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~dia" +msgstr[1] "%lld~dias" #, c-format msgid "%lld~hour" msgid_plural "%lld~hours" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~hora" +msgstr[1] "%lld~horas" #, c-format msgid "%lld~minute" msgid_plural "%lld~minutes" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~minuto" +msgstr[1] "%lld~minutos" #, c-format msgid "%lld~second" msgid_plural "%lld~seconds" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%lld~segundo" +msgstr[1] "%lld~segundos" #, c-format msgid "%s: Verified 0~signatures and encrypted 0~messages." -msgstr "" +msgstr "%s: 0~assinaturas verificadas e 0~mensagens cifradas." -#, fuzzy, c-format -#| msgid "Deleted %d signatures.\n" +#, c-format msgid "%s: Verified 0 signatures." -msgstr "%d assinaturas removidas.\n" +msgstr "%s: Verificado 0 assinaturas." -#, fuzzy msgid "Encrypted 0 messages." -msgstr "Repita a frase secreta\n" +msgstr "Cifrado 0 mensagens." -#, fuzzy, c-format -#| msgid "Policy: " +#, c-format msgid "(policy: %s)" -msgstr "Política: " +msgstr "(política: %s)" #, c-format msgid "" "Warning: we have yet to see a message signed using this key and user id!\n" msgstr "" +"Atenção: ainda não vimos uma mensagem assinada com esta chave e ID de " +"utilizador!\n" #, c-format msgid "" "Warning: we've only seen one message signed using this key and user id!\n" msgstr "" +"Atenção: apenas vimos uma mensagem assinada com esta chave e ID de " +"utilizador!\n" #, c-format msgid "Warning: you have yet to encrypt a message to this key!\n" -msgstr "" +msgstr "Atenção: você ainda não cifrou uma mensagem para esta chave!\n" #, c-format msgid "Warning: you have only encrypted one message to this key!\n" -msgstr "" +msgstr "Atenção: você apenas cifrou uma mensagem para esta chave!\n" #, c-format msgid "" @@ -6496,136 +6261,153 @@ msgid_plural "" " %s\n" "to mark it as being bad.\n" msgstr[0] "" +"Atenção: se acha que viu mais assinaturas feitas por esta chave e este ID de " +"utilizador, então esta chave pode ser uma falsificação! Examine " +"cuidadosamente o endereço de email à procura de de pequenas variações. Se a " +"chave for suspeita, use\n" +" %s\n" +"para marcá-la como sendo inválida.\n" msgstr[1] "" +"Atenção: se acha que viu mais assinaturas feitas por esta chave e estes IDs " +"de utilizador, então esta chave pode ser uma falsificação! Examine " +"cuidadosamente os endereços de email à procura de de pequenas variações. Se " +"a chave for suspeita, use\n" +" %s\n" +"para marcá-la como sendo inválida.\n" -#, fuzzy, c-format +#, c-format msgid "error opening TOFU database: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao abrir a base de dados TOFU: %s\n" #, c-format msgid "WARNING: Encrypting to %s, which has no non-revoked user ids\n" -msgstr "" +msgstr "AVISO: Cifrando para %s, que não tem ids de utilizador não revogados\n" -#, fuzzy, c-format -#| msgid "`%s' is not a valid long keyID\n" +#, c-format msgid "'%s' is not a valid long keyID\n" -msgstr "`%s' não é um identificador longo de chave válido\n" +msgstr "'%s' não é um keyID longo válido\n" -#, fuzzy, c-format +#, c-format msgid "key %s: accepted as trusted key\n" -msgstr "chave %08lX: aceite como chave de confiança\n" +msgstr "chave %s: aceite como chave confiável\n" -#, fuzzy, c-format +#, c-format msgid "key %s occurs more than once in the trustdb\n" -msgstr "chave %08lX ocrreu mais do que uma vez na base de dados de confiança\n" +msgstr "a chave %s ocorre mais de uma vez na trustdb\n" -#, fuzzy, c-format +#, c-format msgid "key %s: no public key for trusted key - skipped\n" -msgstr "" -"chave %08lX: nenhuma chave pública para chave de confiança - ignorada\n" -"\n" +msgstr "chave %s: nenhuma chave pública para a chave confiável - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "key %s marked as ultimately trusted\n" -msgstr "chave marcada como de confiança absoluta\n" +msgstr "chave %s marcada como plenamente confiável\n" #, c-format msgid "trust record %lu, req type %d: read failed: %s\n" -msgstr "registo de confiança %lu, tipo req %d: falha na leitura: %s\n" +msgstr "registo da confiança %lu, tipo pedido %d: falha na leitura: %s\n" #, c-format msgid "trust record %lu is not of requested type %d\n" -msgstr "registo de confiança %lu não é do tipo pedido %d\n" +msgstr "registo da confiança %lu não é do tipo %d pedido\n" #, c-format msgid "You may try to re-create the trustdb using the commands:\n" -msgstr "" +msgstr "Você pode tentar recriar a trustdb usando os comandos:\n" #, c-format msgid "If that does not work, please consult the manual\n" -msgstr "" +msgstr "Se isso não funcionar, consulte o manual\n" #, c-format msgid "unable to use unknown trust model (%d) - assuming %s trust model\n" msgstr "" +"não é possível usar modelo da confiança desconhecido (%d) - assumindo o " +"modelo da confiança %s\n" #, c-format msgid "using %s trust model\n" -msgstr "" +msgstr "usando o modelo da confiança %s\n" #, c-format msgid "no need for a trustdb check\n" -msgstr "não é necessária uma verificação da base de dados de confiança\n" +msgstr "não há necessidade de uma verificação da trustdb\n" #, c-format msgid "next trustdb check due at %s\n" -msgstr "proxima verificação da base de dados de confiança a %s\n" +msgstr "próxima verificação da trustdb a %s\n" -#, fuzzy, c-format +#, c-format msgid "no need for a trustdb check with '%s' trust model\n" -msgstr "não é necessária uma verificação da base de dados de confiança\n" +msgstr "" +"não há necessidade de uma verificação da trustdb, com o modelo da confiança " +"'%s'\n" -#, fuzzy, c-format +#, c-format msgid "no need for a trustdb update with '%s' trust model\n" -msgstr "não é necessária uma verificação da base de dados de confiança\n" +msgstr "" +"não há necessidade de uma atualização da trustdb, com o modelo da confiança " +"'%s'\n" -#, fuzzy, c-format +#, c-format msgid "public key %s not found: %s\n" -msgstr "chave pública %08lX não encontrada: %s\n" +msgstr "chave pública %s não encontrada: %s\n" #, c-format msgid "please do a --check-trustdb\n" -msgstr "" +msgstr "faça uma --check-trustdb\n" #, c-format msgid "checking the trustdb\n" -msgstr "a verificar a base de dados de confiança\n" +msgstr "verificando a trustdb\n" -#, fuzzy, c-format +#, c-format msgid "%d key processed" msgid_plural "%d keys processed" -msgstr[0] "%lu chaves processadas até agora\n" -msgstr[1] "%lu chaves processadas até agora\n" +msgstr[0] "%d chave processada" +msgstr[1] "%d chaves processadas" #, c-format msgid " (%d validity count cleared)\n" msgid_plural " (%d validity counts cleared)\n" -msgstr[0] "" -msgstr[1] "" +msgstr[0] " (%d contagem da validade limpa)\n" +msgstr[1] " (%d contagens das validades limpas)\n" -#, fuzzy, c-format +#, c-format msgid "no ultimately trusted keys found\n" -msgstr "" -"chave pública da chave absolutamente de confiança %08lX não encontrada\n" +msgstr "nenhumas chaves plenamente confiáveis encontradas\n" -#, fuzzy, c-format +#, c-format msgid "public key of ultimately trusted key %s not found\n" -msgstr "" -"chave pública da chave absolutamente de confiança %08lX não encontrada\n" +msgstr "chave pública da chave plenamente confiável %s não encontrada\n" #, c-format msgid "" "depth: %d valid: %3d signed: %3d trust: %d-, %dq, %dn, %dm, %df, %du\n" msgstr "" +"profundidade: %d válidas: %3d assinadas: %3d confiáveis: %d-, %di, %dn, %dm, " +"%dc, %dp\n" -#, fuzzy, c-format +#, c-format msgid "unable to update trustdb version record: write failed: %s\n" -msgstr "registo de confiança %lu, tipo %d: escrita falhou: %s\n" +msgstr "" +"não é possível atualizar o registo de versão da trustdb: falha ao escrever: " +"%s\n" msgid "undefined" -msgstr "" +msgstr "indefinida" msgid "never" -msgstr "" +msgstr "nunca" msgid "marginal" -msgstr "" +msgstr "marginal" msgid "full" -msgstr "" +msgstr "completa" msgid "ultimate" -msgstr "" +msgstr "plena" #. TRANSLATORS: these strings are similar to those in #. trust_value_to_string(), but are a fixed length. This is needed to @@ -6636,34 +6418,31 @@ msgstr "" #. essentially a comment and need not be translated. Either key and #. uid are both NULL, or neither are NULL. msgid "10 translator see trust.c:uid_trust_string_fixed" -msgstr "" +msgstr "12 translator see trust.c:uid_trust_string_fixed" -#, fuzzy msgid "[ revoked]" -msgstr "revkey" +msgstr "[ revogada ]" -#, fuzzy msgid "[ expired]" -msgstr "expire" +msgstr "[ expirada ]" -#, fuzzy msgid "[ unknown]" -msgstr "versão desconhecida" +msgstr "[desconhec.]" msgid "[ undef ]" -msgstr "" +msgstr "[indefinida]" msgid "[ never ]" -msgstr "" +msgstr "[ nunca ]" msgid "[marginal]" -msgstr "" +msgstr "[ marginal ]" msgid "[ full ]" -msgstr "" +msgstr "[ completa ]" msgid "[ultimate]" -msgstr "" +msgstr "[ plena ]" #, c-format msgid "" @@ -6672,665 +6451,643 @@ msgid "" "should be the first file given on the command line.\n" msgstr "" "a assinatura não pode ser verificada.\n" -"Não se esqueça que o ficheiro com a assinatura (.sig ou .asc)\n" -"deve ser o primeiro a ser dado na linha de comando.\n" +"Lembre-se que o ficheiro com a assinatura (.sig ou .asc)\n" +"deve ser o primeiro ficheiro a ser dado na linha de comando.\n" #, c-format msgid "input line %u too long or missing LF\n" -msgstr "linha de entrada %u demasiado longa ou falta o LF\n" +msgstr "linha de entrada %u demasiado longa ou LF ausente\n" -#, fuzzy, c-format +#, c-format msgid "can't open fd %d: %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "não é possível abrir fd %d: %s\n" -#, fuzzy, c-format -#| msgid "WARNING: message was not integrity protected\n" +#, c-format msgid "WARNING: encrypting without integrity protection is dangerous\n" -msgstr "AVISO: a mensagem não tinha a sua integridade protegida\n" +msgstr "AVISO: cifrar sem proteção de integridade é perigoso\n" -#, fuzzy, c-format +#, c-format msgid "Hint: Do not use option %s\n" -msgstr "a ler opções de `%s'\n" +msgstr "Dica: Não use a opção %s\n" msgid "set debugging flags" -msgstr "" +msgstr "definindo flags de debug" msgid "enable full debugging" -msgstr "" +msgstr "habilitando debug completo" -#, fuzzy msgid "Usage: kbxutil [options] [files] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: kbxutil [opções] [ficheiros] (-h para ajuda)" -#, fuzzy msgid "" "Syntax: kbxutil [options] [files]\n" "List, export, import Keybox data\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "" +"Sintaxe: kbxutil [opções] [ficheiros]\n" +"Listar, exportar, importar dados da Keybox\n" #. TRANSLATORS: Put a \x1f right before a colon. This can be #. * used by pinentry to nicely align the names and values. Keep #. * the %s at the start and end of the string. #, c-format msgid "%sNumber: %s%%0AHolder: %s%s" -msgstr "" +msgstr "%sNúmero: %s%%0ATitular: %s%s" #. TRANSLATORS: This is the number of remaining attempts to #. * enter a PIN. Use %%0A (double-percent,0A) for a linefeed. #, c-format msgid "Remaining attempts: %d" -msgstr "" +msgstr "Tentativas restantes: %d" -#, fuzzy msgid "|N|Please enter the new Global-PIN" -msgstr "muda a frase secreta" +msgstr "|N|Introduza o novo Global-PIN" -#, fuzzy msgid "||Please enter the Global-PIN of your PIV card" -msgstr "motivo da revocação: " +msgstr "||Introduza o Global-PIN do seu cartão PIV" -#, fuzzy msgid "|N|Please enter the new PIN" -msgstr "muda a frase secreta" +msgstr "|N|Introduza o novo PIN" -#, fuzzy msgid "||Please enter the PIN of your PIV card" -msgstr "motivo da revocação: " +msgstr "||Introduza o PIN do seu cartão PIV" -#, fuzzy msgid "|N|Please enter the new Unblocking Key" -msgstr "muda a frase secreta" +msgstr "|N|Introduza a nova Unblocking Key" -#, fuzzy msgid "||Please enter the Unblocking Key of your PIV card" -msgstr "motivo da revocação: " +msgstr "||Introduza a Unblocking Key do seu cartão PIV" #, c-format msgid "PIN callback returned error: %s\n" -msgstr "" +msgstr "callback de PIN retornou erro: %s\n" #, c-format msgid "PIN is too short; minimum length is %d\n" -msgstr "" +msgstr "O PIN é muito curto; o comprimento mínimo é %d\n" #, c-format msgid "PIN is too long; maximum length is %d\n" -msgstr "" +msgstr "O PIN é muito longo; o comprimento máximo é %d\n" #, c-format msgid "PIN has invalid characters; only digits are allowed\n" -msgstr "" +msgstr "O PIN tem caracteres inválidos; apenas dígitos são permitidos\n" -#, fuzzy, c-format +#, c-format msgid "key already exists\n" -msgstr "%s' já comprimido\n" +msgstr "chave já existe\n" #, c-format msgid "existing key will be replaced\n" -msgstr "" +msgstr "a chave existente será substituída\n" -#, fuzzy, c-format +#, c-format msgid "generating new key\n" -msgstr "gerar um novo par de chaves" +msgstr "gerando nova chave\n" -#, fuzzy, c-format +#, c-format msgid "writing new key\n" -msgstr "gerar um novo par de chaves" +msgstr "escrevendo nova chave\n" -#, fuzzy, c-format +#, c-format msgid "failed to store the key: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao armazenar a chave: %s\n" #, c-format msgid "response does not contain the RSA modulus\n" -msgstr "" +msgstr "resposta não contém o módulo de RSA\n" #, c-format msgid "response does not contain the RSA public exponent\n" -msgstr "" +msgstr "resposta não contém o expoente público de RSA\n" -#, fuzzy, c-format -#| msgid "remove keys from the public keyring" +#, c-format msgid "response does not contain the EC public key\n" -msgstr "remover chaves do porta-chaves público" +msgstr "resposta não contém a chave pública de EC\n" #, c-format msgid "please wait while key is being generated ...\n" -msgstr "" +msgstr "aguarde enquanto a chave está a ser gerada ...\n" -#, fuzzy, c-format +#, c-format msgid "generating key failed\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao gerar chave\n" -#, fuzzy, c-format +#, c-format msgid "key generation completed (%d second)\n" msgid_plural "key generation completed (%d seconds)\n" -msgstr[0] "A geração de chaves falhou: %s\n" -msgstr[1] "A geração de chaves falhou: %s\n" +msgstr[0] "geração de chave concluída (%d segundo)\n" +msgstr[1] "geração de chave concluída (%d segundos)\n" #, c-format msgid "response does not contain the public key data\n" -msgstr "" +msgstr "a resposta não contém os dados da chave pública\n" msgid "||Please enter the PIN for the key to create qualified signatures." -msgstr "" +msgstr "||Introduza o PIN da chave para criar assinaturas qualificadas." #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at #. the start of the string. Use %0A (single percent) for a linefeed. -#, fuzzy msgid "|A|Please enter the Admin PIN" -msgstr "muda a frase secreta" +msgstr "|A|Introduza o PIN do Admin" -#, fuzzy msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys." -msgstr "motivo da revocação: " +msgstr "|P|Introduza o PIN Unblocking Code (PUK) para as chaves padrão." -#, fuzzy msgid "||Please enter the PIN for the standard keys." -msgstr "muda a frase secreta" +msgstr "||Introduza o PIN das chaves padrão." #, c-format msgid "RSA modulus missing or not of size %d bits\n" -msgstr "" +msgstr "Módulo de RSA ausente ou não tem o tamanho de %d bits\n" #, c-format msgid "RSA public exponent missing or larger than %d bits\n" -msgstr "" +msgstr "Expoente público de RSA ausente ou maior que %d bits\n" -#, fuzzy -#| msgid "Note: This key has been disabled.\n" msgid "Note: PIN has not yet been enabled." -msgstr "Nota: Esta chave foi desactivada.\n" +msgstr "Nota: o PIN ainda não foi habilitado." #, c-format msgid "the NullPIN has not yet been changed\n" -msgstr "" +msgstr "o NullPIN ainda não foi alterado\n" -#, fuzzy msgid "|N|Please enter a new PIN for the standard keys." -msgstr "muda a frase secreta" +msgstr "|N|Introduza um novo PIN para as chaves padrão." -#, fuzzy msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys." -msgstr "motivo da revocação: " +msgstr "" +"|NP|Introduza um novo PIN Unblocking Code (PUK) para as chaves padrão. " msgid "|N|Please enter a new PIN for the key to create qualified signatures." -msgstr "" +msgstr "|N|Introduza um novo PIN para a chave criar assinaturas qualificadas." msgid "" "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create " "qualified signatures." msgstr "" +"|NP|Introduza um novo PIN Unblocking Code (PUK) para a chave criar " +"assinaturas qualificadas." msgid "" "|P|Please enter the PIN Unblocking Code (PUK) for the key to create " "qualified signatures." msgstr "" +"|P|Introduza o PIN Unblocking Code (PUK) para a chave criar assinaturas " +"qualificadas." -#, fuzzy, c-format +#, c-format msgid "error getting new PIN: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter novo PIN: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to store the fingerprint: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao armazenar a impressão digital: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to store the creation date: %s\n" -msgstr "falha ao criar 'cache' do porta-chaves: %s\n" +msgstr "falha ao armazenar a data de criação: %s\n" #, c-format msgid "error retrieving CHV status from card\n" -msgstr "" +msgstr "erro ao obter o status CHV do cartão\n" -#, fuzzy, c-format +#, c-format msgid "reading public key failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao ler a chave pública: %s\n" #. TRANSLATORS: Put a \x1f right before a colon. This can be #. * used by pinentry to nicely align the names and values. Keep #. * the %s at the start and end of the string. #, c-format msgid "%sNumber: %s%%0AHolder: %s%%0ACounter: %lu%s" -msgstr "" +msgstr "%sNúmero: %s%%0ATitular: %s%%0AContador: %lu%s" #, c-format msgid "using default PIN as %s\n" -msgstr "" +msgstr "usando o PIN pré-definido como %s\n" #, c-format msgid "failed to use default PIN as %s: %s - disabling further default use\n" msgstr "" +"falha ao usar o PIN pré-definido como %s: %s - desabilitando um uso pré-" +"definido adicional\n" -#, fuzzy msgid "||Please unlock the card" -msgstr "muda a frase secreta" +msgstr "||Desbloqueie o cartão" #, c-format msgid "PIN for CHV%d is too short; minimum length is %d\n" -msgstr "" +msgstr "O PIN para CHV%d é muito curto; o comprimento mínimo é %d\n" -#, fuzzy, c-format +#, c-format msgid "verify CHV%d failed: %s\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "verificar CHV%d falhou: %s\n" #, c-format msgid "card is permanently locked!\n" -msgstr "" +msgstr "cartão está permanentemente bloqueado!\n" #, c-format msgid "%d Admin PIN attempt remaining before card is permanently locked\n" msgid_plural "" "%d Admin PIN attempts remaining before card is permanently locked\n" msgstr[0] "" +"%d tentativa de PIN do Admin restante antes de o cartão ser permanentemente " +"bloqueado\n" msgstr[1] "" +"%d tentativas de PIN do Admin restantes antes de o cartão ser " +"permanentemente bloqueado\n" #, c-format msgid "access to admin commands is not configured\n" -msgstr "" +msgstr "o acesso aos comandos admin não está configurado\n" -#, fuzzy msgid "||Please enter the PIN" -msgstr "muda a frase secreta" +msgstr "||Introduza o PIN" -#, fuzzy msgid "||Please enter the Reset Code for the card" -msgstr "motivo da revocação: " +msgstr "||Introduza o Código de Reset do cartão" #, c-format msgid "Reset Code is too short; minimum length is %d\n" -msgstr "" +msgstr "O Código de Reset é muito curto; o comprimento mínimo é %d\n" #. TRANSLATORS: Do not translate the "|*|" prefixes but #. keep it at the start of the string. We need this elsewhere #. to get some infos on the string. msgid "|RN|New Reset Code" -msgstr "" +msgstr "|RN|Novo Código de Reset" msgid "|AN|New Admin PIN" -msgstr "" +msgstr "|AN|Novo PIN do Admin" msgid "|N|New PIN" -msgstr "" +msgstr "|N|Novo PIN" -#, fuzzy msgid "||Please enter the Admin PIN and New Admin PIN" -msgstr "muda a frase secreta" +msgstr "||Introduza o PIN do Admin e o Novo PIN do Admin" -#, fuzzy msgid "||Please enter the PIN and New PIN" -msgstr "muda a frase secreta" +msgstr "||Introduza o PIN e o Novo PIN" -#, fuzzy, c-format +#, c-format msgid "error reading application data\n" -msgstr "erro na leitura do bloco de chave: %s\n" +msgstr "erro ao ler dados da aplicação\n" -#, fuzzy, c-format +#, c-format msgid "error reading fingerprint DO\n" -msgstr "%s: erro ao ler registo livre: %s\n" +msgstr "erro ao ler impressão digital DO\n" #, c-format msgid "creation timestamp missing\n" -msgstr "" +msgstr "timestamp de criação ausente\n" #, c-format msgid "RSA prime %s missing or not of size %d bits\n" -msgstr "" +msgstr "primo %s de RSA ausente ou não tem o tamanho de %d bits\n" -#, fuzzy, c-format -#| msgid "unsupported URI" +#, c-format msgid "unsupported curve\n" -msgstr "URI não suportado" +msgstr "sem suporte à curva\n" #, c-format msgid "invalid structure of OpenPGP card (DO 0x93)\n" -msgstr "" +msgstr "estrutura inválida do cartão OpenPGP (DO 0x93)\n" #, c-format msgid "fingerprint on card does not match requested one\n" -msgstr "" +msgstr "impressão digital no cartão não corresponde à pedida\n" -#, fuzzy, c-format +#, c-format msgid "card does not support digest algorithm %s\n" -msgstr "assinatura %s de: \"%s\"\n" +msgstr "cartão não suporta algoritmo digest %s\n" #, c-format msgid "signatures created so far: %lu\n" -msgstr "" +msgstr "assinaturas criadas até agora: %lu\n" #, c-format msgid "" "verification of Admin PIN is currently prohibited through this command\n" msgstr "" +"a verificação do PIN do Admin é atualmente proibida através deste comando\n" -#, fuzzy, c-format +#, c-format msgid "can't access %s - invalid OpenPGP card?\n" -msgstr "nenhum dado OpenPGP válido encontrado.\n" +msgstr "incapaz aceder %s - cartão OpenPGP inválido?\n" -#, fuzzy msgid "||Please enter your PIN at the reader's pinpad" -msgstr "muda a frase secreta" +msgstr "||Introduza o seu PIN no pinpad do leitor" #. TRANSLATORS: Do not translate the "|*|" prefixes but #. keep it at the start of the string. We need this elsewhere #. to get some infos on the string. msgid "|N|Initial New PIN" -msgstr "" +msgstr "|N|Novo PIN Inicial" msgid "run in multi server mode (foreground)" -msgstr "" +msgstr "executar no modo multi server (primeiro plano)" msgid "|LEVEL|set the debugging level to LEVEL" -msgstr "" +msgstr "|LEVEL|definir o nível de debug para LEVEL" -#, fuzzy msgid "|FILE|write a log to FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|escrever um log no FILE" msgid "|N|connect to reader at port N" -msgstr "" +msgstr "|N|conectar ao leitor na porta N" -#, fuzzy msgid "|NAME|use NAME as ct-API driver" -msgstr "|NOME|usar NOME como destinatário por omissão" +msgstr "|NAME|usar NAME como driver ct-API" -#, fuzzy msgid "|NAME|use NAME as PC/SC driver" -msgstr "|NOME|usar NOME como destinatário por omissão" +msgstr "|NAME|usar NAME como driver de PC/SC" -#, fuzzy msgid "do not use the internal CCID driver" -msgstr "nunca usar o terminal" +msgstr "não usar o driver CCID interno" msgid "|N|disconnect the card after N seconds of inactivity" -msgstr "" +msgstr "|N|desconectar o cartão após N segundos de inatividade" msgid "do not use a reader's pinpad" -msgstr "" +msgstr "não usar o pinpad de um leitor" msgid "use variable length input for pinpad" -msgstr "" +msgstr "usar entrada de comprimento variável para o pinpad" msgid "|LIST|change the application priority to LIST" -msgstr "" +msgstr "|LIST|alterar a prioridade da aplicação para LIST" -#, fuzzy msgid "deny the use of admin card commands" -msgstr "comandos em conflito\n" +msgstr "negar o uso de comandos admin do cartão" -#, fuzzy msgid "Usage: @SCDAEMON@ [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @SCDAEMON@ [opções] (-h para ajuda)" msgid "" "Syntax: scdaemon [options] [command [args]]\n" "Smartcard daemon for @GNUPG@\n" msgstr "" +"Sintaxe: scdaemon [opções] [comando [args]]\n" +"Daemon de smartcard para @GNUPG@\n" #, c-format msgid "please use the option '--daemon' to run the program in the background\n" -msgstr "" +msgstr "use a opção '--daemon' para executar o programa em segundo plano\n" #, c-format msgid "handler for fd %d started\n" -msgstr "" +msgstr "handler para fd %d iniciado\n" #, c-format msgid "handler for fd %d terminated\n" -msgstr "" +msgstr "handler para fd %d terminado\n" -#, fuzzy, c-format +#, c-format msgid "error getting key usage information: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao obter informações de utilização da chave: %s\n" msgid "Tor might be in use - network access is limited" -msgstr "" +msgstr "O Tor pode estar em uso - o acesso à rede é limitado" #, c-format msgid "validation model requested by certificate: %s" -msgstr "" +msgstr "modelo de validação pedido pelo certificado: %s" msgid "chain" -msgstr "" +msgstr "corrente" -#, fuzzy msgid "shell" -msgstr "help" +msgstr "shell" -#, fuzzy, c-format +#, c-format msgid "critical certificate extension %s is not supported" -msgstr "a versão %d do protocolo gpg-agent não é suportada\n" +msgstr "extensão de certificado crítico %s não é suportada" #, c-format msgid "issuer certificate is not marked as a CA" -msgstr "" +msgstr "certificado do emissor não está marcado como uma CA" msgid "critical marked policy without configured policies" -msgstr "" +msgstr "política marcada crítica sem políticas configuradas" -#, fuzzy, c-format +#, c-format msgid "failed to open '%s': %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "falha ao abrir '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "Note: non-critical certificate policy not allowed" -msgstr "a escrever chave privada para `%s'\n" +msgstr "Nota: a política de certificado não crítico não é permitida" -#, fuzzy, c-format +#, c-format msgid "certificate policy not allowed" -msgstr "a escrever chave privada para `%s'\n" +msgstr "política de certificado não permitida" -#, fuzzy, c-format +#, c-format msgid "failed to get the fingerprint\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao obter a impressão digital\n" #, c-format msgid "looking up issuer at external location\n" -msgstr "" +msgstr "procurando o emissor no local externo\n" #, c-format msgid "number of issuers matching: %d\n" -msgstr "" +msgstr "número de emissores correspondentes: %d\n" -#, fuzzy, c-format -#| msgid "%s: can't access: %s\n" +#, c-format msgid "can't get authorityInfoAccess: %s\n" -msgstr "%s: impossível aceder: %s\n" +msgstr "não é possível obter authorityInfoAccess: %s\n" #, c-format msgid "looking up issuer from the Dirmngr cache\n" -msgstr "" +msgstr "procurando o emissor a partir da cache do Dirmngr\n" -#, fuzzy, c-format +#, c-format msgid "number of matching certificates: %d\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "número de certificados correspondentes: %d\n" -#, fuzzy, c-format +#, c-format msgid "dirmngr cache-only key lookup failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao procurar por chave apenas na cache do dirmngr: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to allocate keyDB handle\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao alocar handle de keyDB\n" -#, fuzzy msgid "certificate has been revoked" -msgstr "NOTA: a chave foi revogada" +msgstr "o certificado foi revogado" msgid "the status of the certificate is unknown" -msgstr "" +msgstr "o status do certificado é desconhecido" #, c-format msgid "please make sure that the \"dirmngr\" is properly installed\n" -msgstr "" +msgstr "certifique-se de que o \"dirmngr\" está instalado corretamente\n" -#, fuzzy, c-format +#, c-format msgid "checking the CRL failed: %s" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao verificar a CRL: %s" #, c-format msgid "certificate with invalid validity: %s" -msgstr "" +msgstr "certificado com validação inválida: %s" #, c-format msgid "certificate not yet valid" -msgstr "" +msgstr "certificado ainda não está válido" -#, fuzzy msgid "root certificate not yet valid" -msgstr "a escrever chave privada para `%s'\n" +msgstr "certificado raiz ainda não está válido" msgid "intermediate certificate not yet valid" -msgstr "" +msgstr "certificado intermediário ainda não está válido" -#, fuzzy, c-format +#, c-format msgid "certificate has expired" -msgstr "Esta chave expirou!" +msgstr "o certificado expirou" -#, fuzzy msgid "root certificate has expired" -msgstr "Esta chave expirou!" +msgstr "o certificado raiz expirou" -#, fuzzy msgid "intermediate certificate has expired" -msgstr "Esta chave expirou!" +msgstr "o certificado intermediário expirou" #, c-format msgid "required certificate attributes missing: %s%s%s" -msgstr "" +msgstr "atributos de certificado necessários ausentes: %s%s%s" -#, fuzzy msgid "certificate with invalid validity" -msgstr "Esta chave expirou!" +msgstr "certificado com validação inválida" msgid "signature not created during lifetime of certificate" -msgstr "" +msgstr "assinatura não criada durante a vida útil do certificado" msgid "certificate not created during lifetime of issuer" -msgstr "" +msgstr "certificado não criado durante a vida útil do emissor" msgid "intermediate certificate not created during lifetime of issuer" -msgstr "" +msgstr "certificado intermediário não criado durante a vida útil do emissor" -#, fuzzy, c-format +#, c-format msgid " ( signature created at " -msgstr " novas assinaturas: %lu\n" +msgstr " ( assinatura criada em " -#, fuzzy, c-format +#, c-format msgid " (certificate created at " -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr " ( certificado criado em " -#, fuzzy, c-format +#, c-format msgid " (certificate valid from " -msgstr "certificado incorrecto" +msgstr " (certificado válido desde " #, c-format msgid " ( issuer valid from " -msgstr "" +msgstr " ( emissor válido desde " -#, fuzzy, c-format +#, c-format msgid "fingerprint=%s\n" -msgstr "mostra impressão digital" +msgstr "impressão digital=%s\n" #, c-format msgid "root certificate has now been marked as trusted\n" -msgstr "" +msgstr "o certificado raiz foi agora marcado como confiável\n" #, c-format msgid "interactive marking as trusted not enabled in gpg-agent\n" -msgstr "" +msgstr "marcar interativamente como confiável não habilitado no gpg-agent\n" #, c-format msgid "interactive marking as trusted disabled for this session\n" -msgstr "" +msgstr "marcar interativamente como confiável desabilitado para esta sessão\n" msgid "WARNING: creation time of signature not known - assuming current time" msgstr "" +"AVISO: tempo de criação da assinatura não conhecido - supondo a hora atual" -#, fuzzy msgid "no issuer found in certificate" -msgstr "gerar um certificado de revogação" +msgstr "nenhum emissor encontrado no certificado" msgid "self-signed certificate has a BAD signature" -msgstr "" +msgstr "certificado auto-assinado tem uma assinatura INVÁLIDA" #, c-format msgid "root certificate is not marked trusted" -msgstr "" +msgstr "o certificado raiz não está marcado como confiável" -#, fuzzy, c-format +#, c-format msgid "checking the trust list failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao verificar a lista da confiança: %s\n" #, c-format msgid "certificate chain too long\n" -msgstr "" +msgstr "corrente de certificados muito longa\n" #, c-format msgid "issuer certificate not found" -msgstr "" +msgstr "certificado do emissor não encontrado" -#, fuzzy, c-format +#, c-format msgid "certificate has a BAD signature" -msgstr "verificar uma assinatura" +msgstr "certificado tem uma assinatura INVÁLIDA" msgid "found another possible matching CA certificate - trying again" msgstr "" +"encontrado outro certificado de CA que possivelmente corresponde - tentando " +"novamente" #, c-format msgid "certificate chain longer than allowed by CA (%d)" -msgstr "" +msgstr "corrente de certificados maior do que o permitido pela CA (%d)" -#, fuzzy, c-format +#, c-format msgid "certificate is good\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado é válido\n" -#, fuzzy, c-format +#, c-format msgid "intermediate certificate is good\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado intermediário é válido\n" -#, fuzzy, c-format +#, c-format msgid "root certificate is good\n" -msgstr "certificado incorrecto" +msgstr "certificado raiz é válido\n" msgid "switching to chain model" -msgstr "" +msgstr "mudando para o modelo de corrente" #, c-format msgid "validation model used: %s" -msgstr "" +msgstr "modelo de validação usado: %s" #, c-format msgid "a %u bit hash is not valid for a %u bit %s key\n" -msgstr "" +msgstr "um hash de %u bit não é válido para uma chave de %u bit %s\n" -#, fuzzy, c-format +#, c-format msgid "out of core\n" -msgstr "não processado" +msgstr "fora do core\n" #, c-format msgid "(this is the MD2 algorithm)\n" -msgstr "" +msgstr "(este é o algoritmo MD2)\n" -#, fuzzy msgid "none" -msgstr "não" +msgstr "nenhuma" -#, fuzzy msgid "[Error - invalid encoding]" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "[Erro - codificação inválida]" msgid "[Error - out of core]" -msgstr "" +msgstr "[Erro - fora do core]" msgid "[Error - No name]" -msgstr "" +msgstr "[Erro - Sem nome]" -#, fuzzy msgid "[Error - invalid DN]" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "[Erro - DN inválido]" -#, fuzzy, c-format +#, c-format msgid "" "Please enter the passphrase to unlock the secret key for the X.509 " "certificate:\n" @@ -7338,343 +7095,325 @@ msgid "" "S/N %s, ID 0x%08lX,\n" "created %s, expires %s.\n" msgstr "" -"Precisa de uma frase secreta para desbloquear a chave secreta do " -"utilizador:\n" -"\n" -"\"%.*s\"\n" -"chave %u bits %s, ID %08lx, criada %s%s\n" +"Introduza a frase-secreta para desbloquear a chave secreta para o " +"certificado X.509:\n" +"\"%s\"\n" +"S/N %s, ID 0x%08lX,\n" +"criado %s, expira %s.\n" #, c-format msgid "no key usage specified - assuming all usages\n" msgstr "" +"nenhuma utilização da chave especificada - supondo todos as utilizações\n" #, c-format msgid "certificate should not have been used for certification\n" -msgstr "" +msgstr "certificado não deveria ter sido usado para certificação\n" #, c-format msgid "certificate should not have been used for OCSP response signing\n" msgstr "" +"certificado não deveria ter sido usado para assinatura de resposta OCSP\n" #, c-format msgid "certificate should not have been used for encryption\n" -msgstr "" +msgstr "certificado não deveria ter sido usado para a cifração\n" #, c-format msgid "certificate should not have been used for signing\n" -msgstr "" +msgstr "certificado não deveria ter sido usado para a assinatura\n" #, c-format msgid "certificate is not usable for encryption\n" -msgstr "" +msgstr "o certificado não é utilizável para cifração\n" #, c-format msgid "certificate is not usable for signing\n" -msgstr "" +msgstr "o certificado não é utilizável para assinar\n" -#, fuzzy, c-format +#, c-format msgid "looking for another certificate\n" -msgstr "certificado incorrecto" +msgstr "à procura de outro certificado\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid algorithm\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: algoritmo inválido\n" #, c-format msgid "line %d: invalid key length %u (valid are %d to %d)\n" -msgstr "" +msgstr "linha %d: comprimento de chave %u inválido (é válido desde %d a %d)\n" #, c-format msgid "line %d: no subject name given\n" -msgstr "" +msgstr "linha %d: nenhum nome de entidade fornecido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid subject name label '%.*s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: rótulo do nome de entidade '%.*s' inválido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid subject name '%s' at pos %d\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: nome de entidade '%s' inválido no PDV %d\n" -#, fuzzy, c-format +#, c-format msgid "line %d: not a valid email address\n" -msgstr "Endereço eletrónico inválido\n" +msgstr "linha %d: não é um endereço de email válido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid serial number\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: número de série inválido\n" #, c-format msgid "line %d: invalid issuer name label '%.*s'\n" -msgstr "" +msgstr "linha %d: rótulo do nome do emissor '%.*s' inválido\n" #, c-format msgid "line %d: invalid issuer name '%s' at pos %d\n" -msgstr "" +msgstr "linha %d: nome do emissor '%s' inválido no PDV %d\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid date given\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: fornecida data inválida\n" -#, fuzzy, c-format +#, c-format msgid "line %d: error getting signing key by keygrip '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "linha %d: erro ao obter a chave de assinatura pelo keygrip '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid hash algorithm given\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: fornecido algoritmo de hash inválido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid authority-key-id\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: authority-key-id inválido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid subject-key-id\n" -msgstr "chave %08lX: ligação de subchave inválida\n" +msgstr "linha %d: subject-key-id inválido\n" -#, fuzzy, c-format +#, c-format msgid "line %d: invalid extension syntax\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "linha %d: sintaxe de extensão inválida\n" -#, fuzzy, c-format +#, c-format msgid "line %d: error reading key '%s' from card: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "linha %d: erro ao ler a chave '%s' do cartão: %s\n" -#, fuzzy, c-format +#, c-format msgid "line %d: error getting key by keygrip '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "linha %d: erro ao obter chave por keygrip '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "line %d: key generation failed: %s <%s>\n" -msgstr "A geração de chaves falhou: %s\n" +msgstr "linha %d: falha na geração de chaves: %s <%s>\n" msgid "" "To complete this certificate request please enter the passphrase for the key " "you just created once more.\n" msgstr "" +"Para concluir este pedido de certificado, introduza mais uma vez a frase-" +"secreta para a chave que você acabou de criar.\n" -#, fuzzy, c-format +#, c-format msgid " (%d) Existing key\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) Chave existente\n" #, c-format msgid " (%d) Existing key from card\n" -msgstr "" +msgstr " (%d) Chave existente do cartão\n" #, c-format msgid "Possible actions for a %s key:\n" -msgstr "" +msgstr "Ações possíveis para uma chave %s:\n" -#, fuzzy, c-format +#, c-format msgid " (%d) sign, encrypt\n" -msgstr " (%d) RSA (assinatura e cifragem)\n" +msgstr " (%d) assinar, cifrar\n" -#, fuzzy, c-format +#, c-format msgid " (%d) sign\n" -msgstr " (%d) DSA (apenas assinatura)\n" +msgstr " (%d) assinar\n" -#, fuzzy, c-format +#, c-format msgid " (%d) encrypt\n" -msgstr " (%d) RSA (apenas cifragem)\n" +msgstr " (%d) cifrar\n" msgid "Enter the X.509 subject name: " -msgstr "" +msgstr "Introduzir o nome de entidade X.509: " msgid "No subject name given\n" -msgstr "" +msgstr "Nenhum nome de entidade fornecido\n" -#, fuzzy, c-format +#, c-format msgid "Invalid subject name label '%.*s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "Rótulo do nome de entidade inválido '%.*s'\n" #. TRANSLATORS: The 22 in the second string is the #. length of the first string up to the "%s". Please #. adjust it do the length of your translation. The #. second string is merely passed to atoi so you can #. drop everything after the number. -#, fuzzy, c-format +#, c-format msgid "Invalid subject name '%s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "Nome de entidade inválido '%s'\n" msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty" -msgstr "" +msgstr "27 translator: see certreg-ui.c:gpgsm_gencertreq_tty" -#, fuzzy msgid "Enter email addresses" -msgstr "Endereço de correio eletrónico: " +msgstr "Introduzir os endereços de email" -#, fuzzy msgid " (end with an empty line):\n" -msgstr "" -"\n" -"Insira o identificador do utilizador. Termine com uma linha vazia: " +msgstr " (terminar com uma linha vazia):\n" -#, fuzzy msgid "Enter DNS names" -msgstr "Digite novo nome de ficheiro" +msgstr "Introduzir nomes DNS" -#, fuzzy msgid " (optional; end with an empty line):\n" -msgstr "" -"\n" -"Insira o identificador do utilizador. Termine com uma linha vazia: " +msgstr " (opcional; terminar com uma linha vazia):\n" msgid "Enter URIs" -msgstr "" +msgstr "Introduzir URIs" -#, fuzzy msgid "Create self-signed certificate? (y/N) " -msgstr "Gerar um certificado de revogação para esta assinatura? (s/N)" +msgstr "Criar certificado auto-assinado? (s/N) " msgid "These parameters are used:\n" -msgstr "" +msgstr "São usados estes parâmetros:\n" -#, fuzzy, c-format +#, c-format msgid "error creating temporary file: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar ficheiro temporário: %s\n" msgid "Now creating self-signed certificate. " -msgstr "" +msgstr "Criando agora certificado auto-assinado. " -#, fuzzy msgid "Now creating certificate request. " -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "Criando agora o pedido de certificado. " msgid "This may take a while ...\n" -msgstr "" +msgstr "Isto pode demorar um pouco...\n" msgid "Ready.\n" -msgstr "" +msgstr "Pronto.\n" msgid "Ready. You should now send this request to your CA.\n" -msgstr "" +msgstr "Pronto. Agora você deverá enviar este pedido para sua CA.\n" #, c-format msgid "resource problem: out of core\n" -msgstr "" +msgstr "problema de recurso: fora do core\n" #, c-format msgid "(this is the RC2 algorithm)\n" -msgstr "" +msgstr "(este é o algoritmo RC2)\n" #, c-format msgid "(this does not seem to be an encrypted message)\n" -msgstr "" +msgstr "(esta não parece ser uma mensagem cifrada)\n" -#, fuzzy, c-format +#, c-format msgid "encrypted to %s key %s\n" -msgstr "cifrado com chave %s, ID %08lX\n" +msgstr "cifrado para chave %s %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate '%s' not found: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "certificado '%s' não encontrado: %s\n" -#, fuzzy, c-format +#, c-format msgid "error locking keybox: %s\n" -msgstr "erro na leitura do bloco de chave: %s\n" +msgstr "erro ao bloquear a keybox: %s\n" -#, fuzzy, c-format +#, c-format msgid "duplicated certificate '%s' deleted\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado duplicado '%s' apagado\n" -#, fuzzy, c-format +#, c-format msgid "certificate '%s' deleted\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado '%s' apagado\n" -#, fuzzy, c-format +#, c-format msgid "deleting certificate \"%s\" failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao apagar o certificado \"%s\": %s\n" -#, fuzzy, c-format +#, c-format msgid "no valid recipients given\n" -msgstr "resposta do agente inválida\n" +msgstr "nenhum destinatário válido fornecido\n" -#, fuzzy msgid "list external keys" -msgstr "listar as chaves secretas" +msgstr "listar chaves externas" -#, fuzzy msgid "list certificate chain" -msgstr "certificado incorrecto" +msgstr "listar corrente de certificados" -#, fuzzy msgid "import certificates" -msgstr "certificado incorrecto" +msgstr "importar certificados" -#, fuzzy msgid "export certificates" -msgstr "certificado incorrecto" +msgstr "exportar certificados" msgid "register a smartcard" -msgstr "" +msgstr "registar um smartcard" msgid "pass a command to the dirmngr" -msgstr "" +msgstr "passar um comando para o dirmngr" msgid "invoke gpg-protect-tool" -msgstr "" +msgstr "invocar gpg-protect-tool" msgid "don't use the terminal at all" msgstr "nunca usar o terminal" msgid "|N|number of certificates to include" -msgstr "" +msgstr "|N|número de certificados a incluir" msgid "|FILE|take policy information from FILE" -msgstr "" +msgstr "|FILE|pegar informações de política do FILE" msgid "assume input is in PEM format" -msgstr "" +msgstr "supor que a entrada esteja no formato PEM" msgid "assume input is in base-64 format" -msgstr "" +msgstr "supor que a entrada esteja no formato base-64" msgid "assume input is in binary format" -msgstr "" +msgstr "supor que a entrada esteja em formato binário" -#, fuzzy msgid "create base-64 encoded output" -msgstr "criar saída com armadura ascii" +msgstr "criar saída codificada em base-64" -#, fuzzy msgid "|USER-ID|use USER-ID as default secret key" -msgstr "|NOME|usar NOME como chave secreta por omissão" +msgstr "|USER-ID|usar USER-ID como chave secreta pré-definida" -#, fuzzy msgid "|FILE|add keyring to the list of keyrings" -msgstr "" -"adicionar este porta-chaves\n" -"à lista de porta-chaves" +msgstr "|FILE|adicionar porta-chaves à lista dos porta-chaves" msgid "fetch missing issuer certificates" -msgstr "" +msgstr "buscar certificados de emissor ausentes" -#, fuzzy msgid "|NAME|use encoding NAME for PKCS#12 passphrases" -msgstr "" -"|NOME|usar algoritmo de criptografia NOME para\n" -"frases secretas" +msgstr "|NAME|usar a codificação NAME para frases-secretas PKCS#12" msgid "never consult a CRL" -msgstr "" +msgstr "nunca consultar uma CRL" msgid "do not check CRLs for root certificates" -msgstr "" +msgstr "não verificar CRLs para certificados raiz" msgid "check validity using OCSP" -msgstr "" +msgstr "verificar a validade usando OCSP" msgid "do not check certificate policies" -msgstr "" +msgstr "não verificar políticas de certificado" msgid "|NAME|use cipher algorithm NAME" -msgstr "|NOME|usar algoritmo de criptografia NOME" +msgstr "|NAME|usar algoritmo da cifra NAME" msgid "|NAME|use message digest algorithm NAME" -msgstr "|NOME|usar algoritmo de \"digest\" de mensagens NOME" +msgstr "|NAME|usar algoritmo de digest das mensagens NAME" msgid "batch mode: never ask" -msgstr "modo não-interactivo: nunca perguntar" +msgstr "modo batch: nunca perguntar" msgid "assume yes on most questions" msgstr "assumir sim para a maioria das perguntas" @@ -7682,111 +7421,107 @@ msgstr "assumir sim para a maioria das perguntas" msgid "assume no on most questions" msgstr "assumir não para a maioria das perguntas" -#, fuzzy msgid "|FILE|write an audit log to FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|escrever um log de auditoria no FILE" -#, fuzzy -#| msgid "Usage: gpg [options] [files] (-h for help)" msgid "Usage: @GPGSM@ [options] [files] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPGSM@ [opções] [ficheiros] (-h para ajuda)" -#, fuzzy msgid "" "Syntax: @GPGSM@ [options] [files]\n" "Sign, check, encrypt or decrypt using the S/MIME protocol\n" "Default operation depends on the input data\n" msgstr "" -"Sintaxe: gpg [opções] [ficheiros]\n" -"assina, verifica, cifra ou decifra\n" -"a operação por omissão depende dos dados de entrada\n" +"Sintaxe: @GPGSM@ [opções] [ficheiros]\n" +"Assinar, verificar, cifrar, ou decifrar usando o protocolo S/MIME\n" +"A operação pré-definida depende dos dados de entrada\n" -#, fuzzy, c-format +#, c-format msgid "Note: won't be able to encrypt to '%s': %s\n" -msgstr "impossível ligar a `%s': %s\n" +msgstr "Nota: não será possível cifrar para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "unknown validation model '%s'\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "modelo de validação '%s' desconhecido\n" -#, fuzzy, c-format +#, c-format msgid "importing common certificates '%s'\n" -msgstr "a escrever para `%s'\n" +msgstr "importando certificados comuns '%s'\n" -#, fuzzy, c-format +#, c-format msgid "can't sign using '%s': %s\n" -msgstr "impossível fechar `%s': %s\n" +msgstr "não é possível assinar usando '%s': %s\n" #, c-format msgid "invalid command (there is no implicit command)\n" -msgstr "" +msgstr "comando inválido (não há comando implícito)\n" -#, fuzzy, c-format +#, c-format msgid "total number processed: %lu\n" -msgstr "Número total processado: %lu\n" +msgstr "número total processado: %lu\n" -#, fuzzy, c-format +#, c-format msgid "error storing certificate\n" -msgstr "gerar um certificado de revogação" +msgstr "erro ao armazenar certificado\n" #, c-format msgid "basic certificate checks failed - not imported\n" -msgstr "" +msgstr "falha nas verificações básicas de certificado - não importado\n" -#, fuzzy, c-format +#, c-format msgid "error getting stored flags: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter flags armazenadas: %s\n" -#, fuzzy, c-format +#, c-format msgid "error importing certificate: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao importar certificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading input: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler a entrada: %s\n" -#, fuzzy, c-format +#, c-format msgid "no keyboxd running in this session\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "nenhum keyboxd em execução nesta sessão\n" -#, fuzzy, c-format +#, c-format msgid "error opening key DB: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao abrir keyDB: %s\n" #, c-format msgid "problem looking for existing certificate: %s\n" -msgstr "" +msgstr "problema ao procurar certificado existente: %s\n" -#, fuzzy, c-format +#, c-format msgid "error finding writable keyDB: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao encontrar keyDB com permissão de escrita: %s\n" -#, fuzzy, c-format +#, c-format msgid "error storing certificate: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao armazenar certificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "problem re-searching certificate: %s\n" -msgstr "rev? problema ao verificar revogação: %s\n" +msgstr "problema ao pesquisar novamente o certificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "error storing flags: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao armazenar flags: %s\n" msgid "Error - " -msgstr "" +msgstr "Erro - " #, c-format msgid "GPG_TTY has not been set - using maybe bogus default\n" -msgstr "" +msgstr "GPG_TTY não foi definido - talvez esteja usando falsa pré-definição\n" -#, fuzzy, c-format +#, c-format msgid "invalid formatted fingerprint in '%s', line %d\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "impressão digital formatada está inválida em '%s', linha %d\n" -#, fuzzy, c-format +#, c-format msgid "invalid country code in '%s', line %d\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "código de país está inválido em '%s', linha %d\n" #, c-format msgid "" @@ -7797,12 +7532,20 @@ msgid "" "\n" "%s%sAre you really sure that you want to do this?" msgstr "" +"Você está prestes a criar uma assinatura usando seu certificado:\n" +"\"%s\"\n" +"Isto criará uma assinatura qualificada por lei equiparada a uma assinatura " +"manuscrita.\n" +"\n" +"%s%sTem certeza de que deseja fazer isto?" #, c-format msgid "" "Note, that this software is not officially approved to create or verify such " "signatures.\n" msgstr "" +"Note que este software não é oficialmente aprovado para criar ou verificar " +"tais assinaturas.\n" #, c-format msgid "" @@ -7810,604 +7553,601 @@ msgid "" "\"%s\"\n" "Note, that this certificate will NOT create a qualified signature!" msgstr "" +"Você está prestes a criar uma assinatura usando seu certificado:\n" +"\"%s\"\n" +"Note que este certificado NÃO criará uma assinatura qualificada!" -#, fuzzy, c-format +#, c-format msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n" -msgstr "algoritmo de protecção %d%s não é suportado\n" +msgstr "" +"algoritmo de hash %d (%s) para o signatário %d não suportado; usando %s\n" #, c-format msgid "hash algorithm used for signer %d: %s (%s)\n" -msgstr "" +msgstr "algoritmo de hash usado para o signatário %d: %s (%s)\n" -#, fuzzy, c-format +#, c-format msgid "checking for qualified certificate failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha na verificação do certificado qualificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "%s/%s signature using %s key %s\n" -msgstr "Assinatura feita em %.*s usando %s, ID da chave %08lX\n" +msgstr "assinatura %s/%s usando a chave %s %s\n" -#, fuzzy, c-format +#, c-format msgid "Signature made " -msgstr "Esta assinatura expirou em %s.\n" +msgstr "Assinatura feita " #, c-format msgid "[date not given]" -msgstr "" +msgstr "[data não fornecida]" -#, fuzzy, c-format +#, c-format msgid "algorithm:" -msgstr "armadura: %s\n" +msgstr "algoritmo:" #, c-format msgid "" "invalid signature: message digest attribute does not match computed one\n" msgstr "" +"assinatura inválida: o atributo digest da mensagem não corresponde ao " +"computado\n" -#, fuzzy, c-format +#, c-format msgid "Good signature from" -msgstr "Assinatura correcta de \"" +msgstr "Assinatura válida de" -#, fuzzy, c-format +#, c-format msgid " aka" -msgstr " ou \"" +msgstr " aka" -#, fuzzy, c-format +#, c-format msgid "This is a qualified signature\n" -msgstr "" -"\n" -"Isto será uma auto-assinatura.\n" +msgstr "Esta é uma assinatura qualificada\n" -#, fuzzy, c-format +#, c-format msgid "can't initialize certificate cache lock: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "não é possível inicializar o bloqueio da cache de certificados: %s\n" #, c-format msgid "can't acquire read lock on the certificate cache: %s\n" msgstr "" +"não é possível adquirir bloqueio de leitura da cache de certificados: %s\n" #, c-format msgid "can't acquire write lock on the certificate cache: %s\n" msgstr "" +"não é possível adquirir bloqueio de escrita da cache de certificados: %s\n" #, c-format msgid "can't release lock on the certificate cache: %s\n" -msgstr "" +msgstr "não é possível libertar o bloqueio da cache de certificados: %s\n" #, c-format msgid "dropping %u certificates from the cache\n" -msgstr "" +msgstr "descartando %u certificados da cache\n" -#, fuzzy, c-format -#| msgid "can't create `%s': %s\n" +#, c-format msgid "can't parse certificate '%s': %s\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível processar o certificado '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate '%s' already cached\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado '%s' já armazenado em cache\n" -#, fuzzy, c-format +#, c-format msgid "trusted certificate '%s' loaded\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado confiável '%s' carregado\n" -#, fuzzy, c-format +#, c-format msgid "certificate '%s' loaded\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado '%s' carregado\n" -#, fuzzy, c-format +#, c-format msgid " SHA1 fingerprint = %s\n" -msgstr "mostra impressão digital" +msgstr " impressão digital SHA1 = %s\n" msgid " issuer =" -msgstr "" +msgstr " emissor =" msgid " subject =" -msgstr "" +msgstr " entidade =" -#, fuzzy, c-format +#, c-format msgid "error loading certificate '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao carregar o certificado '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "permanently loaded certificates: %u\n" -msgstr "certificado incorrecto" +msgstr " certificados permanentemente carregados: %u\n" -#, fuzzy, c-format +#, c-format msgid " runtime cached certificates: %u\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "certificados de cache em tempo de execução: %u\n" -#, fuzzy, c-format +#, c-format msgid " trusted certificates: %u (%u,%u,%u,%u)\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr " certificados confiáveis: %u (%u,%u,%u,%u)\n" -#, fuzzy, c-format +#, c-format msgid "certificate already cached\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "certificado já em cache\n" -#, fuzzy, c-format +#, c-format msgid "certificate cached\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado armazenado em cache\n" -#, fuzzy, c-format +#, c-format msgid "error caching certificate: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao armazenar o certificado em cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "invalid SHA1 fingerprint string '%s'\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "string de impressão digital SHA1 inválida '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error fetching certificate by S/N: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao buscar certificado por S/N: %s\n" -#, fuzzy, c-format +#, c-format msgid "error fetching certificate by subject: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao buscar certificado por entidade: %s\n" -#, fuzzy, c-format +#, c-format msgid "no issuer found in certificate\n" -msgstr "gerar um certificado de revogação" +msgstr "nenhum emissor encontrado no certificado\n" -#, fuzzy, c-format +#, c-format msgid "error getting authorityKeyIdentifier: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter authorityKeyIdentifier: %s\n" -#, fuzzy, c-format +#, c-format msgid "creating directory '%s'\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "criando a pasta '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error creating directory '%s': %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "erro ao criar a pasta '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "ignoring database dir '%s'\n" -msgstr "erro na última linha\n" +msgstr "ignorando a pasta da base de dados '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error reading directory '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler a pasta '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "removing cache file '%s'\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "removendo o ficheiro de cache '%s'\n" -#, fuzzy, c-format -#| msgid "enarmoring failed: %s\n" +#, c-format msgid "not removing file '%s'\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "não removendo ficheiro '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error closing cache file: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fechar o ficheiro de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to open cache dir file '%s': %s\n" -msgstr "impossível abrir `%s': %s\n" +msgstr "falha ao abrir o ficheiro '%s' da pasta de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "error creating new cache dir file '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar novo ficheiro '%s' da pasta de cache: %s\n" -#, fuzzy, c-format -#| msgid "error writing secret keyring `%s': %s\n" +#, c-format msgid "error writing new cache dir file '%s': %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao escrever novo ficheiro '%s' da pasta de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "error closing new cache dir file '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fechar novo ficheiro '%s' da pasta de cache: %s\n" -#, fuzzy, c-format -#| msgid "new configuration file `%s' created\n" +#, c-format msgid "new cache dir file '%s' created\n" -msgstr "criado um novo ficheiro de configuração `%s'\n" +msgstr "novo ficheiro '%s' da pasta de cache criado\n" -#, fuzzy, c-format +#, c-format msgid "failed to re-open cache dir file '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "falha ao reabrir ficheiro '%s' da pasta de cache: %s\n" #, c-format msgid "first record of '%s' is not the version\n" -msgstr "" +msgstr "primeiro registo de '%s' não é a versão\n" #, c-format msgid "old version of cache directory - cleaning up\n" -msgstr "" +msgstr "versão antiga da pasta de cache - limpando\n" #, c-format msgid "old version of cache directory - giving up\n" -msgstr "" +msgstr "versão antiga da pasta de cache - desistindo\n" #, c-format msgid "extra field detected in crl record of '%s' line %u\n" -msgstr "" +msgstr "campo extra detetado no registo crl de '%s' linha %u\n" -#, fuzzy, c-format +#, c-format msgid "invalid line detected in '%s' line %u\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "linha inválida detetada em '%s' linha %u\n" -#, fuzzy, c-format +#, c-format msgid "duplicate entry detected in '%s' line %u\n" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "entrada duplicada detetada em '%s' linha %u\n" #, c-format msgid "unsupported record type in '%s' line %u skipped\n" -msgstr "" +msgstr "tipo de registo sem suporte em '%s' linha %u ignorada\n" -#, fuzzy, c-format +#, c-format msgid "invalid issuer hash in '%s' line %u\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "hash do emissor inválido em '%s' linha %u\n" -#, fuzzy, c-format +#, c-format msgid "no issuer DN in '%s' line %u\n" -msgstr "armadura: %s\n" +msgstr "nenhum DN emissor em '%s' linha %u\n" -#, fuzzy, c-format +#, c-format msgid "invalid timestamp in '%s' line %u\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "timestamp inválido em '%s' linha %u\n" -#, fuzzy, c-format -#| msgid "WARNING: invalid size of random_seed file - not used\n" +#, c-format msgid "WARNING: invalid cache file hash in '%s' line %u\n" -msgstr "" -"AVISO: o ficheiro random_seed tem um tamanho inválido - não utilizado\n" +msgstr "AVISO: hash de ficheiro de cache inválido em '%s' linha %u\n" #, c-format msgid "detected errors in cache dir file\n" -msgstr "" +msgstr "erros detetados no ficheiro da pasta de cache\n" #, c-format msgid "please check the reason and manually delete that file\n" -msgstr "" +msgstr "verifique o motivo e apague manualmente este ficheiro\n" -#, fuzzy, c-format +#, c-format msgid "failed to create temporary cache dir file '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "falha ao criar o ficheiro temporário '%s' da pasta de cache: %s\n" -#, fuzzy, c-format -#| msgid "error reading `%s': %s\n" +#, c-format msgid "error renaming '%s' to '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao renomear '%s' para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "can't hash '%s': %s\n" -msgstr "impossível fechar `%s': %s\n" +msgstr "não é possível fazer hash de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error setting up MD5 hash context: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao definir o contexto da hash MD5: %s\n" -#, fuzzy, c-format +#, c-format msgid "error hashing '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fazer hash de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "invalid formatted checksum for '%s'\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "checksum formatada inválida para '%s'\n" #, c-format msgid "too many open cache files; can't open anymore\n" -msgstr "" +msgstr "muitos ficheiros de cache abertos; posso abrir mais nenhum\n" -#, fuzzy, c-format +#, c-format msgid "opening cache file '%s'\n" -msgstr "assinatura falhou: %s\n" +msgstr "abrindo o ficheiro de cache '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error opening cache file '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao abrir o ficheiro de cache '%s': %s\n" #, c-format msgid "error initializing cache file '%s' for reading: %s\n" -msgstr "" +msgstr "erro ao inicializar o ficheiro de cache '%s' para leitura: %s\n" #, c-format msgid "calling unlock_db_file on a closed file\n" -msgstr "" +msgstr "chamando unlock_db_file num ficheiro fechado\n" #, c-format msgid "calling unlock_db_file on an unlocked file\n" -msgstr "" +msgstr "chamando unlock_db_file num ficheiro desbloqueado\n" -#, fuzzy, c-format +#, c-format msgid "failed to create a new cache object: %s\n" -msgstr "%s: falha ao criar tabela de dispersão: %s\n" +msgstr "falha ao criar um novo objeto de cache: %s\n" -#, fuzzy, c-format -#| msgid "No help available for `%s'" +#, c-format msgid "no CRL available for issuer id %s\n" -msgstr "Nenhuma ajuda disponível para `%s'" +msgstr "nenhuma CRL disponível para a id do emissor %s\n" #, c-format msgid "cached CRL for issuer id %s too old; update required\n" msgstr "" +"CRL em cache muito antiga para a id do emissor %s; atualização necessária\n" #, c-format msgid "" "force-crl-refresh active and %d minutes passed for issuer id %s; update " "required\n" msgstr "" +"force-crl-refresh ativa e %d minutos passados para a id do emissor %s; " +"atualização necessária\n" #, c-format msgid "force-crl-refresh active for issuer id %s; update required\n" msgstr "" +"force-crl-refresh ativa para a id do emissor %s; atualização necessária\n" #, c-format msgid "available CRL for issuer ID %s can't be used\n" -msgstr "" +msgstr "CRL disponível para a id do emissor %s não pode ser usada\n" #, c-format msgid "cached CRL for issuer id %s tampered; we need to update\n" msgstr "" +"CRL em cache adulterada para a id do emissor %s; precisamos atualizar\n" #, c-format msgid "WARNING: invalid cache record length for S/N " -msgstr "" +msgstr "AVISO: comprimento do registo de cache inválido para S/N " -#, fuzzy, c-format +#, c-format msgid "problem reading cache record for S/N %s: %s\n" -msgstr "erro ao criar porta-chaves `%s': %s\n" +msgstr "problema ao ler o registo de cache para S/N %s: %s\n" #, c-format msgid "S/N %s is not valid; reason=%02X date=%.15s\n" -msgstr "" +msgstr "S/N %s não é válido; razão=%02X data=%.15s\n" #, c-format msgid "S/N %s is valid, it is not listed in the CRL\n" -msgstr "" +msgstr "S/N %s é válido, não está listado na CRL\n" -#, fuzzy, c-format +#, c-format msgid "error getting data from cache file: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter os dados do ficheiro de cache: %s\n" #, c-format msgid "got an invalid S-expression from libksba\n" -msgstr "" +msgstr "obtive uma S-expression inválida da libksba\n" -#, fuzzy, c-format +#, c-format msgid "converting S-expression failed: %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "falha na conversão da S-expression: %s\n" -#, fuzzy, c-format -#| msgid "invalid hash algorithm `%s'\n" +#, c-format msgid "unknown hash algorithm '%s'\n" -msgstr "algoritmo de dispersão inválido `%s'\n" +msgstr "algoritmo de hash desconhecido '%s'\n" #, c-format msgid "gcry_md_open for algorithm %d failed: %s\n" -msgstr "" +msgstr "gcry_md_open para o algoritmo %d falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "creating S-expression failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao criar a S-expression: %s\n" -#, fuzzy, c-format +#, c-format msgid "ksba_crl_parse failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "ksba_crl_parse falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "error getting update times of CRL: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter tempos de atualização da CRL: %s\n" #, c-format msgid "update times of this CRL: this=%s next=%s\n" -msgstr "" +msgstr "tempos de atualização desta CRL: este=%s próximo=%s\n" #, c-format msgid "nextUpdate not given; assuming a validity period of one day\n" -msgstr "" +msgstr "nextUpdate não fornecido; assumindo que expira num período de um dia\n" -#, fuzzy, c-format +#, c-format msgid "error getting CRL item: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter o item da CRL: %s\n" -#, fuzzy, c-format +#, c-format msgid "error inserting item into temporary cache file: %s\n" -msgstr "a escrever para `%s'\n" +msgstr "erro ao inserir item no ficheiro de cache temporário: %s\n" -#, fuzzy, c-format +#, c-format msgid "no CRL issuer found in CRL: %s\n" -msgstr "gerar um certificado de revogação" +msgstr "nenhum emissor de CRL encontrado na CRL: %s\n" #, c-format msgid "locating CRL issuer certificate by authorityKeyIdentifier\n" msgstr "" +"localizando o certificado do emissor da CRL por authorityKeyIdentifier\n" -#, fuzzy, c-format -#| msgid "signature verification suppressed\n" +#, c-format msgid "CRL signature verification failed: %s\n" -msgstr "verificação de assinatura suprimida\n" +msgstr "falha na verificação de assinatura da CRL: %s\n" -#, fuzzy, c-format +#, c-format msgid "error checking validity of CRL issuer certificate: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "erro ao verificar a validade do certificado do emissor da CRL: %s\n" -#, fuzzy, c-format +#, c-format msgid "ksba_crl_new failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "ksba_crl_new falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "ksba_crl_set_reader failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "ksba_crl_set_reader falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "removed stale temporary cache file '%s'\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "ficheiro de cache temporário obsoleto '%s' foi removido\n" -#, fuzzy, c-format +#, c-format msgid "problem removing stale temporary cache file '%s': %s\n" -msgstr "%s: impossível criar directoria: %s\n" +msgstr "problema ao remover o ficheiro de cache temporário obsoleto '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error creating temporary cache file '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao criar o ficheiro de cache temporário '%s': %s\n" -#, fuzzy, c-format -#| msgid "update secret failed: %s\n" +#, c-format msgid "crl_parse_insert failed: %s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "crl_parse_insert falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "error finishing temporary cache file '%s': %s\n" -msgstr "a escrever para `%s'\n" +msgstr "erro ao finalizar o ficheiro de cache temporário '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error closing temporary cache file '%s': %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao fechar o ficheiro de cache temporário '%s': %s\n" #, c-format msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n" msgstr "" +"ATENÇÃO: nova CRL ainda muito antiga; ela expirou em %s - carregando mesmo " +"assim\n" #, c-format msgid "new CRL still too old; it expired on %s\n" -msgstr "" +msgstr "nova CRL ainda muito antiga; expirou em %s\n" #, c-format msgid "unknown critical CRL extension %s\n" -msgstr "" +msgstr "extensão crítica de CRL desconhecida %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading CRL extensions: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler extensões de CRL: %s\n" -#, fuzzy, c-format +#, c-format msgid "creating cache file '%s'\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "criando o ficheiro de cache '%s'\n" -#, fuzzy, c-format +#, c-format msgid "problem renaming '%s' to '%s': %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "problema ao renomear '%s' para '%s': %s\n" #, c-format msgid "" "updating the DIR file failed - cache entry will get lost with the next " "program start\n" msgstr "" +"falha ao atualizar o ficheiro DIR - a entrada de cache será perdida com o " +"próximo início do programa\n" #, c-format msgid "Begin CRL dump (retrieved via %s)\n" -msgstr "" +msgstr "Iniciar dump de CRL (obtido via %s)\n" msgid "" " ERROR: The CRL will not be used because it was still too old after an " "update!\n" msgstr "" +" ERRO: A CRL não será usada porque ainda era muito antiga após uma " +"atualização!\n" msgid "" " ERROR: The CRL will not be used due to an unknown critical extension!\n" msgstr "" +" ERRO: A CRL não será usada devido a uma extensão crítica desconhecida!\n" msgid " ERROR: The CRL will not be used\n" -msgstr "" +msgstr " ERRO: A CRL não será usada\n" msgid " ERROR: This cached CRL may have been tampered with!\n" -msgstr "" +msgstr " ERRO: Esta CRL em cache pode ter sido adulterada!\n" -#, fuzzy, c-format -#| msgid "WARNING: invalid size of random_seed file - not used\n" +#, c-format msgid " WARNING: invalid cache record length\n" -msgstr "" -"AVISO: o ficheiro random_seed tem um tamanho inválido - não utilizado\n" +msgstr " AVISO: comprimento de registo de cache inválido\n" -#, fuzzy, c-format +#, c-format msgid "problem reading cache record: %s\n" -msgstr "%s: erro ao ler registo livre: %s\n" +msgstr "problema ao ler o registo de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "problem reading cache key: %s\n" -msgstr "rev? problema ao verificar revogação: %s\n" +msgstr "problema ao ler a chave de cache: %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading cache entry from db: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler a entrada de cache da base de dados: %s\n" msgid "End CRL dump\n" -msgstr "" +msgstr "Fim do dump de CRL\n" -#, fuzzy, c-format +#, c-format msgid "crl_fetch via DP failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "crl_fetch via DP falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "crl_cache_insert via DP failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "crl_cache_insert via DP falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "crl_cache_insert via issuer failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "crl_cache_insert via emissor falhou: %s\n" #, c-format msgid "reader to file mapping table full - waiting\n" -msgstr "" +msgstr "leitor cheio para tabela de mapeamento de ficheiros - aguardando\n" -#, fuzzy msgid "CRL access not possible due to Tor mode" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "o acesso à CRL não é possível devido ao modo Tor" #, c-format msgid "CRL access not possible due to disabled %s\n" -msgstr "" +msgstr "o acesso à CRL não é possível devido a %s estar desabilitado\n" -#, fuzzy, c-format +#, c-format msgid "error retrieving '%s': %s\n" -msgstr "erro ao criar `%s': %s\n" +msgstr "erro ao obter '%s': %s\n" -#, fuzzy, c-format -#| msgid "%s: error writing dir record: %s\n" +#, c-format msgid "error initializing reader object: %s\n" -msgstr "%s: erro ao escrever registo de diretório: %s\n" +msgstr "erro ao inicializar o objeto leitor: %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate search not possible due to disabled %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "" +"a pesquisa de certificados não é possível devido a %s estar desabilitado\n" msgid "use OCSP instead of CRLs" -msgstr "" +msgstr "usar OCSP em vez de CRLs" msgid "check whether a dirmngr is running" -msgstr "" +msgstr "verificar se um dirmngr está em execução" -#, fuzzy msgid "add a certificate to the cache" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "adicionar um certificado à cache" -#, fuzzy msgid "validate a certificate" -msgstr "certificado incorrecto" +msgstr "validar um certificado" -#, fuzzy msgid "lookup a certificate" -msgstr "certificado incorrecto" +msgstr "procurar um certificado" -#, fuzzy msgid "lookup only locally stored certificates" -msgstr "certificado incorrecto" +msgstr "procurar apenas certificados armazenados localmente" msgid "expect an URL for --lookup" -msgstr "" +msgstr "esperar uma URL para --lookup" msgid "load a CRL into the dirmngr" -msgstr "" +msgstr "carregar uma CRL no dirmngr" msgid "special mode for use by Squid" -msgstr "" +msgstr "modo especial para uso pelo Squid" -#, fuzzy msgid "expect certificates in PEM format" -msgstr "certificado incorrecto" +msgstr "esperar certificados no formato PEM" -#, fuzzy -#| msgid "Enter the user ID of the designated revoker: " msgid "force the use of the default OCSP responder" -msgstr "Insira o ID de utilizador do revogador escolhido: " +msgstr "forçar o uso do respondente OCSP pré-definido" -#, fuzzy -#| msgid "Usage: gpg [options] [files] (-h for help)" msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "" +"Uso: dirmngr-client [opções] [ficheiro-cert|padrão] (-h para obter ajuda)\n" msgid "" "Syntax: dirmngr-client [options] [certfile|pattern]\n" @@ -8415,2987 +8155,821 @@ msgid "" "The process returns 0 if the certificate is valid, 1 if it is\n" "not valid and other error codes for general failures\n" msgstr "" +"Sintaxe: dirmngr-client [opções] [ficheiro-cert|padrão]\n" +"Testar um certificado X.509 em relação a uma CRL ou fazer uma\n" +"verificação OCSP.\n" +"O processo retorna 0 se o certificado for válido, 1 se não for\n" +"válido, e outros códigos de erro para falhas gerais.\n" -#, fuzzy, c-format +#, c-format msgid "error reading certificate from stdin: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao ler certificado de stdin: %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading certificate from '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler o certificado de '%s': %s\n" #, c-format msgid "certificate too large to make any sense\n" -msgstr "" +msgstr "certificado demasiado grande para fazer qualquer sentido\n" -#, fuzzy, c-format -#| msgid "can't connect to `%s': %s\n" +#, c-format msgid "can't connect to the dirmngr: %s\n" -msgstr "impossível ligar a `%s': %s\n" +msgstr "não é possível conectar-se ao dirmngr: %s\n" -#, fuzzy, c-format -#| msgid "update failed: %s\n" +#, c-format msgid "lookup failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "falha na procura: %s\n" -#, fuzzy, c-format +#, c-format msgid "loading CRL '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha ao carregar a CRL '%s': %s\n" #, c-format msgid "a dirmngr daemon is up and running\n" -msgstr "" +msgstr "um daemon dirmngr está a correr\n" -#, fuzzy, c-format +#, c-format msgid "validation of certificate failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha na validação do certificado: %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate is valid\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "certificado é válido\n" -#, fuzzy, c-format +#, c-format msgid "certificate has been revoked\n" -msgstr "NOTA: a chave foi revogada" +msgstr "o certificado foi revogado\n" -#, fuzzy, c-format +#, c-format msgid "certificate check failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha na verificação do certificado: %s\n" -#, fuzzy, c-format -#| msgid "can't stat `%s': %s\n" +#, c-format msgid "got status: '%s'\n" -msgstr "impossível 'stat' a `%s': %s\n" +msgstr "recebi status: '%s'\n" -#, fuzzy, c-format -#| msgid "error writing secret keyring `%s': %s\n" +#, c-format msgid "error writing base64 encoding: %s\n" -msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" +msgstr "erro ao escrever codificação base64: %s\n" -#, fuzzy, c-format +#, c-format msgid "unsupported inquiry '%s'\n" -msgstr "" -"\n" -"Algoritmos suportados:\n" +msgstr "inquérito não suportado '%s'\n" #, c-format msgid "absolute file name expected\n" -msgstr "" +msgstr "esperado nome absoluto de ficheiro\n" #, c-format msgid "looking up '%s'\n" -msgstr "" +msgstr "procurando '%s'\n" msgid "list the contents of the CRL cache" -msgstr "" +msgstr "listar o conteúdo da cache de CRL" -#, fuzzy msgid "|FILE|load CRL from FILE into cache" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|carregar CRL de FILE para cache" msgid "|URL|fetch a CRL from URL" -msgstr "" +msgstr "|URL|buscar uma CRL de URL" msgid "shutdown the dirmngr" -msgstr "" +msgstr "terminar o dirmngr" msgid "flush the cache" -msgstr "" +msgstr "limpar a cache" msgid "allow online software version check" -msgstr "" +msgstr "permitir verificação online da versão do software" msgid "|N|do not return more than N items in one query" -msgstr "" +msgstr "|N|não retornar mais de N itens em uma consulta" msgid "Network related options" -msgstr "" +msgstr "Opções relacionadas à rede" msgid "route all network traffic via Tor" -msgstr "" +msgstr "direcionar todo o tráfego de rede via Tor" msgid "Configuration for HTTP servers" -msgstr "" +msgstr "Configurações para servidores HTTP" msgid "inhibit the use of HTTP" -msgstr "" +msgstr "inibir o uso de HTTP" msgid "ignore HTTP CRL distribution points" -msgstr "" +msgstr "ignorar os pontos de distribuição de CRL que são HTTP" msgid "|URL|redirect all HTTP requests to URL" -msgstr "" +msgstr "|URL|redirecionar todas os pedidos HTTP para URL" msgid "use system's HTTP proxy setting" -msgstr "" +msgstr "usar a definição de proxy HTTP do sistema" msgid "Configuration for OpenPGP servers" -msgstr "" +msgstr "Configurações para servidores OpenPGP" -#, fuzzy msgid "|URL|use keyserver at URL" -msgstr "não consegui processar a URI do servidor de chaves\n" +msgstr "|URL|usar servidor de chaves na URL" msgid "|FILE|use the CA certificates in FILE for HKP over TLS" -msgstr "" +msgstr "|FILE|usar os certificados CA em FILE para HKP sobre TLS" msgid "Configuration for X.509 servers" -msgstr "" +msgstr "Configurações para servidores X.509" msgid "inhibit the use of LDAP" -msgstr "" +msgstr "inibir o uso do LDAP" msgid "ignore LDAP CRL distribution points" -msgstr "" +msgstr "ignorar os pontos de distribuição de CRL que são LDAP" msgid "|HOST|use HOST for LDAP queries" -msgstr "" +msgstr "|HOST|usar HOST para consultas LDAP" msgid "do not use fallback hosts with --ldap-proxy" -msgstr "" +msgstr "não usar hosts de fallback com --ldap-proxy" -#, fuzzy msgid "|SPEC|use this keyserver to lookup keys" -msgstr "|ENDEREÇO|usar este servidor para buscar chaves" +msgstr "|SPEC|usar este servidor de chaves para procurar por chaves" -#, fuzzy msgid "|FILE|read LDAP server list from FILE" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|ler lista de servidores LDAP do FILE" msgid "add new servers discovered in CRL distribution points to serverlist" msgstr "" +"adicionar novos servidores descobertos em pontos de distribuição de CRL à " +"serverlist" msgid "|N|set LDAP timeout to N seconds" -msgstr "" +msgstr "|N|definir tempo limite LDAP para N segundos" msgid "Configuration for OCSP" -msgstr "" +msgstr "Configurações para OCSP" msgid "allow sending OCSP requests" -msgstr "" +msgstr "permitir enviar pedidos OCSP" msgid "ignore certificate contained OCSP service URLs" -msgstr "" +msgstr "ignorar URL de serviço OCSP contido no certificado" -#, fuzzy msgid "|URL|use OCSP responder at URL" -msgstr "não consegui processar a URI do servidor de chaves\n" +msgstr "|URL|usar o respondente de OCSP na URL" msgid "|FPR|OCSP response signed by FPR" -msgstr "" +msgstr "|FPR|resposta OCSP assinada por FPR" msgid "force loading of outdated CRLs" -msgstr "" +msgstr "forçar o carregar de CRLs desatualizados" -#, fuzzy -#| msgid "" -#| "@\n" -#| "(See the man page for a complete listing of all commands and options)\n" msgid "" "@\n" "(See the \"info\" manual for a complete listing of all commands and " "options)\n" msgstr "" "@\n" -"(Veja a página man para uma lista completa de comandos e opções)\n" +"(Veja o manual \"info\" para obter uma lista completa de todos os comandos e " +"opções)\n" -#, fuzzy msgid "Usage: @DIRMNGR@ [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @DIRMNGR@ [opções] (-h para ajuda)" msgid "" "Syntax: @DIRMNGR@ [options] [command [args]]\n" "Keyserver, CRL, and OCSP access for @GNUPG@\n" msgstr "" +"Sintaxe: @DIRMNGR@ [opções] [comando [args]]\n" +"Acesso a servidor de chaves, CRL, e OCSP para @GNUPG@\n" #, c-format msgid "valid debug levels are: %s\n" -msgstr "" +msgstr "os níveis de debug válidos são: %s\n" -#, fuzzy, c-format +#, c-format msgid "usage: %s [options] " -msgstr "uso: gpg [opções] " +msgstr "uso: %s [opções] " -#, fuzzy, c-format -#| msgid "%s not allowed with %s!\n" +#, c-format msgid "colons are not allowed in the socket name\n" -msgstr "%s não é permitido com %s!\n" +msgstr "'dois pontos' não são permitidos no nome do socket\n" -#, fuzzy, c-format +#, c-format msgid "fetching CRL from '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha ao buscar a CRL de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "processing CRL from '%s' failed: %s\n" -msgstr "criação de armadura falhou: %s\n" +msgstr "falha ao processar a CRL de '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: line too long - skipped\n" -msgstr "frase secreta demasiado longa\n" +msgstr "%s:%u: linha muito longa - ignorada\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: invalid fingerprint detected\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "%s:%u: impressão digital inválida detetada\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: read error: %s\n" -msgstr "armadura: %s\n" +msgstr "%s:%u: erro de leitura: %s\n" #, c-format msgid "%s:%u: garbage at end of line ignored\n" -msgstr "" +msgstr "%s:%u: lixo no final da linha ignorado\n" #, c-format msgid "SIGHUP received - re-reading configuration and flushing caches\n" -msgstr "" +msgstr "SIGHUP recebido - re-lendo a configuração e limpando as caches\n" #, c-format msgid "SIGUSR2 received - no action defined\n" -msgstr "" +msgstr "SIGUSR2 recebido - nenhuma ação definida\n" #, c-format msgid "SIGTERM received - shutting down ...\n" -msgstr "" +msgstr "SIGTERM recebido - terminando ...\n" #, c-format msgid "SIGTERM received - still %d active connections\n" -msgstr "" +msgstr "SIGTERM recebido - ainda há %d conexões ativas\n" -#, fuzzy, c-format +#, c-format msgid "shutdown forced\n" -msgstr "não processado" +msgstr "terminar forçado\n" #, c-format msgid "SIGINT received - immediate shutdown\n" -msgstr "" +msgstr "SIGINT recebido - terminando imediatamente\n" #, c-format msgid "signal %d received - no action defined\n" -msgstr "" +msgstr "sinal %d recebido - nenhuma ação definida\n" -#, fuzzy, c-format +#, c-format msgid "error accessing '%s': http status %u\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao aceder '%s': status http %u\n" #, c-format msgid "URL '%s' redirected to '%s' (%u)\n" -msgstr "" +msgstr "URL '%s' redirecionada para '%s' (%u)\n" -#, fuzzy, c-format +#, c-format msgid "too many redirections\n" -msgstr "demasiadas preferências `%c'\n" +msgstr "demasiados redirecionamentos\n" -#, fuzzy, c-format -#| msgid "writing to `%s'\n" +#, c-format msgid "redirection changed to '%s'\n" -msgstr "a escrever para `%s'\n" +msgstr "redirecionamento alterado para '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error printing log line: %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao mostrar linha de log: %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading log from ldap wrapper %d: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler log do wrapper ldap %d: %s\n" #, c-format msgid "ldap wrapper %d ready" -msgstr "" +msgstr "wrapper ldap %d pronto" #, c-format msgid "ldap wrapper %d ready: timeout\n" -msgstr "" +msgstr "wrapper ldap %d pronto: pausa\n" #, c-format msgid "ldap wrapper %d ready: exitcode=%d\n" -msgstr "" +msgstr "wrapper ldap %d pronto: exitcode=%d\n" -#, fuzzy, c-format +#, c-format msgid "waiting for ldap wrapper %d failed: %s\n" -msgstr "actualização falhou: %s\n" +msgstr "falha ao aguardar por wrapper ldap %d: %s\n" #, c-format msgid "ldap wrapper %d stalled - killing\n" -msgstr "" +msgstr "wrapper ldap %d obsoleto - matando\n" #, c-format msgid "invalid char 0x%02x in host name - not added\n" -msgstr "" +msgstr "char 0x%02x inválido no nome do host - não adicionado\n" -#, fuzzy, c-format +#, c-format msgid "adding '%s:%d' to the ldap server list\n" -msgstr "a procurar por \"%s\" no servidor HKP %s\n" +msgstr "adicionando '%s:%d' à lista de servidores ldap\n" -#, fuzzy, c-format +#, c-format msgid "malloc failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "malloc falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "'%s' is not an LDAP URL\n" -msgstr "%s: não é um base de dados de confiança\n" +msgstr "'%s' não é uma URL LDAP\n" #, c-format msgid "'%s' is an invalid LDAP URL\n" -msgstr "" +msgstr "'%s' é uma URL LDAP inválida\n" #, c-format msgid "ldap_search hit the size limit of the server\n" -msgstr "" +msgstr "ldap_search atingiu o tamanho limite do servidor\n" #, c-format msgid "%s:%u: password given without user\n" -msgstr "" +msgstr "%s:%u: senha dada sem utilizador\n" #, c-format msgid "%s:%u: ignoring unknown flag '%s'\n" -msgstr "" +msgstr "%s:%u: ignorando flag '%s' desconhecida\n" -#, fuzzy, c-format +#, c-format msgid "%s:%u: skipping this line\n" -msgstr " s = saltar esta chave\n" +msgstr "%s:%u: ignorando esta linha\n" -#, fuzzy, c-format -#| msgid "%s: invalid file version %d\n" +#, c-format msgid "invalid canonical S-expression found\n" -msgstr "%s: versão de ficheiro inválida %d\n" +msgstr "encontrada S-expression canónica inválida\n" -#, fuzzy, c-format +#, c-format msgid "gcry_md_open failed: %s\n" -msgstr "impossível abrir %s: %s\n" +msgstr "gcry_md_open falhou: %s\n" -#, fuzzy, c-format -#| msgid "update secret failed: %s\n" +#, c-format msgid "oops: ksba_cert_hash failed: %s\n" -msgstr "actualização da chave secreta falhou: %s\n" +msgstr "oops: ksba_cert_hash falhou: %s\n" #, c-format msgid "bad URL encoding detected\n" -msgstr "" +msgstr "detetada codificação de URL inválida\n" -#, fuzzy, c-format +#, c-format msgid "error reading from responder: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler do respondente: %s\n" #, c-format msgid "response from server too large; limit is %d bytes\n" -msgstr "" +msgstr "resposta do servidor muito grande; limite é %d bytes\n" -#, fuzzy msgid "OCSP request not possible due to Tor mode" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "pedido OCSP não é possível devido ao modo Tor" #, c-format msgid "OCSP request not possible due to disabled HTTP\n" -msgstr "" +msgstr "pedido OCSP não é possível devido a HTTP desabilitado\n" -#, fuzzy, c-format +#, c-format msgid "error setting OCSP target: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao definir o destino OCSP: %s\n" -#, fuzzy, c-format +#, c-format msgid "error building OCSP request: %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao criar o pedido OCSP: %s\n" -#, fuzzy, c-format +#, c-format msgid "error connecting to '%s': %s\n" -msgstr "erro na escrita do porta-chaves `%s': %s\n" +msgstr "erro ao conectar a '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error reading HTTP response for '%s': %s\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao ler a resposta HTTP para '%s': %s\n" -#, fuzzy, c-format +#, c-format msgid "error parsing OCSP response for '%s': %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao processar a resposta OCSP para '%s': %s\n" #, c-format msgid "OCSP responder at '%s' status: %s\n" -msgstr "" +msgstr "respondente OCSP no status '%s': %s\n" #, c-format msgid "failed to establish a hashing context for OCSP: %s\n" -msgstr "" +msgstr "falha ao estabelecer um contexto de hash para OCSP: %s\n" -#, fuzzy, c-format +#, c-format msgid "hashing the OCSP response for '%s' failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha ao fazer hashing da resposta OCSP para '%s': %s\n" #, c-format msgid "not signed by a default OCSP signer's certificate" -msgstr "" +msgstr "não assinado por um certificado de signatário OCSP pré-definido" -#, fuzzy, c-format +#, c-format msgid "allocating list item failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao alocar item de lista: %s\n" -#, fuzzy, c-format +#, c-format msgid "error getting responder ID: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter o ID do respondente: %s\n" #, c-format msgid "no suitable certificate found to verify the OCSP response\n" msgstr "" +"nenhum certificado adequado encontrado para verificar a resposta do OCSP\n" -#, fuzzy, c-format +#, c-format msgid "issuer certificate not found: %s\n" -msgstr "chave `%s' não encontrada: %s\n" +msgstr "certificado do emissor não encontrado: %s\n" #, c-format msgid "caller did not return the target certificate\n" -msgstr "" +msgstr "o chamador não retornou o certificado de destino\n" -#, fuzzy, c-format +#, c-format msgid "caller did not return the issuing certificate\n" -msgstr "gerar um certificado de revogação" +msgstr "o chamador não retornou o certificado de emissão\n" -#, fuzzy, c-format +#, c-format msgid "failed to allocate OCSP context: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao alocar contexto OCSP: %s\n" #, c-format msgid "no default OCSP responder defined\n" -msgstr "" +msgstr "nenhum respondente OCSP pré-definido\n" -#, fuzzy, c-format -#| msgid "no default secret keyring: %s\n" +#, c-format msgid "no default OCSP signer defined\n" -msgstr "sem porta-chaves público por omissão: %s\n" +msgstr "nenhum assinante OCSP pré-definido\n" #, c-format msgid "using default OCSP responder '%s'\n" -msgstr "" +msgstr "usando o respondente OCSP pré-definido '%s'\n" -#, fuzzy, c-format +#, c-format msgid "using OCSP responder '%s'\n" -msgstr "assinatura falhou: %s\n" +msgstr "usando o respondente OCSP '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error getting OCSP status for target certificate: %s\n" -msgstr "erro na criação da frase secreta: %s\n" +msgstr "erro ao obter o status OCSP para o certificado de destino: %s\n" #, c-format msgid "certificate status is: %s (this=%s next=%s)\n" -msgstr "" +msgstr "o status do certificado é: %s (este=%s próximo=%s)\n" msgid "good" -msgstr "" +msgstr "válido" -#, fuzzy, c-format +#, c-format msgid "certificate has been revoked at: %s due to: %s\n" -msgstr "NOTA: a chave foi revogada" +msgstr "o certificado foi revogado em: %s devido a: %s\n" #, c-format msgid "OCSP responder returned a status in the future\n" -msgstr "" +msgstr "o respondente OCSP retornou um status no futuro\n" #, c-format msgid "OCSP responder returned a non-current status\n" -msgstr "" +msgstr "o respondente OCSP retornou um status não atual\n" #, c-format msgid "OCSP responder returned an too old status\n" -msgstr "" +msgstr "o respondente OCSP retornou um status muito antigo\n" -#, fuzzy, c-format +#, c-format msgid "assuan_inquire(%s) failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "assuan_inquire(%s) falhou: %s\n" msgid "serialno missing in cert ID" -msgstr "" +msgstr "número de série ausente na ID do certificado" -#, fuzzy, c-format +#, c-format msgid "assuan_inquire failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "assuan_inquire falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "fetch_cert_by_url failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "fetch_cert_by_url falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "error sending data: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao enviar dados: %s\n" -#, fuzzy, c-format +#, c-format msgid "start_cert_fetch failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "start_cert_fetch falhou: %s\n" -#, fuzzy, c-format +#, c-format msgid "fetch_next_cert failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "fetch_next_cert falhou: %s\n" #, c-format msgid "max_replies %d exceeded\n" -msgstr "" +msgstr "excedido max_replies %d\n" -#, fuzzy, c-format +#, c-format msgid "can't allocate control structure: %s\n" -msgstr "impossível criar `%s': %s\n" +msgstr "não é possível alocar a estrutura de controle: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to allocate assuan context: %s\n" -msgstr "%s: falha ao criar tabela de dispersão: %s\n" +msgstr "falha ao alocar contexto assuan: %s\n" -#, fuzzy, c-format -#| msgid "failed to initialize the TrustDB: %s\n" +#, c-format msgid "failed to initialize the server: %s\n" -msgstr "falha ao inicializar a base de dados de confiança: %s\n" +msgstr "falha ao inicializar o servidor: %s\n" -#, fuzzy, c-format +#, c-format msgid "failed to the register commands with Assuan: %s\n" -msgstr "falha ao criar 'cache' do porta-chaves: %s\n" +msgstr "falha ao registar comandos com Assuan: %s\n" #, c-format msgid "Assuan accept problem: %s\n" -msgstr "" +msgstr "problema de aceitação Assuan: %s\n" -#, fuzzy, c-format -#| msgid "signing failed: %s\n" +#, c-format msgid "Assuan processing failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "falha no processamento do Assuan: %s\n" #, c-format msgid "accepting root CA not marked as a CA" -msgstr "" +msgstr "aceitando a CA raiz não marcada como uma CA" -#, fuzzy, c-format -#| msgid "checking the trustdb\n" +#, c-format msgid "CRL checking too deeply nested\n" -msgstr "a verificar a base de dados de confiança\n" +msgstr "verificação de CRL muito aprofundadamente aninhada\n" msgid "not checking CRL for" -msgstr "" +msgstr "não verificando CRL para" -#, fuzzy msgid "checking CRL for" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "verificando CRL para" -#, fuzzy, c-format +#, c-format msgid "checking trustworthiness of root certificate failed: %s\n" -msgstr "verificação da assinatura criada falhou: %s\n" +msgstr "falha na verificação da confiança do certificado raiz: %s\n" -#, fuzzy, c-format +#, c-format msgid "certificate chain is good\n" -msgstr "preferência %c%lu duplicada\n" +msgstr "a corrente de certificados é válida\n" #, c-format msgid "certificate should not have been used for CRL signing\n" -msgstr "" +msgstr "certificado não deveria ter sido usado para assinatura de CRL\n" -#, fuzzy msgid "quiet" -msgstr "sair" +msgstr "silencioso" msgid "print data out hex encoded" -msgstr "" +msgstr "imprimir dados codificados em hex" msgid "decode received data lines" -msgstr "" +msgstr "descodificar linhas de dados recebidas" msgid "connect to the dirmngr" -msgstr "" +msgstr "conectar ao dirmngr" msgid "connect to the keyboxd" -msgstr "" +msgstr "conectar ao keyboxd" msgid "|NAME|connect to Assuan socket NAME" -msgstr "" +msgstr "|NAME|conectar ao socket Assuan NAME" msgid "|ADDR|connect to Assuan server at ADDR" -msgstr "" +msgstr "|ADDR|conectar ao servidor Assuan em ADDR" msgid "run the Assuan server given on the command line" -msgstr "" +msgstr "execute o servidor Assuan fornecido na linha de comando" msgid "do not use extended connect mode" -msgstr "" +msgstr "não usar o modo de conexão estendida" -#, fuzzy msgid "|FILE|run commands from FILE on startup" -msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" +msgstr "|FILE|executar comandos do FILE na inicialização" msgid "run /subst on startup" -msgstr "" +msgstr "executar /subst na inicialização" -#, fuzzy msgid "Usage: @GPG@-connect-agent [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPG@-connect-agent [opções] (-h para ajuda)" msgid "" "Syntax: @GPG@-connect-agent [options]\n" "Connect to a running agent and send commands\n" msgstr "" +"Sintaxe: @GPG@-connect-agent [opções]\n" +"Conectar-se a um agent em execução e enviar comandos\n" #, c-format msgid "option \"%s\" requires a program and optional arguments\n" -msgstr "" +msgstr "a opção \"%s\" requer um programa e argumentos opcionais\n" #, c-format msgid "option \"%s\" ignored due to \"%s\"\n" -msgstr "" +msgstr "opção \"%s\" ignorada devido a \"%s\"\n" -#, fuzzy, c-format +#, c-format msgid "receiving line failed: %s\n" -msgstr "remoção do bloco de chave falhou: %s\n" +msgstr "falha ao receber linha: %s\n" -#, fuzzy, c-format +#, c-format msgid "line too long - skipped\n" -msgstr "frase secreta demasiado longa\n" +msgstr "linha muito longa - ignorada\n" #, c-format msgid "line shortened due to embedded Nul character\n" -msgstr "" +msgstr "linha encurtada devido ao caractere Nul incorporado\n" -#, fuzzy, c-format +#, c-format msgid "unknown command '%s'\n" -msgstr "destinatário por omissão desconhecido `%s'\n" +msgstr "comando desconhecido '%s'\n" -#, fuzzy, c-format +#, c-format msgid "sending line failed: %s\n" -msgstr "assinatura falhou: %s\n" +msgstr "falha ao enviar linha: %s\n" -#, fuzzy, c-format +#, c-format msgid "no keybox daemon running in this session\n" -msgstr "o gpg-agent não está disponível nesta sessão\n" +msgstr "nenhum daemon keybox em execução nesta sessão\n" -#, fuzzy, c-format +#, c-format msgid "error sending standard options: %s\n" -msgstr "erro ao enviar para `%s': %s\n" +msgstr "erro ao enviar opções padrão: %s\n" msgid "OpenPGP" -msgstr "" +msgstr "OpenPGP" msgid "S/MIME" -msgstr "" +msgstr "S/MIME" -#, fuzzy msgid "Public Keys" -msgstr "a chave pública é %08lX\n" +msgstr "Chaves Públicas" msgid "Private Keys" -msgstr "" +msgstr "Chaves Privadas" msgid "Smartcards" -msgstr "" +msgstr "Smartcards" msgid "TPM" -msgstr "" +msgstr "TPM" -#, fuzzy -#| msgid "network error" msgid "Network" -msgstr "erro na rede" +msgstr "Rede" -#, fuzzy msgid "Passphrase Entry" -msgstr "frase secreta incorrecta" +msgstr "Entrada de Frase-secreta" -#, fuzzy msgid "Component not suitable for launching" -msgstr "chave pública não encontrada" +msgstr "Componente não adequado para lançamento" #, c-format msgid "Configuration file of component %s is broken\n" -msgstr "" +msgstr "O ficheiro de configuração do componente %s está quebrado\n" -#, fuzzy, c-format -#| msgid "Please use the command \"toggle\" first.\n" +#, c-format msgid "Note: Use the command \"%s%s\" to get details.\n" -msgstr "Por favor utilize o comando \"toggle\" primeiro.\n" +msgstr "Nota: Usar o comando \"%s%s\" para obter detalhes.\n" #, c-format msgid "External verification of component %s failed" -msgstr "" +msgstr "Falha na verificação externa do componente %s" msgid "Note that group specifications are ignored\n" -msgstr "" +msgstr "Repare que as especificações do grupo são ignoradas\n" -#, fuzzy, c-format +#, c-format msgid "error closing '%s'\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao fechar '%s'\n" -#, fuzzy, c-format +#, c-format msgid "error parsing '%s'\n" -msgstr "erro na leitura de `%s': %s\n" +msgstr "erro ao processar '%s'\n" msgid "list all components" -msgstr "" +msgstr "listar todos os componentes" msgid "check all programs" -msgstr "" +msgstr "verificar todos os programas" msgid "|COMPONENT|list options" -msgstr "" +msgstr "|COMPONENT|listar opções" msgid "|COMPONENT|change options" -msgstr "" +msgstr "|COMPONENT|alterar opções" msgid "|COMPONENT|check options" -msgstr "" +msgstr "|COMPONENT|verificar opções" msgid "apply global default values" -msgstr "" +msgstr "aplicar valores globais pré-definidos" msgid "|FILE|update configuration files using FILE" -msgstr "" +msgstr "|FILE|atualizar ficheiros de configuração usando FILE" msgid "get the configuration directories for @GPGCONF@" -msgstr "" +msgstr "obter as pastas de configuração para @GPGCONF@" -#, fuzzy msgid "list global configuration file" -msgstr "criado um novo ficheiro de configuração `%s'\n" +msgstr "listar ficheiro de configuração global" -#, fuzzy msgid "check global configuration file" -msgstr "criado um novo ficheiro de configuração `%s'\n" +msgstr "verificar ficheiro de configuração global" -#, fuzzy -#| msgid "update the trust database" msgid "query the software version database" -msgstr "actualizar a base de dados de confiança" +msgstr "consultar a base de dados da versão do software" msgid "reload all or a given component" -msgstr "" +msgstr "recarregar todos ou um determinado componente" msgid "launch a given component" -msgstr "" +msgstr "lançar um determinado componente" msgid "kill a given component" -msgstr "" +msgstr "matar um determinado componente" msgid "use as output file" msgstr "usar como ficheiro de saída" msgid "activate changes at runtime, if possible" -msgstr "" +msgstr "ativar alterações em tempo de execução, se possível" -#, fuzzy msgid "Usage: @GPGCONF@ [options] (-h for help)" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "Uso: @GPGCONF@ [opções] (-h para ajuda)" msgid "" "Syntax: @GPGCONF@ [options]\n" "Manage configuration options for tools of the @GNUPG@ system\n" msgstr "" +"Sintaxe: @GPGCONF@ [opções]\n" +"Gerir opções de configuração para as ferramentas do sistema @GNUPG@\n" msgid "Need one component argument" -msgstr "" +msgstr "Precisa de um argumento de componente" -#, fuzzy msgid "Component not found" -msgstr "chave pública não encontrada" +msgstr "Componente não encontrado" -#, fuzzy msgid "No argument allowed" -msgstr "a escrever chave privada para `%s'\n" +msgstr "Nenhum argumento permitido" -#, fuzzy msgid "Usage: gpg-check-pattern [options] patternfile (-h for help)\n" -msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" +msgstr "" +"Uso: gpg-check-pattern [opções] ficheiro-de-padrões (-h para obter ajuda)\n" msgid "" "Syntax: gpg-check-pattern [options] patternfile\n" "Check a passphrase given on stdin against the patternfile\n" msgstr "" +"Sintaxe: gpg-check-pattern [opções] ficheiro-de-padrões\n" +"Verificar uma frase-secreta dada em stdin em relação a um ficheiro de " +"padrão\n" -#, fuzzy, c-format +#, c-format msgid "Note: key %s is already stored on the card!\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "Nota: a chave %s já está armazenada no cartão!\n" -#, fuzzy, c-format +#, c-format msgid "Note: Keys are already stored on the card!\n" -msgstr "ignorado: a chave secreta já está presente\n" +msgstr "Nota: As chaves já estão armazenadas no cartão!\n" #, c-format msgid "Replace existing key %s ? (y/N) " -msgstr "" +msgstr "Substituir a chave %s existente? (s/N) " #, c-format msgid "%s card no. %s detected\n" -msgstr "" +msgstr "cartão %s nº %s detetado\n" #, c-format msgid "User Interaction Flag is set to \"%s\" - can't change\n" msgstr "" +"a User Interaction Flag está definido como \"%s\" - não é possível alterar\n" #, c-format msgid "" "Warning: Setting the User Interaction Flag to \"%s\"\n" " can only be reverted using a factory reset!\n" msgstr "" +"Aviso: Definindo a User Interaction Flag como \"%s\" só\n" +" pode ser revertida usando uma reset de fábrica!\n" #, c-format msgid "Please use \"uif --yes %d %s\"\n" -msgstr "" +msgstr "Use \"uif --yes %d %s\"\n" -#, fuzzy msgid "authenticate to the card" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "autenticar no cartão" msgid "send a reset to the card daemon" -msgstr "" +msgstr "enviar uma reset para o daemon do cartão" -#, fuzzy -#| msgid "|NAME|use NAME as default recipient" msgid "setup KDF for PIN authentication" -msgstr "|NOME|usar NOME como destinatário por omissão" +msgstr "configurar o KDF para autenticação por PIN" -#, fuzzy -#| msgid "change the expire date" msgid "change a private data object" -msgstr "muda a data de validade" +msgstr "alterar um objeto de dados privados" -#, fuzzy msgid "read a certificate from a data object" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "ler um certificado a partir de um objeto de dados" -#, fuzzy msgid "store a certificate to a data object" -msgstr "chave %08lX: certificado de revogação \"%s\" adicionado\n" +msgstr "armazenar um certificado em um objeto de dados" msgid "store a private key to a data object" -msgstr "" +msgstr "armazenar uma chave privada em um objeto de dados" msgid "Yubikey management commands" -msgstr "" +msgstr "comandos de gerir uma Yubikey" msgid "manage the command history" -msgstr "" - -#, fuzzy -#~| msgid "selected digest algorithm is invalid\n" -#~ msgid "selected AEAD algorithm is invalid\n" -#~ msgstr "o algoritmo de \"digest\" selecionado é inválido\n" - -#, fuzzy -#~| msgid "invalid personal cipher preferences\n" -#~ msgid "invalid personal AEAD preferences\n" -#~ msgstr "preferências pessoais de cifra inválidas\n" - -#, fuzzy -#~ msgid "AEAD algorithm '%s' may not be used in %s mode\n" -#~ msgstr "não pode utilizar %s enquanto estiver no modo %s\n" - -#~ msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" -#~ msgstr "" -#~ "ao forçar a cifra simétrica %s (%d) viola as preferências do " -#~ "destinatário\n" - -#, fuzzy -#~ msgid "error writing to temporary file: %s\n" -#~ msgstr "a escrever para `%s'\n" - -#, fuzzy -#~| msgid "Key is superseded" -#~ msgid "run in supervised mode" -#~ msgstr "A chave foi substituída" - -#~ msgid "Name may not start with a digit\n" -#~ msgstr "O nome não pode começar com um dígito\n" - -#~ msgid "Name must be at least 5 characters long\n" -#~ msgstr "O nome deve ter pelo menos 5 caracteres\n" - -#, fuzzy -#~ msgid "selfsigned certificate has a BAD signature" -#~ msgstr "verificar uma assinatura" - -#, fuzzy -#~ msgid "requesting key %s from %s server %s\n" -#~ msgstr "a pedir a chave %08lX de %s\n" - -#, fuzzy -#~ msgid "could not parse keyserver\n" -#~ msgstr "não consegui processar a URI do servidor de chaves\n" - -#, fuzzy -#~| msgid "|NAME|set terminal charset to NAME" -#~ msgid "|NAME|connect to host NAME" -#~ msgstr "" -#~ "|NOME|definir mapa de caracteres do terminal como\n" -#~ "NOME" - -#, fuzzy -#~| msgid "|NAME|use NAME as default recipient" -#~ msgid "|NAME|use user NAME for authentication" -#~ msgstr "|NOME|usar NOME como destinatário por omissão" - -#, fuzzy -#~| msgid "Usage: gpg [options] [files] (-h for help)" -#~ msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#, fuzzy -#~| msgid "invalid import options\n" -#~ msgid "invalid port number %d\n" -#~ msgstr "opções de importação inválidas\n" - -#, fuzzy -#~ msgid "error writing to stdout: %s\n" -#~ msgstr "erro na escrita do porta-chaves `%s': %s\n" - -#, fuzzy -#~ msgid "attribute '%s' not found\n" -#~ msgstr "chave `%s' não encontrada: %s\n" - -#, fuzzy -#~| msgid "reading from `%s'\n" -#~ msgid "processing url '%s'\n" -#~ msgstr "lendo de `%s'\n" - -#, fuzzy -#~| msgid " w/o user IDs: %lu\n" -#~ msgid " user '%s'\n" -#~ msgstr " sem IDs de utilizadores: %lu\n" - -#, fuzzy -#~ msgid " pass '%s'\n" -#~ msgstr " ou \"" - -#, fuzzy -#~ msgid " host '%s'\n" -#~ msgstr " ou \"" - -#, fuzzy -#~| msgid " not imported: %lu\n" -#~ msgid " port %d\n" -#~ msgstr " não importadas: %lu\n" - -#, fuzzy -#~ msgid " DN '%s'\n" -#~ msgstr " ou \"" - -#, fuzzy -#~ msgid " attr '%s'\n" -#~ msgstr " ou \"" - -#, fuzzy -#~| msgid "WARNING: using insecure memory!\n" -#~ msgid "WARNING: using first attribute only\n" -#~ msgstr "AVISO: a utilizar memória insegura!\n" - -#, fuzzy -#~ msgid "LDAP init to '%s:%d' failed: %s\n" -#~ msgstr "criação de armadura falhou: %s\n" - -#, fuzzy -#~ msgid "LDAP init to '%s' failed: %s\n" -#~ msgstr "criação de armadura falhou: %s\n" - -#, fuzzy -#~ msgid "LDAP init to '%s' done\n" -#~ msgstr "criação de armadura falhou: %s\n" - -#, fuzzy -#~ msgid "binding to '%s:%d' failed: %s\n" -#~ msgstr "criação de armadura falhou: %s\n" - -#, fuzzy -#~| msgid "dearmoring failed: %s\n" -#~ msgid "searching '%s' failed: %s\n" -#~ msgstr "retirada de armadura falhou: %s\n" - -#, fuzzy -#~ msgid "Suggest a random passphrase." -#~ msgstr "muda a frase secreta" - -#, fuzzy -#~ msgid "no authentication key for ssh on card: %s\n" -#~ msgstr "erro ao escrever no porta-chaves secreto `%s': %s\n" - -#, fuzzy -#~ msgid "use a log file for the server" -#~ msgstr "procurar chaves num servidor de chaves" - -#, fuzzy -#~ msgid "argument not expected" -#~ msgstr "a escrever chave privada para `%s'\n" - -#, fuzzy -#~ msgid "read error" -#~ msgstr "erro de leitura" - -#, fuzzy -#~ msgid "keyword too long" -#~ msgstr "frase secreta demasiado longa\n" - -#, fuzzy -#~ msgid "missing argument" -#~ msgstr "argumento inválido" - -#, fuzzy -#~| msgid "invalid armor" -#~ msgid "invalid argument" -#~ msgstr "armadura inválida" - -#, fuzzy -#~ msgid "invalid command" -#~ msgstr "comandos em conflito\n" - -#, fuzzy -#~ msgid "invalid alias definition" -#~ msgstr "opções de importação inválidas\n" - -#, fuzzy -#~ msgid "out of core" -#~ msgstr "não processado" - -#, fuzzy -#~ msgid "invalid meta command" -#~ msgstr "comandos em conflito\n" - -#, fuzzy -#~ msgid "unknown meta command" -#~ msgstr "destinatário por omissão desconhecido `%s'\n" - -#, fuzzy -#~| msgid "unexpected data" -#~ msgid "unexpected meta command" -#~ msgstr "dados inesperados" - -#, fuzzy -#~ msgid "invalid option" -#~ msgstr "opções de importação inválidas\n" - -#, fuzzy -#~ msgid "invalid command \"%.50s\"\n" -#~ msgstr "Comando inválido (tente \"help\")\n" - -#, fuzzy -#~ msgid "invalid option \"%.50s\"\n" -#~ msgstr "opções de importação inválidas\n" - -#, fuzzy -#~| msgid "NOTE: no default option file `%s'\n" -#~ msgid "Note: no default option file '%s'\n" -#~ msgstr "NOTA: ficheiro de opções por omissão `%s' inexistente\n" - -#, fuzzy -#~| msgid "option file `%s': %s\n" -#~ msgid "option file '%s': %s\n" -#~ msgstr "ficheiro de opções `%s': %s\n" - -#, fuzzy -#~| msgid "you may not use %s while in %s mode\n" -#~ msgid "keyserver option \"%s\" may not be used in %s mode\n" -#~ msgstr "não pode utilizar %s enquanto estiver no modo %s\n" - -#, fuzzy -#~ msgid "unable to execute program '%s': %s\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid "unable to execute external program\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid "unable to read external program response: %s\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid " (%d) ECC and ECC\n" -#~ msgstr " (%d) DSA e ElGamal (por omissão)\n" - -#, fuzzy -#~ msgid "run without asking a user" -#~ msgstr "Sair sem gravar? " - -#, fuzzy -#~| msgid "NOTE: old default options file `%s' ignored\n" -#~ msgid "Note: old default options file '%s' ignored\n" -#~ msgstr "NOTA: o ficheiro antigo de opções por omissão `%s' foi ignorado\n" - -#, fuzzy -#~ msgid "" -#~ "@\n" -#~ "Commands:\n" -#~ " " -#~ msgstr "" -#~ "@Comandos:\n" -#~ " " - -#, fuzzy -#~ msgid "decryption modus" -#~ msgstr "decifragem correcta\n" - -#, fuzzy -#~ msgid "encryption modus" -#~ msgstr "decifragem correcta\n" - -#, fuzzy -#~ msgid "program filename" -#~ msgstr "--store [nome_do_ficheiro]" - -#, fuzzy -#~ msgid "Usage: symcryptrun [options] (-h for help)" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#, fuzzy -#~ msgid "%s on %s aborted with status %i\n" -#~ msgstr "%s não é permitido com %s!\n" - -#, fuzzy -#~ msgid "%s on %s failed with status %i\n" -#~ msgstr "impossível abrir %s: %s\n" - -#, fuzzy -#~ msgid "can't create temporary directory '%s': %s\n" -#~ msgstr "%s: impossível criar directoria: %s\n" - -#, fuzzy -#~ msgid "could not open %s for writing: %s\n" -#~ msgstr "impossível abrir %s: %s\n" - -#, fuzzy -#~ msgid "error closing %s: %s\n" -#~ msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy -#~ msgid "could not create pipe: %s\n" -#~ msgstr "impossível criar %s: %s\n" - -#, fuzzy -#~ msgid "could not create pty: %s\n" -#~ msgstr "impossível criar %s: %s\n" - -#, fuzzy -#~ msgid "execv failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~ msgid "select failed: %s\n" -#~ msgstr "remoção do bloco de chave falhou: %s\n" - -#, fuzzy -#~ msgid "read failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~ msgid "pty read failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~ msgid "waitpid failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~ msgid "cannot allocate infile string: %s\n" -#~ msgstr "impossível criar `%s': %s\n" - -#, fuzzy -#~ msgid "cannot allocate outfile string: %s\n" -#~ msgstr "impossível criar `%s': %s\n" - -#, fuzzy -#~ msgid "class %s is not supported\n" -#~ msgstr "algoritmo de protecção %d%s não é suportado\n" - -#, fuzzy -#~ msgid " using certificate ID 0x%08lX\n" -#~ msgstr "erro na criação da frase secreta: %s\n" - -#, fuzzy -#~ msgid "male" -#~ msgstr "enable" - -#, fuzzy -#~ msgid "female" -#~ msgstr "enable" - -#, fuzzy -#~ msgid "unspecified" -#~ msgstr "Nenhum motivo especificado" - -#, fuzzy -#~ msgid "error creating 'ultimately_trusted_keys' TOFU table: %s\n" -#~ msgstr "erro na criação da frase secreta: %s\n" - -#, fuzzy -#~ msgid "error creating 'encryptions' TOFU table: %s\n" -#~ msgstr "erro ao enviar para `%s': %s\n" - -#, fuzzy -#~ msgid "resetting keydb: %s\n" -#~ msgstr "erro na escrita do porta-chaves `%s': %s\n" - -#, fuzzy -#~ msgid "error setting TOFU binding's policy to %s\n" -#~ msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy -#~ msgid "%s: Verified %ld~signature in the past %s." -#~ msgid_plural "%s: Verified %ld~signatures in the past %s." -#~ msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -#~ msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" - -#, fuzzy -#~ msgid "Encrypted %ld~message in the past %s." -#~ msgid_plural "Encrypted %ld~messages in the past %s." -#~ msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -#~ msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" - -#, fuzzy -#~| msgid "error writing public keyring `%s': %s\n" -#~ msgid "error setting policy for key %s, user id \"%s\": %s" -#~ msgstr "erro ao escrever no porta-chaves público `%s': %s\n" - -#, fuzzy -#~ msgid "error looking up: %s\n" -#~ msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy -#~| msgid "error creating keyring `%s': %s\n" -#~ msgid "Warning: %s appears in the keyring %d times\n" -#~ msgstr "erro ao criar porta-chaves `%s': %s\n" - -#, fuzzy -#~ msgid "error retrieving '%s': http status %u\n" -#~ msgstr "erro na leitura de `%s': %s\n" - -#, fuzzy -#~ msgid "npth_select failed: %s - waiting 1s\n" -#~ msgstr "actualização da chave secreta falhou: %s\n" - -#, fuzzy -#~ msgid "reading from ldap wrapper %d failed: %s\n" -#~ msgstr "remoção do bloco de chave falhou: %s\n" - -#, fuzzy -#~ msgid "What keysize do you want for the Signature key? (%u) " -#~ msgstr "Qual o tamanho de chave desejado? (1024) " - -#, fuzzy -#~ msgid "What keysize do you want for the Encryption key? (%u) " -#~ msgstr "Qual o tamanho de chave desejado? (1024) " - -#, fuzzy -#~ msgid "What keysize do you want for the Authentication key? (%u) " -#~ msgstr "Qual o tamanho de chave desejado? (1024) " - -#, fuzzy -#~ msgid "listen() failed: %s\n" -#~ msgstr "actualização falhou: %s\n" - -#, fuzzy -#~| msgid "new configuration file `%s' created\n" -#~ msgid "new configuration file '%s' created\n" -#~ msgstr "criado um novo ficheiro de configuração `%s'\n" - -#, fuzzy -#~| msgid "WARNING: options in `%s' are not yet active during this run\n" -#~ msgid "WARNING: options in '%s' are not yet active during this run\n" -#~ msgstr "AVISO: opções em `%s' ainda não estão activas nesta execução\n" - -#, fuzzy -#~| msgid "Key generation failed: %s\n" -#~ msgid "User ID revocation failed: %s\n" -#~ msgstr "A geração de chaves falhou: %s\n" - -#, fuzzy -#~ msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]" -#~ msgstr "muda a frase secreta" - -#~ msgid "DSA requires the use of a 160 bit hash algorithm\n" -#~ msgstr "" -#~ "DSA necessita de utilização de uma algoritmo de dispersão de 160 bit\n" - -#~ msgid "--store [filename]" -#~ msgstr "--store [nome_do_ficheiro]" - -#~ msgid "--symmetric [filename]" -#~ msgstr "--symmetric [nome_do_ficheiro]" - -#~ msgid "--encrypt [filename]" -#~ msgstr "--encrypt [nome_do_ficheiro]" - -#, fuzzy -#~ msgid "--symmetric --encrypt [filename]" -#~ msgstr "--sign --encrypt [nome_do_ficheiro]" - -#~ msgid "--sign [filename]" -#~ msgstr "--sign [nome_do_ficheiro]" - -#~ msgid "--sign --encrypt [filename]" -#~ msgstr "--sign --encrypt [nome_do_ficheiro]" - -#, fuzzy -#~ msgid "--symmetric --sign --encrypt [filename]" -#~ msgstr "--sign --encrypt [nome_do_ficheiro]" - -#~ msgid "--sign --symmetric [filename]" -#~ msgstr "--sign --symmetric [nome_do_ficheiro]" - -#~ msgid "--clear-sign [filename]" -#~ msgstr "--clear-sign [nome_do_ficheiro]" - -#~ msgid "--decrypt [filename]" -#~ msgstr "--decrypt [nome_do_ficheiro]" - -#~ msgid "--sign-key user-id" -#~ msgstr "--sign-key id-utilizador" - -#~ msgid "--lsign-key user-id" -#~ msgstr "--lsign-key id-utilizador" - -#~ msgid "--edit-key user-id [commands]" -#~ msgstr "--edit-key id-utilizador [comandos]" - -#, fuzzy -#~ msgid "--passwd " -#~ msgstr "--sign-key id-utilizador" - -#~ msgid "[filename]" -#~ msgstr "[nome_do_ficheiro]" - -#, fuzzy -#~ msgid "shadowing the key failed: %s\n" -#~ msgstr "remoção do bloco de chave falhou: %s\n" - -#, fuzzy -#~ msgid "available TOFU policies:\n" -#~ msgstr "desactiva uma chave" - -#, fuzzy -#~ msgid "%ld message signed" -#~ msgid_plural "%ld messages signed" -#~ msgstr[0] "|algo [ficheiros]|imprimir \"digests\" de mensagens" -#~ msgstr[1] "|algo [ficheiros]|imprimir \"digests\" de mensagens" - -#~ msgid "communication problem with gpg-agent\n" -#~ msgstr "problemas na comunicação com o gpg-agent\n" - -#, fuzzy -#~ msgid "canceled by user\n" -#~ msgstr "cancelado pelo utilizador\n" - -#, fuzzy -#~ msgid "problem with the agent\n" -#~ msgstr "problema com o agente: o agente returnou 0x%lx\n" - -#, fuzzy -#~ msgid "problem with the agent (unexpected response \"%s\")\n" -#~ msgstr "problema com o agente: o agente returnou 0x%lx\n" - -#, fuzzy -#~ msgid "unknown TOFU DB format '%s'\n" -#~ msgstr "destinatário por omissão desconhecido `%s'\n" - -#, fuzzy -#~ msgid "" -#~ "Please enter the passphrase to unlock the secret key for the OpenPGP " -#~ "certificate:\n" -#~ "\"%.*s\"\n" -#~ "%u-bit %s key, ID %s,\n" -#~ "created %s%s.\n" -#~ msgstr "" -#~ "Precisa de uma frase secreta para desbloquear a chave secreta do " -#~ "utilizador:\n" -#~ "\n" -#~ "\"%.*s\"\n" -#~ "chave %u bits %s, ID %08lx, criada %s%s\n" - -#, fuzzy -#~ msgid "" -#~ "You need a passphrase to unlock the secret key for\n" -#~ "user: \"%s\"\n" -#~ msgstr "" -#~ "\n" -#~ "Você precisa de uma frase secreta para desbloquear a chave secreta do\n" -#~ "utilizador: \"" - -#, fuzzy -#~ msgid "%u-bit %s key, ID %s, created %s" -#~ msgstr "chave de %u-bit/%s, ID %08lX, criada em %s" - -#, fuzzy -#~ msgid "can't access directory '%s': %s\n" -#~ msgstr "%s: impossível criar directoria: %s\n" - -#~ msgid "you found a bug ... (%s:%d)\n" -#~ msgstr "você encontrou um bug ... (%s:%d)\n" - -#, fuzzy -#~| msgid "%d user IDs without valid self-signatures detected\n" -#~ msgid "%d user ID without valid self-signature detected\n" -#~ msgid_plural "%d user IDs without valid self-signatures detected\n" -#~ msgstr[0] "%d IDs de utilizadores sem auto-assinaturas válidas detectados\n" -#~ msgstr[1] "%d IDs de utilizadores sem auto-assinaturas válidas detectados\n" - -#~ msgid "moving a key signature to the correct place\n" -#~ msgstr "a mover a assinatura da chave para o local correcto\n" - -#~ msgid "%d signatures not checked due to missing keys\n" -#~ msgstr "%d assinaturas não verificadas por falta de chaves\n" - -#~ msgid "%d signatures not checked due to errors\n" -#~ msgstr "%d assinaturas não verificadas devido a erros\n" - -#~ msgid "1 user ID without valid self-signature detected\n" -#~ msgstr "1 ID de utilizador sem auto-assinatura válida detectado\n" - -#, fuzzy -#~ msgid "User ID \"%s\": %d signatures removed\n" -#~ msgstr "Utilizador \"%s\" está revocado." - -#~ msgid "" -#~ "You need a Passphrase to protect your secret key.\n" -#~ "\n" -#~ msgstr "" -#~ "Você precisa de uma frase secreta para proteger a sua chave.\n" -#~ "\n" - -#, fuzzy -#~ msgid "" -#~ "Please enter a passphrase to protect the off-card backup of the new " -#~ "encryption key." -#~ msgstr "Por favor digite a frase secreta \n" - -#~ msgid "passphrase not correctly repeated; try again" -#~ msgstr "a frase secreta não foi repetida corretamente; tente outra vez" - -#~ msgid "%s.\n" -#~ msgstr "%s.\n" - -#~ msgid "" -#~ "You don't want a passphrase - this is probably a *bad* idea!\n" -#~ "I will do it anyway. You can change your passphrase at any time,\n" -#~ "using this program with the option \"--edit-key\".\n" -#~ "\n" -#~ msgstr "" -#~ "Você não quer uma frase secreta - provavelmente isto é uma *má* idéia!\n" -#~ "Vou continuar assim mesmo. Você pode mudar sua frase secreta a\n" -#~ "qualquer hora, usando este programa com a opção \"--edit-key\".\n" -#~ "\n" - -#, fuzzy -#~ msgid "storing key onto card failed: %s\n" -#~ msgstr "remoção do bloco de chave falhou: %s\n" - -#, fuzzy -#~| msgid "1 bad signature\n" -#~ msgid "1 good signature\n" -#~ msgstr "1 assinatura incorrecta\n" - -#, fuzzy -#~ msgid "%lu keys cached (%lu signatures)\n" -#~ msgstr "%lu chave verificadas (%lu assinaturas)\n" - -#, fuzzy -#~ msgid "refreshing 1 key from %s\n" -#~ msgstr "a pedir a chave %08lX de %s\n" - -#, fuzzy -#~ msgid "sending key %s to %s server %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "public key %s is %lu seconds newer than the signature\n" -#~ msgstr "a chave pública %08lX é %lu segundos mais nova que a assinatura\n" - -#, fuzzy -#~ msgid "" -#~ "key %s was created %lu seconds in the future (time warp or clock " -#~ "problem)\n" -#~ msgstr "" -#~ "a chave foi criada %lu segundos no futuro\n" -#~ "(viagem no tempo ou problema no relógio)\n" - -#, fuzzy -#~| msgid "can't open the keyring" -#~ msgid "Failed to open the keyring DB.\n" -#~ msgstr "não é possível abrir o porta-chaves" - -#, fuzzy -#~ msgid "Failed to parse '%s'.\n" -#~ msgstr "impossível abrir `%s': %s\n" - -#, fuzzy -#~ msgid "error looking up secret key \"%s\": %s\n" -#~ msgstr "erro na leitura do bloco de chave secreto `%s': %s\n" - -#, fuzzy -#~ msgid "Please select at most one subkey.\n" -#~ msgstr "Por favor seleccione no máximo uma chave secundária.\n" - -#, fuzzy -#~ msgid "malformed %s environment variable\n" -#~ msgstr "variável de ambiente GPG_AGENT_INFO inválida\n" - -#, fuzzy -#~ msgid "dirmngr protocol version %d is not supported\n" -#~ msgstr "a versão %d do protocolo gpg-agent não é suportada\n" - -#, fuzzy -#~ msgid "toggle between the secret and public key listings" -#~ msgstr "alterna entre listagem de chave secreta e pública" - -#, fuzzy -#~ msgid "WARNING: keyserver option '%s' is not used on this platform\n" -#~ msgstr "AVISO: opções em `%s' ainda não estão activas nesta execução\n" - -#~ msgid "gpg-agent is not available in this session\n" -#~ msgstr "o gpg-agent não está disponível nesta sessão\n" - -#, fuzzy -#~ msgid "use a standard location for the socket" -#~ msgstr "" -#~ "Realmente actualizar as preferências para os utilizadores seleccionados?" - -#, fuzzy -#~ msgid "Usage: gpg-agent [options] (-h for help)" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#~ msgid "malformed GPG_AGENT_INFO environment variable\n" -#~ msgstr "variável de ambiente GPG_AGENT_INFO inválida\n" - -#~ msgid "gpg-agent protocol version %d is not supported\n" -#~ msgstr "a versão %d do protocolo gpg-agent não é suportada\n" - -#, fuzzy -#~ msgid "can't fdopen pipe for reading: %s\n" -#~ msgstr "impossível abrir %s: %s\n" - -#, fuzzy -#~ msgid "error creating socket: %s\n" -#~ msgstr "erro ao criar `%s': %s\n" - -#, fuzzy -#~ msgid "host not found" -#~ msgstr "[Utilizador não encontrado]" - -#, fuzzy -#~ msgid "unknown key protection algorithm\n" -#~ msgstr "algoritmo de compressão desconhecido" - -#, fuzzy -#~ msgid "secret parts of key are not available\n" -#~ msgstr "Componentes secretas da chave primária não disponíveis.\n" - -#, fuzzy -#~ msgid "secret key already stored on a card\n" -#~ msgstr "ignorado: a chave secreta já está presente\n" - -#, fuzzy -#~ msgid "error writing key to card: %s\n" -#~ msgstr "erro na escrita do porta-chaves `%s': %s\n" - -#~ msgid "" -#~ "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n" -#~ msgstr "" -#~ "no modo --pgp2 só pode cifrar com chaves RSA de 2048 bits ou menos\n" - -#~ msgid "" -#~ "unable to use the IDEA cipher for all of the keys you are encrypting to.\n" -#~ msgstr "" -#~ "impossível utilizar a cifra IDEA para todas as chaves para que está a " -#~ "cifrar.\n" - -#, fuzzy -#~ msgid "remove the passphrase from exported subkeys" -#~ msgstr "revoga uma chave secundária" - -#, fuzzy -#~ msgid "key %s: not protected - skipped\n" -#~ msgstr "chave %08lX: não está protegida - ignorada\n" - -#, fuzzy -#~ msgid "failed to unprotect the subkey: %s\n" -#~ msgstr "falha ao inicializar a base de dados de confiança: %s\n" - -#~ msgid "too many entries in pk cache - disabled\n" -#~ msgstr "entradas demais no cache pk - desactivado\n" - -#, fuzzy -#~ msgid "no secret subkey for public subkey %s - ignoring\n" -#~ msgstr "há uma chave secreta para a chave pública \"%s\"!\n" - -#, fuzzy -#~ msgid "key %s: secret key without public key - skipped\n" -#~ msgstr "chave %08lX: chave secreta sem chave pública - ignorada\n" - -#~ msgid "usage: gpg [options] " -#~ msgstr "uso: gpg [opções] " - -#~ msgid "" -#~ "you can only make detached or clear signatures while in --pgp2 mode\n" -#~ msgstr "" -#~ "só pode fazer assinaturas separadas ou em texto puro no modo --pgp2\n" - -#~ msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n" -#~ msgstr "não pode assinar e cifrar ao mesmo tempo no modo --pgp2\n" - -#~ msgid "" -#~ "you must use files (and not a pipe) when working with --pgp2 enabled.\n" -#~ msgstr "" -#~ "deve utilizar ficheiros (e não um 'pipe') quando trabalho no modo --" -#~ "pgp2.\n" - -#~ msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n" -#~ msgstr "cifrar uma mensagem no modo --pgp2 necessita da cifra IDEA\n" - -#, fuzzy -#~ msgid "key %s: already in secret keyring\n" -#~ msgstr "chave %08lX: já está no porta-chaves secreto\n" - -#, fuzzy -#~ msgid "key %s: secret key not found: %s\n" -#~ msgstr "chave %08lX: chave secreta não encontrada: %s\n" - -#, fuzzy -#~ msgid "NOTE: primary key is online and stored on card\n" -#~ msgstr "ignorado: a chave secreta já está presente\n" - -#, fuzzy -#~ msgid "NOTE: secondary key is online and stored on card\n" -#~ msgstr "ignorado: a chave secreta já está presente\n" - -#~ msgid "" -#~ "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 " -#~ "mode.\n" -#~ msgstr "" -#~ "Não pode criar uma assinatura OpenPGP numa chave PGP 2.x no modo --pgp2.\n" - -#~ msgid "This would make the key unusable in PGP 2.x.\n" -#~ msgstr "Isto tornaria a chave inutilizável no PGP 2.x.\n" - -#~ msgid "This key is not protected.\n" -#~ msgstr "Esta chave não é protegida.\n" - -#~ msgid "Key is protected.\n" -#~ msgstr "A chave é protegida.\n" - -#~ msgid "Can't edit this key: %s\n" -#~ msgstr "Impossível editar esta chave: %s\n" - -#~ msgid "" -#~ "Enter the new passphrase for this secret key.\n" -#~ "\n" -#~ msgstr "" -#~ "Digite a nova frase para esta chave secreta.\n" -#~ "\n" - -#~ msgid "" -#~ "You don't want a passphrase - this is probably a *bad* idea!\n" -#~ "\n" -#~ msgstr "" -#~ "Você não quer uma frase secreta - provavelmente isto é uma *má* idéia!\n" -#~ "\n" - -#, fuzzy -#~ msgid "Do you really want to do this? (y/N) " -#~ msgstr "Você quer realmente fazer isso? " - -#~ msgid "Please remove selections from the secret keys.\n" -#~ msgstr "Por favor remova as selecções das chaves secretas.\n" - -#~ msgid "No corresponding signature in secret ring\n" -#~ msgstr "Nenhuma assinatura correspondente no porta-chaves secreto\n" - -#, fuzzy -#~ msgid "writing secret key stub to `%s'\n" -#~ msgstr "a escrever chave privada para `%s'\n" - -#~ msgid "writing secret key to `%s'\n" -#~ msgstr "a escrever chave privada para `%s'\n" - -#~ msgid "no writable secret keyring found: %s\n" -#~ msgstr "" -#~ "nenhum porta-chaves secreto com permissões de escrita encontrado: %s\n" - -#~ msgid "WARNING: 2 files with confidential information exists.\n" -#~ msgstr "AVISO: existem 2 ficheiros com informações confidenciais.\n" - -#~ msgid "%s is the unchanged one\n" -#~ msgstr "%s é o não modificado\n" - -#~ msgid "%s is the new one\n" -#~ msgstr "%s é o novo\n" - -#~ msgid "Please fix this possible security flaw\n" -#~ msgstr "Por favor conserte esta possível falha de segurança\n" - -#, fuzzy -#~ msgid "searching for names from %s server %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "searching for names from %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "searching for \"%s\" from %s server %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "searching for \"%s\" from %s\n" -#~ msgstr "a procurar por \"%s\" no servidor HKP %s\n" - -#, fuzzy -#~ msgid "keyserver timed out\n" -#~ msgstr "erro do servidor de chaves" - -#, fuzzy -#~ msgid "keyserver internal error\n" -#~ msgstr "erro do servidor de chaves" - -#, fuzzy -#~ msgid "keyserver communications error: %s\n" -#~ msgstr "A geração de chaves falhou: %s\n" - -#, fuzzy -#~ msgid "WARNING: unable to parse URI %s\n" -#~ msgstr "AVISO: dono pouco seguro em %s \"%s\"\n" - -#~ msgid "invalid root packet detected in proc_tree()\n" -#~ msgstr "pacote raiz inválido detectado em proc_tree()\n" - -#~ msgid "the IDEA cipher plugin is not present\n" -#~ msgstr "o 'plugin' com a cifra IDEA não está presente\n" - -#, fuzzy -#~ msgid "no corresponding public key: %s\n" -#~ msgstr "a escrever chave pública para `%s'\n" - -#, fuzzy -#~ msgid "unknown protection algorithm\n" -#~ msgstr "algoritmo de compressão desconhecido" - -#, fuzzy -#~ msgid "NOTE: This key is not protected!\n" -#~ msgstr "Esta chave não é protegida.\n" - -#, fuzzy -#~ msgid "protection digest %d is not supported\n" -#~ msgstr "algoritmo de protecção %d%s não é suportado\n" - -#~ msgid "Invalid passphrase; please try again" -#~ msgstr "Frase secreta inválida; por favor tente novamente" - -#~ msgid "%s ...\n" -#~ msgstr "%s ...\n" - -#~ msgid "WARNING: Weak key detected - please change passphrase again.\n" -#~ msgstr "" -#~ "AVISO: Chave fraca detectada - por favor mude a frase secreta novamente.\n" - -#~ msgid "" -#~ "generating the deprecated 16-bit checksum for secret key protection\n" -#~ msgstr "" -#~ "a gerar a 'checksum' (depreciada) de 16-bit para protecção da chave " -#~ "secreta\n" - -#~ msgid "" -#~ "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n" -#~ msgstr "" -#~ "só pode assinar-desligar com chaves do tipo PGP 2.x no modo --pgp2\n" - -#~ msgid "" -#~ "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n" -#~ msgstr "só pode assinar à vista com chaves do tipo PGP 2.x no modo --pgp2\n" - -#, fuzzy -#~ msgid "Usage: scdaemon [options] (-h for help)" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#, fuzzy -#~ msgid "Usage: gpgsm [options] [files] (-h for help)" -#~ msgstr "Uso: gpg [opções] [ficheiros] (-h para ajuda)" - -#, fuzzy -#~ msgid "usage: gpgconf [options] " -#~ msgstr "uso: gpg [opções] " - -#, fuzzy -#~ msgid "failed to allocated keyDB handle\n" -#~ msgstr "falha ao inicializar a base de dados de confiança: %s\n" - -#~ msgid "Command> " -#~ msgstr "Comando> " - -#~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n" -#~ msgstr "" -#~ "A base de dados de confiança está danificada; por favor execute\n" -#~ "\"gpg --fix-trustdb\".\n" - -#~ msgid "Please report bugs to .\n" -#~ msgstr "Por favor comunique bugs para .\n" - -#, fuzzy -#~ msgid "Please report bugs to " -#~ msgstr "Por favor comunique bugs para .\n" - -#, fuzzy -#~ msgid "DSA keypair will have %u bits.\n" -#~ msgstr "O par de chaves DSA terá 1024 bits.\n" - -#~ msgid "Repeat passphrase\n" -#~ msgstr "Repita a frase secreta\n" - -#, fuzzy -#~ msgid "read options from file" -#~ msgstr "a ler opções de `%s'\n" - -#~ msgid "|[file]|make a signature" -#~ msgstr "|[ficheiro]|fazer uma assinatura" - -#, fuzzy -#~ msgid "|[FILE]|make a signature" -#~ msgstr "|[ficheiro]|fazer uma assinatura" - -#, fuzzy -#~ msgid "|[FILE]|make a clear text signature" -#~ msgstr "|[ficheiro]|fazer uma assinatura em texto puro" - -#~ msgid "use the default key as default recipient" -#~ msgstr "usar a chave por omissão como destinatário por omissão" - -#~ msgid "force v3 signatures" -#~ msgstr "forçar assinaturas v3" - -#~ msgid "always use a MDC for encryption" -#~ msgstr "sempre usar um MDC para cifrar" - -#~ msgid "add this secret keyring to the list" -#~ msgstr "adicionar este porta-chaves secreto à lista" - -#~ msgid "|FILE|load extension module FILE" -#~ msgstr "|FICHEIRO|carregar módulo de extensão FICHEIRO" - -#~ msgid "|N|use compress algorithm N" -#~ msgstr "|N|usar algoritmo de compressão N" - -#, fuzzy -#~ msgid "remove key from the public keyring" -#~ msgstr "remover chaves do porta-chaves público" - -#~ msgid "" -#~ "It's up to you to assign a value here; this value will never be exported\n" -#~ "to any 3rd party. We need it to implement the web-of-trust; it has " -#~ "nothing\n" -#~ "to do with the (implicitly created) web-of-certificates." -#~ msgstr "" -#~ "Você decide que valor usar aqui; este valor nunca será exportado para\n" -#~ "terceiros. Precisamos dele implementar a rede de confiança, que não tem\n" -#~ "nada a ver com a rede de certificados (implicitamente criada)." - -#~ msgid "" -#~ "To build the Web-of-Trust, GnuPG needs to know which keys are\n" -#~ "ultimately trusted - those are usually the keys for which you have\n" -#~ "access to the secret key. Answer \"yes\" to set this key to\n" -#~ "ultimately trusted\n" -#~ msgstr "" -#~ "Para construir a Teia-de-Confiança ('Web-of-Trust'), o GnuPG precisa de\n" -#~ "saber quais são as chaves em que deposita confiança absoluta - " -#~ "normalmente\n" -#~ "estas são as chaves a que tem acesso à chave privada. Responda \"sim\" " -#~ "para\n" -#~ "que esta chave seja de confiança absoluta.\n" - -#~ msgid "If you want to use this untrusted key anyway, answer \"yes\"." -#~ msgstr "" -#~ "Se você quiser usar esta chave, não de confiança, assim mesmo, responda " -#~ "\"sim\"." - -#~ msgid "" -#~ "Enter the user ID of the addressee to whom you want to send the message." -#~ msgstr "" -#~ "Digite o ID de utilizador do destinatário para quem quer enviar a\n" -#~ "mensagem." - -#~ msgid "" -#~ "In general it is not a good idea to use the same key for signing and\n" -#~ "encryption. This algorithm should only be used in certain domains.\n" -#~ "Please consult your security expert first." -#~ msgstr "" -#~ "Em geral não é uma boa ideia utilizar a mesma chave para assinar e para\n" -#~ "cifrar. Este algoritmo só deve ser utilizado em alguns domínios.\n" -#~ "Por favor consulte primeiro o seu perito em segurança." - -#~ msgid "Enter the size of the key" -#~ msgstr "Insira o tamanho da chave" - -#~ msgid "Answer \"yes\" or \"no\"" -#~ msgstr "Responda \"sim\" ou \"não\"" - -#~ msgid "" -#~ "Enter the required value as shown in the prompt.\n" -#~ "It is possible to enter a ISO date (YYYY-MM-DD) but you won't\n" -#~ "get a good error response - instead the system tries to interpret\n" -#~ "the given value as an interval." -#~ msgstr "" -#~ "Digite o valor necessário conforme pedido.\n" -#~ "É possível digitar uma data ISO (AAAA-MM-DD) mas você não terá uma boa\n" -#~ "reacção a erros - o sistema tentará interpretar o valor dado como um " -#~ "intervalo." - -#~ msgid "Enter the name of the key holder" -#~ msgstr "Digite o nome do possuidor da chave" - -#~ msgid "please enter an optional but highly suggested email address" -#~ msgstr "por favor digite um endereço de email (opcional mas recomendado)" - -#~ msgid "Please enter an optional comment" -#~ msgstr "Por favor digite um comentário (opcional)" - -#~ msgid "" -#~ "N to change the name.\n" -#~ "C to change the comment.\n" -#~ "E to change the email address.\n" -#~ "O to continue with key generation.\n" -#~ "Q to to quit the key generation." -#~ msgstr "" -#~ "N para mudar o nome.\n" -#~ "C para mudar o comentário.\n" -#~ "E para mudar o endereço de email\n" -#~ "O para continuar a geração da chave.\n" -#~ "S para interromper a geração da chave." - -#~ msgid "" -#~ "Answer \"yes\" (or just \"y\") if it is okay to generate the sub key." -#~ msgstr "Responda \"sim\" (ou apenas \"s\") se quiser gerar a subchave." - -#~ msgid "" -#~ "When you sign a user ID on a key, you should first verify that the key\n" -#~ "belongs to the person named in the user ID. It is useful for others to\n" -#~ "know how carefully you verified this.\n" -#~ "\n" -#~ "\"0\" means you make no particular claim as to how carefully you verified " -#~ "the\n" -#~ " key.\n" -#~ "\n" -#~ "\"1\" means you believe the key is owned by the person who claims to own " -#~ "it\n" -#~ " but you could not, or did not verify the key at all. This is useful " -#~ "for\n" -#~ " a \"persona\" verification, where you sign the key of a pseudonymous " -#~ "user.\n" -#~ "\n" -#~ "\"2\" means you did casual verification of the key. For example, this " -#~ "could\n" -#~ " mean that you verified the key fingerprint and checked the user ID on " -#~ "the\n" -#~ " key against a photo ID.\n" -#~ "\n" -#~ "\"3\" means you did extensive verification of the key. For example, this " -#~ "could\n" -#~ " mean that you verified the key fingerprint with the owner of the key " -#~ "in\n" -#~ " person, and that you checked, by means of a hard to forge document " -#~ "with a\n" -#~ " photo ID (such as a passport) that the name of the key owner matches " -#~ "the\n" -#~ " name in the user ID on the key, and finally that you verified (by " -#~ "exchange\n" -#~ " of email) that the email address on the key belongs to the key " -#~ "owner.\n" -#~ "\n" -#~ "Note that the examples given above for levels 2 and 3 are *only* " -#~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" -#~ "mean to you when you sign other keys.\n" -#~ "\n" -#~ "If you don't know what the right answer is, answer \"0\"." -#~ msgstr "" -#~ "Quando assina uma chave de identificação de um utilizador, deve primeiro\n" -#~ "verificar que a chave pertence realmente à pessoa em questão. É útil " -#~ "para\n" -#~ "terceiros saberem com que cuidado é que efectuou esta verificação.\n" -#~ "\n" -#~ "\"0\" significa que não deseja declarar a forma com verificou a chave\n" -#~ "\n" -#~ "\"1\" significa que acredita que a chave pertence à pessoa em questão, " -#~ "mas\n" -#~ " não conseguiu ou não tentou verificar. Este grau é útil para quando\n" -#~ " assina a chave de uma utilizador pseudo-anónimo.\n" -#~ "\n" -#~ "\"2\" significa que efectuou uma verificação normal da chave. Por " -#~ "exemplo,\n" -#~ " isto pode significar que verificou a impressão digital da chave e\n" -#~ " verificou o identificador de utilizador da chave contra uma " -#~ "identificação\n" -#~ " fotográfica.\n" -#~ "\n" -#~ "\"3\" significa que efectuou uma verificação exaustiva da chave. Por " -#~ "exemplo,\n" -#~ " isto pode significar que efectuou a verificação pessoalmente, e que \n" -#~ " utilizou um documento, com fotografia, difícil de falsificar \n" -#~ " (como por exemplo um passaporte) que o nome do dono da chave é o\n" -#~ " mesmo do que o identificador da chave, e que, finalmente, verificou\n" -#~ " (através de troca de e-mail) que o endereço de email da chave " -#~ "pertence\n" -#~ " ao done da chave.\n" -#~ "\n" -#~ "Atenção: os exemplos dados para os níveis 2 e 3 são *apenas* exemplos.\n" -#~ "Compete-lhe a si decidir o que considera, ao assinar chaves, uma " -#~ "verificação\n" -#~ "\"normal\" e uma verificação \"exaustiva\".\n" -#~ "\n" -#~ "Se não sabe qual é a resposta correcta, responda \"0\"." - -#, fuzzy -#~ msgid "Answer \"yes\" if you want to sign ALL the user IDs" -#~ msgstr "Responda \"sim\" se quiser assinar TODOS os IDs de utilizador" - -#~ msgid "" -#~ "Answer \"yes\" if you really want to delete this user ID.\n" -#~ "All certificates are then also lost!" -#~ msgstr "" -#~ "Responda \"sim\" se quiser realmente remover este ID de utilizador.\n" -#~ "Todos os certificados também serão perdidos!" - -#~ msgid "Answer \"yes\" if it is okay to delete the subkey" -#~ msgstr "Responda \"sim\" se quiser remover a subchave" - -#~ msgid "" -#~ "This is a valid signature on the key; you normally don't want\n" -#~ "to delete this signature because it may be important to establish a\n" -#~ "trust connection to the key or another key certified by this key." -#~ msgstr "" -#~ "Esta é uma assinatura válida na chave; normalmente não é desejável\n" -#~ "remover esta assinatura porque ela pode ser importante para estabelecer\n" -#~ "uma conexão de confiança à chave ou a outra chave certificada por esta." - -#~ msgid "" -#~ "This signature can't be checked because you don't have the\n" -#~ "corresponding key. You should postpone its deletion until you\n" -#~ "know which key was used because this signing key might establish\n" -#~ "a trust connection through another already certified key." -#~ msgstr "" -#~ "Esta assinatura não pode ser verificada porque você não tem a chave\n" -#~ "correspondente. Você deve adiar sua remoção até saber que chave foi " -#~ "usada\n" -#~ "porque a chave desta assinatura pode estabelecer uma conexão de " -#~ "confiança\n" -#~ "através de outra chave já certificada." - -#~ msgid "" -#~ "The signature is not valid. It does make sense to remove it from\n" -#~ "your keyring." -#~ msgstr "" -#~ "A assinatura não é válida. Faz sentido removê-la do seu porta-chaves." - -#~ msgid "" -#~ "This is a signature which binds the user ID to the key. It is\n" -#~ "usually not a good idea to remove such a signature. Actually\n" -#~ "GnuPG might not be able to use this key anymore. So do this\n" -#~ "only if this self-signature is for some reason not valid and\n" -#~ "a second one is available." -#~ msgstr "" -#~ "Esta é uma assinatura que liga o ID de utilizador à chave. Geralmente\n" -#~ "não é uma boa idéia remover tal assinatura. É possível que o GnuPG\n" -#~ "não consiga mais usar esta chave. Faça isto apenas se por alguma\n" -#~ "razão esta auto-assinatura não for válida e há uma segunda disponível." - -#~ msgid "" -#~ "Change the preferences of all user IDs (or just of the selected ones)\n" -#~ "to the current list of preferences. The timestamp of all affected\n" -#~ "self-signatures will be advanced by one second.\n" -#~ msgstr "" -#~ "Muda as preferências de todos os identificadores de utilizadores\n" -#~ "(ou apenas dos seleccionados) para a lista actual de preferências.\n" -#~ "O 'timestamp' de todas as auto-assinaturas afectuadas será avançado\n" -#~ "em um segundo.\n" - -#~ msgid "Please enter the passphrase; this is a secret sentence \n" -#~ msgstr "Por favor digite a frase secreta \n" - -#~ msgid "" -#~ "Please repeat the last passphrase, so you are sure what you typed in." -#~ msgstr "Por favor repita a frase secreta, para ter certeza do que digitou." - -#~ msgid "Give the name of the file to which the signature applies" -#~ msgstr "Dê o nome para o ficheiro ao qual a assinatura se aplica" - -#~ msgid "Answer \"yes\" if it is okay to overwrite the file" -#~ msgstr "Responda \"sim\" se quiser escrever por cima do ficheiro" - -#~ msgid "" -#~ "Please enter a new filename. If you just hit RETURN the default\n" -#~ "file (which is shown in brackets) will be used." -#~ msgstr "" -#~ "Por favor digite um novo nome de ficheiro. Se você apenas carregar em " -#~ "RETURN\n" -#~ "o ficheiro por omissão (que é mostrado entre parênteses) será utilizado." - -#~ msgid "" -#~ "You should specify a reason for the certification. Depending on the\n" -#~ "context you have the ability to choose from this list:\n" -#~ " \"Key has been compromised\"\n" -#~ " Use this if you have a reason to believe that unauthorized persons\n" -#~ " got access to your secret key.\n" -#~ " \"Key is superseded\"\n" -#~ " Use this if you have replaced this key with a newer one.\n" -#~ " \"Key is no longer used\"\n" -#~ " Use this if you have retired this key.\n" -#~ " \"User ID is no longer valid\"\n" -#~ " Use this to state that the user ID should not longer be used;\n" -#~ " this is normally used to mark an email address invalid.\n" -#~ msgstr "" -#~ "Deve especificar uma razão para a emissão do certificado. Dependendo no\n" -#~ "contexto, pode escolher as seguintes opções desta lista:\n" -#~ " \"A chave foi comprometida\"\n" -#~ " Utilize esta opção se tem razões para acreditar que indivíduos não\n" -#~ " autorizados obtiveram acesso à sua chave secreta.\n" -#~ " \"A chave foi substituida\"\n" -#~ " Utilize esta opção se substituiu esta chave com uma mais recente.\n" -#~ " \"A chave já não é utilizada\"\n" -#~ " Utilize esta opção se já não utiliza a chave.\n" -#~ " \"O identificador do utilizador já não é válido\"\n" -#~ " Utilize esta opção para comunicar que o identificador do utilizador\n" -#~ " não deve ser mais utilizado; normalmente utilizada para indicar\n" -#~ " que um endereço de email é inválido.\n" - -#~ msgid "" -#~ "If you like, you can enter a text describing why you issue this\n" -#~ "revocation certificate. Please keep this text concise.\n" -#~ "An empty line ends the text.\n" -#~ msgstr "" -#~ "Se desejar, pode inserir uma texto descrevendo a razão pela qual criou\n" -#~ "este certificado de revogação. Por favor mantenha este texto conciso.\n" -#~ "Uma linha vazia termina o texto.\n" - -#, fuzzy -#~ msgid "can't put notation data into v3 (PGP 2.x style) signatures\n" -#~ msgstr "não pode escolher uma chave do tipo PGP 2.x como revogadora\n" - -#, fuzzy -#~ msgid "can't put notation data into v3 (PGP 2.x style) key signatures\n" -#~ msgstr "não pode escolher uma chave do tipo PGP 2.x como revogadora\n" - -#, fuzzy -#~ msgid "can't put a policy URL into v3 (PGP 2.x style) signatures\n" -#~ msgstr "não pode escolher uma chave do tipo PGP 2.x como revogadora\n" - -#, fuzzy -#~ msgid "shelll" -#~ msgstr "help" - -#, fuzzy -#~ msgid "" -#~ "please see http://www.gnupg.org/download/iconv.html for more information\n" -#~ msgstr "" -#~ "por favor veja http://www.gnupg.org/faq.html para mais informações\n" - -#, fuzzy -#~ msgid "key generation is not available from the commandline\n" -#~ msgstr "o gpg-agent não está disponível nesta sessão\n" - -#, fuzzy -#~ msgid "please use the script \"%s\" to generate a new key\n" -#~ msgstr "Por favor selecione o tipo de chave desejado:\n" - -#, fuzzy -#~ msgid "cipher extension `%s' not loaded due to unsafe permissions\n" -#~ msgstr "" -#~ "a extensão de cifra \"%s\" não foi carregada devido às suas permissões " -#~ "inseguras\n" - -#, fuzzy -#~ msgid ".\n" -#~ msgstr "%s.\n" - -#~ msgid "problem with the agent - disabling agent use\n" -#~ msgstr "problema com o agente - a desactivar a utilização deste\n" - -#, fuzzy -#~ msgid "can't query passphrase in batch mode\n" -#~ msgstr "impossível pedir senha em modo não-interactivo\n" - -#~ msgid "Repeat passphrase: " -#~ msgstr "Repita a frase secreta: " - -#~ msgid "-k[v][v][v][c] [user-id] [keyring]" -#~ msgstr "-k[v][v][v][c] [id-utilizador] [porta-chaves]" - -#~ msgid "no entropy gathering module detected\n" -#~ msgstr "nenhum módulo de recolha de entropia detectado\n" - -#, fuzzy -#~ msgid "can't lock `%s': %s\n" -#~ msgstr "impossível abrir `%s'\n" - -#~ msgid "`%s' is not a regular file - ignored\n" -#~ msgstr "`%s' não é um ficheiro normal - ignorado\n" - -#~ msgid "note: random_seed file is empty\n" -#~ msgstr "nota: random_seed está vazia\n" - -#~ msgid "can't read `%s': %s\n" -#~ msgstr "impossível ler `%s': %s\n" - -#~ msgid "note: random_seed file not updated\n" -#~ msgstr "nota: ficheiro random_seed não actualizado\n" - -#~ msgid "can't write `%s': %s\n" -#~ msgstr "impossível escrever `%s': %s\n" - -#~ msgid "can't close `%s': %s\n" -#~ msgstr "impossível fechar `%s': %s\n" - -#~ msgid "WARNING: using insecure random number generator!!\n" -#~ msgstr "AVISO: a utilizar gerador de números aleatórios inseguro!\n" - -#~ msgid "" -#~ "The random number generator is only a kludge to let\n" -#~ "it run - it is in no way a strong RNG!\n" -#~ "\n" -#~ "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n" -#~ "\n" -#~ msgstr "" -#~ "O gerador de números aleatórios é apenas um \"remendo\"\n" -#~ "para poder funcionar - não é de modo algum um bom gerador!\n" -#~ "\n" -#~ "NÃO USE NENHUM DADO GERADO POR ESTE PROGRAMA!\n" -#~ "\n" - -#~ msgid "" -#~ "\n" -#~ "Not enough random bytes available. Please do some other work to give\n" -#~ "the OS a chance to collect more entropy! (Need %d more bytes)\n" -#~ msgstr "" -#~ "\n" -#~ "Não há bytes aleatórios suficientes. Por favor, faça outro trabalho para\n" -#~ "que o sistema possa recolher mais entropia! (São necessários mais %d " -#~ "bytes)\n" - -#, fuzzy -#~ msgid "card reader not available\n" -#~ msgstr "chave secreta não disponível" - -#, fuzzy -#~ msgid "NOTE: %s is not available in this version\n" -#~ msgstr "o gpg-agent não está disponível nesta sessão\n" - -#, fuzzy -#~ msgid " algorithms on these user IDs:\n" -#~ msgstr "Assinou estes identificadores de utilizadores:\n" - -#~ msgid "general error" -#~ msgstr "erro geral" - -#~ msgid "unknown packet type" -#~ msgstr "formato de pacote desconhecido" - -#~ msgid "unknown digest algorithm" -#~ msgstr "algoritmo de \"digest\" desconhecido" - -#~ msgid "bad public key" -#~ msgstr "chave pública incorrecta" - -#~ msgid "bad secret key" -#~ msgstr "chave secreta incorrecta" - -#~ msgid "bad signature" -#~ msgstr "assinatura incorrecta" - -#~ msgid "checksum error" -#~ msgstr "erro de \"checksum\"" - -#~ msgid "unknown cipher algorithm" -#~ msgstr "algoritmo de criptografia desconhecido" - -#~ msgid "invalid packet" -#~ msgstr "pacote inválido" - -#~ msgid "no such user id" -#~ msgstr "identificador de utilizador inexistente" - -#~ msgid "secret key not available" -#~ msgstr "chave secreta não disponível" - -#~ msgid "wrong secret key used" -#~ msgstr "chave secreta incorrecta" - -#~ msgid "bad key" -#~ msgstr "chave incorrecta" - -#~ msgid "file write error" -#~ msgstr "erro de escrita" - -#~ msgid "unknown compress algorithm" -#~ msgstr "algoritmo de compressão desconhecido" - -#~ msgid "file open error" -#~ msgstr "erro na abertura do ficheiro" - -#~ msgid "file create error" -#~ msgstr "erro na criação do ficheiro" - -#~ msgid "unimplemented pubkey algorithm" -#~ msgstr "algoritmo de chave pública não implementado" - -#~ msgid "unimplemented cipher algorithm" -#~ msgstr "algoritmo de criptografia não implementado" - -#~ msgid "unknown signature class" -#~ msgstr "classe de assinatura desconhecida" - -#~ msgid "trust database error" -#~ msgstr "erro na base de dados de confiança" - -#~ msgid "resource limit" -#~ msgstr "limite de recursos" - -#~ msgid "invalid keyring" -#~ msgstr "porta-chaves inválido" - -#~ msgid "malformed user id" -#~ msgstr "identificador de utilizador malformado" - -#~ msgid "file close error" -#~ msgstr "erro ao fechar ficheiro" - -#~ msgid "file rename error" -#~ msgstr "erro na renomeação do ficheiro" - -#~ msgid "file delete error" -#~ msgstr "erro na remoção do ficheiro" - -#~ msgid "timestamp conflict" -#~ msgstr "conflito de \"timestamp\"" - -#~ msgid "unusable pubkey algorithm" -#~ msgstr "algoritmo de chave pública inutilizável" - -#~ msgid "file exists" -#~ msgstr "o ficheiro já existe" - -#~ msgid "weak key" -#~ msgstr "chave fraca" - -#~ msgid "bad URI" -#~ msgstr "URI incorrecto" - -#~ msgid "not processed" -#~ msgstr "não processado" - -#~ msgid "unusable public key" -#~ msgstr "chave pública não utilizável" - -#~ msgid "unusable secret key" -#~ msgstr "chave secreta não utilizável" - -#~ msgid "keyserver error" -#~ msgstr "erro do servidor de chaves" - -#, fuzzy -#~ msgid "no card" -#~ msgstr "não cifrado" - -#, fuzzy -#~ msgid "no data" -#~ msgstr "não há dados assinados\n" - -#~ msgid "... this is a bug (%s:%d:%s)\n" -#~ msgstr "... isto é um bug (%s:%d:%s)\n" - -#~ msgid "operation is not possible without initialized secure memory\n" -#~ msgstr "a operação não é possível sem memória segura inicializada\n" - -#~ msgid "(you may have used the wrong program for this task)\n" -#~ msgstr "(você pode ter usado o programa errado para esta tarefa)\n" - -#~ msgid "" -#~ "please see http://www.gnupg.org/why-not-idea.html for more information\n" -#~ msgstr "veja http://www.gnupg.org/why-not-idea.html para mais informações\n" - -#, fuzzy -#~ msgid "all export-clean-* options from above" -#~ msgstr "ler opções do ficheiro" - -#, fuzzy -#~ msgid "all import-clean-* options from above" -#~ msgstr "ler opções do ficheiro" - -#, fuzzy -#~ msgid "expired: %s)" -#~ msgstr "[expira: %s]" - -#, fuzzy -#~ msgid "key %s: expired signature from key %s - skipped\n" -#~ msgstr "chave %08lX: classe de assinatura inesperada (%02x) - ignorada\n" - -#, fuzzy -#~ msgid "Unable to clean `%s'\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid "No user IDs are removable.\n" -#~ msgstr "o utilizador com o id \"%s\" já está revocado\n" - -#, fuzzy -#~ msgid "bad passphrase or unknown cipher algorithm (%d)\n" -#~ msgstr "algoritmo de criptografia desconhecido" - -#~ msgid "can't set client pid for the agent\n" -#~ msgstr "não consegui colocar o pid do cliente no agente\n" - -#~ msgid "can't get server read FD for the agent\n" -#~ msgstr "não consigo obter FD de leitura no servidor para o agente\n" - -#~ msgid "can't get server write FD for the agent\n" -#~ msgstr "não consigo obter FD de escrita no servidor para o agente\n" - -#~ msgid "select secondary key N" -#~ msgstr "seleciona chave secundária N" - -#~ msgid "list signatures" -#~ msgstr "lista assinaturas" - -#~ msgid "sign the key" -#~ msgstr "assina a chave" - -#~ msgid "add a secondary key" -#~ msgstr "adiciona nova chave secundária" - -#~ msgid "delete signatures" -#~ msgstr "remove assinaturas" - -#~ msgid "updated preferences" -#~ msgstr "preferências actualizadas" - -#~ msgid "No secondary key with index %d\n" -#~ msgstr "Nenhuma chave secundária com índice %d\n" - -#~ msgid "--nrsign-key user-id" -#~ msgstr "--nrsign-key id-utilizador" - -#~ msgid "--nrlsign-key user-id" -#~ msgstr "--nrlsign-key id-utilizador" - -#~ msgid "sign the key non-revocably" -#~ msgstr "assina a chave de forma não-revogável" - -#~ msgid "sign the key locally and non-revocably" -#~ msgstr "assinar a chave localmente e de forma não revogável" - -#~ msgid "q" -#~ msgstr "q" - -#~ msgid "list" -#~ msgstr "list" - -#~ msgid "l" -#~ msgstr "l" - -#~ msgid "debug" -#~ msgstr "debug" - -#, fuzzy -#~ msgid "name" -#~ msgstr "enable" - -#, fuzzy -#~ msgid "login" -#~ msgstr "lsign" - -#, fuzzy -#~ msgid "cafpr" -#~ msgstr "fpr" - -#, fuzzy -#~ msgid "forcesig" -#~ msgstr "revsig" - -#, fuzzy -#~ msgid "generate" -#~ msgstr "erro geral" - -#~ msgid "passwd" -#~ msgstr "passwd" - -#~ msgid "save" -#~ msgstr "save" - -#~ msgid "fpr" -#~ msgstr "fpr" - -#~ msgid "uid" -#~ msgstr "uid" - -#~ msgid "check" -#~ msgstr "check" - -#~ msgid "c" -#~ msgstr "c" - -#~ msgid "sign" -#~ msgstr "sign" - -#~ msgid "s" -#~ msgstr "s" - -#, fuzzy -#~ msgid "tsign" -#~ msgstr "sign" - -#~ msgid "lsign" -#~ msgstr "lsign" - -#~ msgid "nrsign" -#~ msgstr "nrsign" - -#~ msgid "nrlsign" -#~ msgstr "nrlsign" - -#~ msgid "adduid" -#~ msgstr "adduid" - -#~ msgid "addphoto" -#~ msgstr "addphoto" - -#~ msgid "deluid" -#~ msgstr "deluid" - -#~ msgid "delphoto" -#~ msgstr "delphoto" - -#, fuzzy -#~ msgid "addcardkey" -#~ msgstr "addkey" - -#~ msgid "delkey" -#~ msgstr "delkey" - -#~ msgid "addrevoker" -#~ msgstr "addrevoker" - -#~ msgid "delsig" -#~ msgstr "delsig" - -#~ msgid "expire" -#~ msgstr "expire" - -#~ msgid "primary" -#~ msgstr "primary" - -#~ msgid "toggle" -#~ msgstr "toggle" - -#~ msgid "t" -#~ msgstr "t" - -#~ msgid "pref" -#~ msgstr "pref" - -#~ msgid "showpref" -#~ msgstr "showpref" - -#~ msgid "setpref" -#~ msgstr "setpref" - -#~ msgid "updpref" -#~ msgstr "updpref" - -#, fuzzy -#~ msgid "keyserver" -#~ msgstr "erro do servidor de chaves" - -#~ msgid "trust" -#~ msgstr "trust" - -#~ msgid "revsig" -#~ msgstr "revsig" - -#~ msgid "revuid" -#~ msgstr "revuid" - -#~ msgid "revkey" -#~ msgstr "revkey" - -#~ msgid "disable" -#~ msgstr "disable" - -#~ msgid "enable" -#~ msgstr "enable" - -#~ msgid "showphoto" -#~ msgstr "showphoto" - -#~ msgid "" -#~ "About to generate a new %s keypair.\n" -#~ " minimum keysize is 768 bits\n" -#~ " default keysize is 1024 bits\n" -#~ " highest suggested keysize is 2048 bits\n" -#~ msgstr "" -#~ "Prestes a gerar um novo par de chaves %s.\n" -#~ " tamanho mínimo é 768 bits\n" -#~ " tamanho por omissão é 1024 bits\n" -#~ " tamanho máximo sugerido é 2048 bits\n" - -#~ msgid "DSA only allows keysizes from 512 to 1024\n" -#~ msgstr "DSA permite apenas tamanhos de 512 a 1024\n" - -#~ msgid "keysize too small; 1024 is smallest value allowed for RSA.\n" -#~ msgstr "tamanho muito pequeno; 1024 é o valor mínimo permitido para RSA.\n" - -#~ msgid "keysize too small; 768 is smallest value allowed.\n" -#~ msgstr "tamanho muito pequeno; 768 é o valor mínimo permitido.\n" - -#~ msgid "keysize too large; %d is largest value allowed.\n" -#~ msgstr "tamanho muito grande; %d é o valor máximo permitido.\n" - -#~ msgid "" -#~ "Keysizes larger than 2048 are not suggested because\n" -#~ "computations take REALLY long!\n" -#~ msgstr "" -#~ "Tamanhos de chave maiores que 2048 não são recomendados\n" -#~ "porque o tempo de computação é REALMENTE longo!\n" - -#, fuzzy -#~ msgid "Are you sure that you want this keysize? (y/N) " -#~ msgstr "Você tem certeza de que quer este tamanho de chave? " - -#~ msgid "" -#~ "Okay, but keep in mind that your monitor and keyboard radiation is also " -#~ "very vulnerable to attacks!\n" -#~ msgstr "" -#~ "Tudo bem, mas não se esqueça que a radiação do seu monitor e teclado " -#~ "também é extremamente vulnerável a ataques!\n" - -#~ msgid "Experimental algorithms should not be used!\n" -#~ msgstr "Algoritmos experimentais não devem ser usados!\n" - -#~ msgid "" -#~ "this cipher algorithm is deprecated; please use a more standard one!\n" -#~ msgstr "" -#~ "este algoritmo de criptografia está desctualizado; por favor use um " -#~ "algoritmo mais standard!x\n" - -#, fuzzy -#~ msgid "sorry, can't do this in batch mode\n" -#~ msgstr "impossível fazer isso em modo não-interativo\n" - -#, fuzzy -#~ msgid "can't open file `%s': %s\n" -#~ msgstr "impossível abrir %s: %s\n" - -#~ msgid "key %08lX: key has been revoked!\n" -#~ msgstr "chave %08lX: a chave foi revogada!\n" - -#~ msgid "key %08lX: subkey has been revoked!\n" -#~ msgstr "chave %08lX: a subchave foi revogada!\n" - -#~ msgid "%08lX: key has expired\n" -#~ msgstr "%08lX: a chave expirou\n" - -#~ msgid "%08lX: We do NOT trust this key\n" -#~ msgstr "%08lX: Nós NÃO confiamos nesta chave\n" - -#, fuzzy -#~ msgid " (%d) RSA (auth only)\n" -#~ msgstr " (%d) RSA (apenas assinatura)\n" - -#, fuzzy -#~ msgid " (%d) RSA (sign and auth)\n" -#~ msgstr " (%d) RSA (assinatura e cifragem)\n" - -#, fuzzy -#~ msgid " (%d) RSA (encrypt and auth)\n" -#~ msgstr " (%d) RSA (apenas cifragem)\n" - -#, fuzzy -#~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (assinatura e cifragem)\n" - -#~ msgid "%s: can't open: %s\n" -#~ msgstr "%s: impossível abrir: %s\n" - -#~ msgid "%s: WARNING: empty file\n" -#~ msgstr "%s: AVISO: ficheiro vazio\n" - -#, fuzzy -#~ msgid " (%d) I trust marginally\n" -#~ msgstr " %d = Confio moderadamente\n" - -#, fuzzy -#~ msgid " (%d) I trust fully\n" -#~ msgstr " %d = Confio plenamente\n" - -#, fuzzy -#~ msgid "expires" -#~ msgstr "expire" - -#, fuzzy -#~ msgid "" -#~ "\"\n" -#~ "locally signed with your key %s at %s\n" -#~ msgstr "" -#~ "\"\n" -#~ "assinada localmente com a sua chave %08lX em %s\n" - -#~ msgid "%s: can't create lock\n" -#~ msgstr "%s: impossível criar tranca\n" - -#~ msgid "%s: can't make lock\n" -#~ msgstr "%s: impossível criar tranca\n" - -#~ msgid "%s: can't create: %s\n" -#~ msgstr "%s: impossível criar: %s\n" - -#~ msgid "If you want to use this revoked key anyway, answer \"yes\"." -#~ msgstr "" -#~ "Se você quiser usar esta chave revogada assim mesmo, responda \"sim\"." - -#, fuzzy -#~ msgid "Unable to open photo \"%s\": %s\n" -#~ msgstr "não foi possível alterar o exec-path para %s\n" - -#, fuzzy -#~ msgid "error: no ownertrust value\n" -#~ msgstr "exportar os valores de confiança" - -#~ msgid " (main key ID %08lX)" -#~ msgstr " (ID principal da chave %08lX)" - -#~ msgid "rev! subkey has been revoked: %s\n" -#~ msgstr "rev! subchave foi revogada: %s\n" - -#~ msgid "rev- faked revocation found\n" -#~ msgstr "rev- revogação falsa encontrada\n" - -#, fuzzy -#~ msgid " [expired: %s]" -#~ msgstr "[expira: %s]" - -#~ msgid " [expires: %s]" -#~ msgstr "[expira: %s]" - -#, fuzzy -#~ msgid " [revoked: %s]" -#~ msgstr "revkey" - -#~ msgid "|[files]|encrypt files" -#~ msgstr "|[ficheiros]|cifrar ficheiros" - -#~ msgid "store only" -#~ msgstr "apenas armazenar" - -#~ msgid "|[files]|decrypt files" -#~ msgstr "|[ficheiros]|decifrar ficheiros" - -#~ msgid "sign a key non-revocably" -#~ msgstr "assinar uma chave de forma não revocável" - -#~ msgid "sign a key locally and non-revocably" -#~ msgstr "assinar uma chave localmente e de forma não revocável" - -#~ msgid "list only the sequence of packets" -#~ msgstr "listar apenas as sequências de pacotes" - -#~ msgid "export the ownertrust values" -#~ msgstr "exportar os valores de confiança" - -#~ msgid "unattended trust database update" -#~ msgstr "actualizar automaticamente a base de dados de confiança" - -#~ msgid "fix a corrupted trust database" -#~ msgstr "consertar uma base de dados de confiança" - -#~ msgid "De-Armor a file or stdin" -#~ msgstr "retirar armadura de um ficheiro ou do \"stdin\"" - -#~ msgid "En-Armor a file or stdin" -#~ msgstr "criar armadura para um ficheiro ou \"stdin\"" - -#~ msgid "do not force v3 signatures" -#~ msgstr "não forçar assinaturas v3" - -#~ msgid "force v4 key signatures" -#~ msgstr "forçar assinaturas v4" - -#~ msgid "do not force v4 key signatures" -#~ msgstr "não forçar assinaturas v4" - -#~ msgid "never use a MDC for encryption" -#~ msgstr "nunca usar um MDC para cifrar" - -#~ msgid "|[file]|write status info to file" -#~ msgstr "|[ficheiro]|escrever ifnroamções de estado para o ficheiro" - -#~ msgid "|KEYID|ultimately trust this key" -#~ msgstr "|KEYID|confiar totalmente nesta chave" - -#~ msgid "emulate the mode described in RFC1991" -#~ msgstr "emular o modo descrito no RFC1991" - -#~ msgid "set all packet, cipher and digest options to OpenPGP behavior" -#~ msgstr "" -#~ "configurar todas as opções de pacote, cifragem e \"digest\"\n" -#~ "para comportamento OpenPGP" - -#~ msgid "set all packet, cipher and digest options to PGP 2.x behavior" -#~ msgstr "" -#~ "configurar todas as opções de pacote, cifragem e \"digest\"\n" -#~ "para comportamento PGP 2.x" - -#~ msgid "|NAME|use message digest algorithm NAME for passphrases" -#~ msgstr "" -#~ "|NOME|usar algoritmo de \"digest\" de mensagens NOME\n" -#~ "para frases secretas" - -#~ msgid "throw keyid field of encrypted packets" -#~ msgstr "eliminar campo keyid dos pacotes cifrados" - -#~ msgid "Show Photo IDs" -#~ msgstr "Mostrar IDs Fotográficos" - -#~ msgid "Don't show Photo IDs" -#~ msgstr "Não mostrar IDs Fotográficos" - -#~ msgid "Set command line to view Photo IDs" -#~ msgstr "Configurar linha de comandos para ver fotografias" - -#, fuzzy -#~ msgid "compress algorithm `%s' is read-only in this release\n" -#~ msgstr "o algoritmo de compressão deve estar na faixa %d..%d\n" - -#~ msgid "compress algorithm must be in range %d..%d\n" -#~ msgstr "o algoritmo de compressão deve estar na faixa %d..%d\n" - -#~ msgid "" -#~ "%08lX: It is not sure that this key really belongs to the owner\n" -#~ "but it is accepted anyway\n" -#~ msgstr "" -#~ "%08lX: Não se tem certeza de que esta chave realmente pertence ao dono,\n" -#~ "mas é aceite de qualquer modo\n" - -#~ msgid "preference %c%lu is not valid\n" -#~ msgstr "preferência %c%lu não é válida\n" - -#~ msgid "key %08lX: not a rfc2440 key - skipped\n" -#~ msgstr "chave %08lX: não é uma chave rfc2440 - ignorada\n" - -#~ msgid "" -#~ "NOTE: Elgamal primary key detected - this may take some time to import\n" -#~ msgstr "" -#~ "NOTA: Chave primária Elgamal detectada - pode demorar algum tempo a " -#~ "importar\n" - -#~ msgid "%s%c %4u%c/%08lX created: %s expires: %s" -#~ msgstr "%s%c %4u%c/%08lX criada: %s expira: %s" - -#~ msgid "can't get key from keyserver: %s\n" -#~ msgstr "não consigo obter chave do servidor: %s\n" - -#~ msgid "success sending to `%s' (status=%u)\n" -#~ msgstr "sucesso ao enviar para `%s' (estado=%u)\n" - -#~ msgid "failed sending to `%s': status=%u\n" -#~ msgstr "erro ao enviar para `%s': estado=%u\n" - -#~ msgid "can't search keyserver: %s\n" -#~ msgstr "não consigo procurar no servidor de chaves: %s\n" - -#~ msgid "" -#~ "key %08lX: this is a PGP generated ElGamal key which is NOT secure for " -#~ "signatures!\n" -#~ msgstr "" -#~ "chave: %08lX: esta é uma chave ElGamal gerada pelo PGP que NÃO é segura " -#~ "para assinaturas!\n" - -#~ msgid "" -#~ "key %08lX has been created %lu second in future (time warp or clock " -#~ "problem)\n" -#~ msgstr "" -#~ "a chave %08lX foi criada %lu segundo no futuro\n" -#~ "(viagem no tempo ou problema no relógio)\n" - -#~ msgid "" -#~ "key %08lX has been created %lu seconds in future (time warp or clock " -#~ "problem)\n" -#~ msgstr "" -#~ "a chave %08lX foi criada %lu segundos no futuro\n" -#~ "(viagem no tempo ou problema no relógio)\n" - -#~ msgid "key %08lX marked as ultimately trusted\n" -#~ msgstr "chave %08lX marcada como de confiança absoluta\n" - -#~ msgid "checking at depth %d signed=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/%d\n" -#~ msgstr "" -#~ "a verificar à profundidade %d assinado=%d ot(-/q/n/m/f/u)=%d/%d/%d/%d/%d/" -#~ "%d\n" - -#~ msgid "" -#~ "Select the algorithm to use.\n" -#~ "\n" -#~ "DSA (aka DSS) is the digital signature algorithm which can only be used\n" -#~ "for signatures. This is the suggested algorithm because verification of\n" -#~ "DSA signatures are much faster than those of ElGamal.\n" -#~ "\n" -#~ "ElGamal is an algorithm which can be used for signatures and encryption.\n" -#~ "OpenPGP distinguishs between two flavors of this algorithms: an encrypt " -#~ "only\n" -#~ "and a sign+encrypt; actually it is the same, but some parameters must be\n" -#~ "selected in a special way to create a safe key for signatures: this " -#~ "program\n" -#~ "does this but other OpenPGP implementations are not required to " -#~ "understand\n" -#~ "the signature+encryption flavor.\n" -#~ "\n" -#~ "The first (primary) key must always be a key which is capable of " -#~ "signing;\n" -#~ "this is the reason why the encryption only ElGamal key is not available " -#~ "in\n" -#~ "this menu." -#~ msgstr "" -#~ "Seleccione o algoritmo a ser usado.\n" -#~ "\n" -#~ "DSA (ou DSS) é o algoritmo de assinatura digital que pode ser usado " -#~ "apenas\n" -#~ "para assinaturas. Este é o algoritmo recomendado porque a verificação de\n" -#~ "assinaturas DSA é muito mais rápida que a verificação de ElGamal.\n" -#~ "\n" -#~ "ElGamal é um algoritmo que pode ser usado para assinatura e cifragem.\n" -#~ "O OpenPGP distingue dois tipos deste algoritmo: um apenas para cifragem\n" -#~ "e outro para assinatura+cifragem; na verdade são iguais, mas alguns\n" -#~ "parâmetros precisam ser escolhidos de modo especial para criar uma chave\n" -#~ "segura para assinatura: este programa faz isso, mas algumas outras\n" -#~ "implementações do OpenPGP não vão necessariamente entender o tipo\n" -#~ "assinatura+cifragem.\n" -#~ "\n" -#~ "A chave primária precisa sempre ser uma chave capaz de fazer " -#~ "assinaturas;\n" -#~ "este é o motivo pelo qual a chave ElGamal apenas para cifragem não está\n" -#~ "disponível neste menu." - -#~ msgid "" -#~ "Although these keys are defined in RFC2440 they are not suggested\n" -#~ "because they are not supported by all programs and signatures created\n" -#~ "with them are quite large and very slow to verify." -#~ msgstr "" -#~ "Apesar de estas chaves estarem definidas no RFC2440, elas não são " -#~ "recomendadas\n" -#~ "porque não são suportadas por todos os programas e assinaturas criadas " -#~ "com\n" -#~ "elas são grandes e sua verificação é lenta." - -#~ msgid "%lu keys so far checked (%lu signatures)\n" -#~ msgstr "%lu chaves verificadas até agora (%lu assinaturas)\n" - -#, fuzzy -#~ msgid "key %08lX incomplete\n" -#~ msgstr "chave %08lX: sem ID de utilizador\n" - -#, fuzzy -#~ msgid "quit|quit" -#~ msgstr "sair" - -#~ msgid "" -#~ "The use of this algorithm is only supported by GnuPG. You will not be\n" -#~ "able to use this key to communicate with PGP users. This algorithm is " -#~ "also\n" -#~ "very slow, and may not be as secure as the other choices.\n" -#~ msgstr "" -#~ "A utilização deste algoritmo só é suportada pelo GnuPG. Não poderá " -#~ "utilizar\n" -#~ "esta chave para comunicar com utilizadores do PGP. Este algoritmo é " -#~ "para\n" -#~ "além disto muito lento, e pode não ser tão seguro como as outras opções.\n" - -#~ msgid "invalid symkey algorithm detected (%d)\n" -#~ msgstr "algoritmo de 'symkey' inválido detectado (%d)\n" - -#~ msgid "this keyserver is not fully HKP compatible\n" -#~ msgstr "o servidor de chaves não é totalmente compatível com HKP\n" +msgstr "gerir o histórico de comandos" From fa677a37cef007cad4ae772c96849b03931c5263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahelenia=20Ziemia=C5=84ska?= Date: Thu, 7 Dec 2023 11:56:54 +0900 Subject: [PATCH 266/869] po: Fix quotes in Polish Translation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -- Signed-off-by: Ahelenia Ziemiańska --- po/pl.po | 790 +++++++++++++++++++++++++++---------------------------- 1 file changed, 395 insertions(+), 395 deletions(-) diff --git a/po/pl.po b/po/pl.po index 555da9661..dcbab2240 100644 --- a/po/pl.po +++ b/po/pl.po @@ -194,11 +194,11 @@ msgstr "klucze ssh większe niż %d bitów nie są obsługiwane\n" #, c-format msgid "can't create '%s': %s\n" -msgstr "nie można utworzyć ,,%s'': %s\n" +msgstr "nie można utworzyć „%s”: %s\n" #, c-format msgid "can't open '%s': %s\n" -msgstr "nie można otworzyć ,,%s'': %s\n" +msgstr "nie można otworzyć „%s”: %s\n" #, c-format msgid "no suitable card key found: %s\n" @@ -429,7 +429,7 @@ msgid "disallow the use of an external password cache" msgstr "niezezwalanie na użycie zewnętrznej pamięci podręcznej haseł" msgid "disallow clients to mark keys as \"trusted\"" -msgstr "niezezwalanie klientom na oznaczanie kluczy jako ,,zaufanych''" +msgstr "niezezwalanie klientom na oznaczanie kluczy jako „zaufanych”" msgid "allow presetting passphrase" msgstr "zezwolenie na predefiniowane hasło" @@ -496,7 +496,7 @@ msgstr "" #, c-format msgid "invalid debug-level '%s' given\n" -msgstr "podano błędny poziom diagnostyki ,,%s''\n" +msgstr "podano błędny poziom diagnostyki „%s”\n" #, c-format msgid "selected digest algorithm is invalid\n" @@ -504,15 +504,15 @@ msgstr "wybrany algorytm skrótów wiadomości jest niepoprawny\n" #, c-format msgid "reading options from '%s'\n" -msgstr "odczyt opcji z ,,%s''\n" +msgstr "odczyt opcji z „%s”\n" #, c-format msgid "Note: '%s' is not considered an option\n" -msgstr "Uwaga: ,,%s'' nie jest uznane za opcję\n" +msgstr "Uwaga: „%s” nie jest uznane za opcję\n" #, c-format msgid "WARNING: \"%s\" is a deprecated option\n" -msgstr "OSTRZEŻENIE: ,,%s'' jest przestarzałą opcją.\n" +msgstr "OSTRZEŻENIE: „%s” jest przestarzałą opcją.\n" #, c-format msgid "can't create socket: %s\n" @@ -520,7 +520,7 @@ msgstr "nie można utworzyć gniazda: %s\n" #, c-format msgid "socket name '%s' is too long\n" -msgstr "nazwa gniazda ,,%s'' zbyt długa\n" +msgstr "nazwa gniazda „%s” zbyt długa\n" #, c-format msgid "trying to steal socket from running %s\n" @@ -536,31 +536,31 @@ msgstr "błąd podczas pobierania nonce z gniazda\n" #, c-format msgid "error binding socket to '%s': %s\n" -msgstr "błąd podczas przypisywania gniazda do ,,%s'': %s\n" +msgstr "błąd podczas przypisywania gniazda do „%s”: %s\n" #, c-format msgid "can't set permissions of '%s': %s\n" -msgstr "nie można ustawić praw dostępu do ,,%s'': %s\n" +msgstr "nie można ustawić praw dostępu do „%s”: %s\n" #, c-format msgid "listening on socket '%s'\n" -msgstr "nasłuchiwanie na gnieździe ,,%s''\n" +msgstr "nasłuchiwanie na gnieździe „%s”\n" #, c-format msgid "can't create directory '%s': %s\n" -msgstr "nie można utworzyć katalogu ,,%s'': %s\n" +msgstr "nie można utworzyć katalogu „%s”: %s\n" #, c-format msgid "directory '%s' created\n" -msgstr "katalog ,,%s'' utworzony\n" +msgstr "katalog „%s” utworzony\n" #, c-format msgid "stat() failed for '%s': %s\n" -msgstr "stat() nie powiodło się dla ,,%s'': %s\n" +msgstr "stat() nie powiodło się dla „%s”: %s\n" #, c-format msgid "can't use '%s' as home directory\n" -msgstr "nie można użyć ,,%s'' jako katalogu domowego\n" +msgstr "nie można użyć „%s” jako katalogu domowego\n" #, c-format msgid "error reading nonce on fd %d: %s\n" @@ -667,31 +667,31 @@ msgstr "błąd podczas pytania o hasło: %s\n" #, c-format msgid "error opening '%s': %s\n" -msgstr "błąd podczas otwierania ,,%s'': %s\n" +msgstr "błąd podczas otwierania „%s”: %s\n" #, c-format msgid "file '%s', line %d: %s\n" -msgstr "plik ,,%s'', linia %d: %s\n" +msgstr "plik „%s”, linia %d: %s\n" #, c-format msgid "statement \"%s\" ignored in '%s', line %d\n" -msgstr "instrukcja \"%s\" zignorowana w ,,%s'', w linii %d\n" +msgstr "instrukcja \"%s\" zignorowana w „%s”, w linii %d\n" #, c-format msgid "system trustlist '%s' not available\n" -msgstr "systemowa lista zaufania ,,%s'' niedostępna\n" +msgstr "systemowa lista zaufania „%s” niedostępna\n" #, c-format msgid "bad fingerprint in '%s', line %d\n" -msgstr "błędny odcisk w ,,%s'', w linii %d\n" +msgstr "błędny odcisk w „%s”, w linii %d\n" #, c-format msgid "invalid keyflag in '%s', line %d\n" -msgstr "nieprawidłowa flaga klucza w ,,%s'', w linii %d\n" +msgstr "nieprawidłowa flaga klucza w „%s”, w linii %d\n" #, c-format msgid "error reading '%s', line %d: %s\n" -msgstr "błąd odczytu ,,%s'', w linii %d: %s\n" +msgstr "błąd odczytu „%s”, w linii %d: %s\n" #, c-format msgid "error reading list of trusted root certificates\n" @@ -710,7 +710,7 @@ msgid "" "Do you ultimately trust%%0A \"%s\"%%0Ato correctly certify user " "certificates?" msgstr "" -"Czy absolutnie ufasz, że%%0A ,,%s''%%0Apoprawnie poświadcza certyfikaty " +"Czy absolutnie ufasz, że%%0A „%s”%%0Apoprawnie poświadcza certyfikaty " "użytkowników?" msgid "Yes" @@ -732,7 +732,7 @@ msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " "fingerprint:%%0A %s" msgstr "" -"Proszę sprawdzić, że certyfikat zidentyfikowany jako:%%0a ,,%s''%%0Ama " +"Proszę sprawdzić, że certyfikat zidentyfikowany jako:%%0a „%s”%%0Ama " "odcisk:%%0A %s" #. TRANSLATORS: "Correct" is the label of a button and intended @@ -839,15 +839,15 @@ msgstr "oczekiwanie na zakończenie procesu %d nie powiodło się: %s\n" #, c-format msgid "error running '%s': probably not installed\n" -msgstr "błąd uruchamiania ,,%s'': prawdopodobnie nie zainstalowany\n" +msgstr "błąd uruchamiania „%s”: prawdopodobnie nie zainstalowany\n" #, c-format msgid "error running '%s': exit status %d\n" -msgstr "błąd uruchamiania ,,%s'': kod wyjścia %d\n" +msgstr "błąd uruchamiania „%s”: kod wyjścia %d\n" #, c-format msgid "error running '%s': terminated\n" -msgstr "błąd uruchamiania ,,%s'': zakończono\n" +msgstr "błąd uruchamiania „%s”: zakończono\n" #, c-format msgid "waiting for processes to terminate failed: %s\n" @@ -859,7 +859,7 @@ msgstr "błąd odczytu kodu zakończenia procesu %d: %s\n" #, c-format msgid "can't connect to '%s': %s\n" -msgstr "nie można się połączyć z ,,%s'': %s\n" +msgstr "nie można się połączyć z „%s”: %s\n" #, c-format msgid "problem setting the gpg-agent options\n" @@ -871,19 +871,19 @@ msgstr "nie można wyłączyć zrzutów pamięci: %s\n" #, c-format msgid "Warning: unsafe ownership on %s \"%s\"\n" -msgstr "Ostrzeżenie: niebezpieczne prawa własności do %s ,,%s''\n" +msgstr "Ostrzeżenie: niebezpieczne prawa własności do %s „%s”\n" #, c-format msgid "Warning: unsafe permissions on %s \"%s\"\n" -msgstr "Ostrzeżenie: niebezpieczne prawa dostępu do %s ,,%s''\n" +msgstr "Ostrzeżenie: niebezpieczne prawa dostępu do %s „%s”\n" #, c-format msgid "waiting for file '%s' to become accessible ...\n" -msgstr "oczekiwanie aż plik ,,%s'' stanie się dostępny...\n" +msgstr "oczekiwanie aż plik „%s” stanie się dostępny...\n" #, c-format msgid "renaming '%s' to '%s' failed: %s\n" -msgstr "zmiana nazwy ,,%s'' na ,,%s'' nie powiodła się: %s\n" +msgstr "zmiana nazwy „%s” na „%s” nie powiodła się: %s\n" #. TRANSLATORS: See doc/TRANSLATE about this string. msgid "yes" @@ -934,15 +934,15 @@ msgstr "błąd przydzielania wystarczającej ilości pamięci: %s\n" #, c-format msgid "%s:%u: obsolete option \"%s\" - it has no effect\n" -msgstr "%s:%u: przestarzała opcja ,,%s'' - nie ma efektu\n" +msgstr "%s:%u: przestarzała opcja „%s” - nie ma efektu\n" #, c-format msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n" -msgstr "OSTRZEŻENIE: ,,%s%s'' jest przestarzałą opcją - nie ma efektu\n" +msgstr "OSTRZEŻENIE: „%s%s” jest przestarzałą opcją - nie ma efektu\n" #, c-format msgid "unknown debug flag '%s' ignored\n" -msgstr "nieznana flaga diagnostyczna ,,%s'' zignorowana\n" +msgstr "nieznana flaga diagnostyczna „%s” zignorowana\n" #, fuzzy, c-format #| msgid "waiting for the %s to come up ... (%ds)\n" @@ -977,7 +977,7 @@ msgstr "ustanowiono połączenie z procesem %s\n" #, fuzzy, c-format #| msgid "no running Dirmngr - starting '%s'\n" msgid "no running %s - starting '%s'\n" -msgstr "Dirmngr nie działa - uruchamianie ,,%s''\n" +msgstr "Dirmngr nie działa - uruchamianie „%s”\n" #, fuzzy, c-format #| msgid "connection to agent is in restricted mode\n" @@ -986,11 +986,11 @@ msgstr "połączenie z agentem jest w trybie ograniczonym\n" #, c-format msgid "error getting version from '%s': %s\n" -msgstr "błąd pobierania wersji z ,,%s'': %s\n" +msgstr "błąd pobierania wersji z „%s”: %s\n" #, c-format msgid "server '%s' is older than us (%s < %s)" -msgstr "serwer ,,%s'' jest starszy niż nasz (%s < %s)" +msgstr "serwer „%s” jest starszy niż nasz (%s < %s)" #, c-format msgid "WARNING: %s\n" @@ -1003,7 +1003,7 @@ msgstr "" #, c-format msgid "Note: Use the command \"%s\" to restart them.\n" -msgstr "Uwaga: do restartu ich należy użyć polecenia ,,%s''.\n" +msgstr "Uwaga: do restartu ich należy użyć polecenia „%s”.\n" #. TRANSLATORS: Copy the prefix between the vertical bars #. verbatim. It will not be printed. @@ -1140,7 +1140,7 @@ msgstr "Dirmngr sprawny" #, c-format msgid "No help available for '%s'." -msgstr "Brak pomocy dla ,,%s''." +msgstr "Brak pomocy dla „%s”." msgid "ignoring garbage line" msgstr "zignorowano błędną linię" @@ -1170,7 +1170,7 @@ msgstr "" #, c-format msgid "conversion from '%s' to '%s' not available\n" -msgstr "konwersja z ,,%s'' do ,,%s'' niedostępna\n" +msgstr "konwersja z „%s” do „%s” niedostępna\n" #, c-format msgid "iconv_open failed: %s\n" @@ -1178,15 +1178,15 @@ msgstr "iconv_open nie powiodło się: %s\n" #, c-format msgid "conversion from '%s' to '%s' failed: %s\n" -msgstr "konwersja z ,,%s'' do ,,%s'' nie powiodła się: %s\n" +msgstr "konwersja z „%s” do „%s” nie powiodła się: %s\n" #, c-format msgid "failed to create temporary file '%s': %s\n" -msgstr "nie udało się utworzyć pliku tymczasowego ,,%s'': %s\n" +msgstr "nie udało się utworzyć pliku tymczasowego „%s”: %s\n" #, c-format msgid "error writing to '%s': %s\n" -msgstr "błąd zapisu do ,,%s'': %s\n" +msgstr "błąd zapisu do „%s”: %s\n" #, c-format msgid "removing stale lockfile (created by %d)\n" @@ -1201,7 +1201,7 @@ msgstr "(zakleszczenie?) " #, c-format msgid "lock '%s' not made: %s\n" -msgstr "blokada ,,%s'' nie założona: %s\n" +msgstr "blokada „%s” nie założona: %s\n" #, c-format msgid "waiting for lock %s...\n" @@ -1213,11 +1213,11 @@ msgstr "biblioteka %s jest zbyt stara (wymagana %s, zainstalowana %s)\n" #, c-format msgid "error creating '%s': %s\n" -msgstr "błąd tworzenia ,,%s'': %s\n" +msgstr "błąd tworzenia „%s”: %s\n" #, c-format msgid "error closing '%s': %s\n" -msgstr "błąd zamykania ,,%s'': %s\n" +msgstr "błąd zamykania „%s”: %s\n" #, c-format msgid "armor: %s\n" @@ -1253,7 +1253,7 @@ msgstr "niepoprawne oznaczenie linii minusami: " #, c-format msgid "invalid radix64 character %02X skipped\n" -msgstr "niewłaściwy znak formatu radix64 ,,%02X'' został pominięty\n" +msgstr "niewłaściwy znak formatu radix64 „%02X” został pominięty\n" #, c-format msgid "premature eof (no CRC)\n" @@ -1304,15 +1304,15 @@ msgid "" "an '='\n" msgstr "" "nazwa adnotacji musi zawierać tylko znaki drukowalne lub spacje i kończyć " -"się znakiem ,,=''\n" +"się znakiem „=”\n" #, c-format msgid "a user notation name must contain the '@' character\n" -msgstr "nazwa adnotacji użytkownika musi zawierać znak ,,@''\n" +msgstr "nazwa adnotacji użytkownika musi zawierać znak „@”\n" #, c-format msgid "a notation name must not contain more than one '@' character\n" -msgstr "nazwa adnotacjinie może zawierać więcej niż jednego znaku ,,@''\n" +msgstr "nazwa adnotacjinie może zawierać więcej niż jednego znaku „@”\n" #, c-format msgid "a notation value must not use any control characters\n" @@ -1320,7 +1320,7 @@ msgstr "wartość adnotacji nie może zawierać żadnych znaków sterujących\n" #, c-format msgid "a notation name may not contain an '=' character\n" -msgstr "nazwa adnotacji nie może zawierać znaku ,,=''\n" +msgstr "nazwa adnotacji nie może zawierać znaku „=”\n" #, c-format msgid "a notation name must have only printable characters or spaces\n" @@ -1357,7 +1357,7 @@ msgstr "brak działającego dirmngr w tej sesji\n" #, fuzzy, c-format #| msgid "keyserver option \"%s\" may not be used in %s mode\n" msgid "keyserver option \"honor-keyserver-url\" may not be used in Tor mode\n" -msgstr "opcja serwera kluczy ,,%s'' nie może być używana w trybie %s\n" +msgstr "opcja serwera kluczy „%s” nie może być używana w trybie %s\n" msgid "WKD uses a cached result" msgstr "WKD używa zapamiętanego wyniku" @@ -1430,7 +1430,7 @@ msgid "Error: Only plain ASCII is currently allowed.\n" msgstr "Błąd: aktualnie dopuszczalne jest tylko czyste ASCII.\n" msgid "Error: The \"<\" character may not be used.\n" -msgstr "Błąd: znak ,,<'' nie może być użyty.\n" +msgstr "Błąd: znak „<” nie może być użyty.\n" msgid "Error: Double spaces are not allowed.\n" msgstr "Błąd: podwójne spacje nie są dopuszczalne.\n" @@ -1450,11 +1450,11 @@ msgstr "URL do odczytania klucza publicznego: " #, c-format msgid "error reading '%s': %s\n" -msgstr "błąd odczytu ,,%s'': %s\n" +msgstr "błąd odczytu „%s”: %s\n" #, c-format msgid "error writing '%s': %s\n" -msgstr "błąd zapisu ,,%s'': %s\n" +msgstr "błąd zapisu „%s”: %s\n" msgid "Login data (account name): " msgstr "Dane logowania (nazwa konta): " @@ -1590,7 +1590,7 @@ msgid "" "You should change them using the command --change-pin\n" msgstr "" "Fabryczne ustawienia PIN-ów to\n" -" PIN = ,,%s'' PIN administracyjny = ,,%s''\n" +" PIN = „%s” PIN administracyjny = „%s”\n" "Należy je zmienić przy użyciu polecenia --change-pin\n" msgid "Please select the type of key to generate:\n" @@ -1620,7 +1620,7 @@ msgid "Continue? (y/N) " msgstr "Kontynuować? (t/N) " msgid "Really do a factory reset? (enter \"yes\") " -msgstr "Naprawdę przywrócić stan fabryczny? (proszę wpisać ,,yes'') " +msgstr "Naprawdę przywrócić stan fabryczny? (proszę wpisać „yes”) " #, c-format msgid "error for setup KDF: %s\n" @@ -1712,7 +1712,7 @@ msgstr "Polecenia dla administratora nie są dozwolone\n" #, c-format msgid "Invalid command (try \"help\")\n" -msgstr "Niepoprawne polecenie (spróbuj ,,help'')\n" +msgstr "Niepoprawne polecenie (spróbuj „help”)\n" #, c-format msgid "--output doesn't work for this command\n" @@ -1720,11 +1720,11 @@ msgstr "opcja --output nie działa z tym poleceniem\n" #, c-format msgid "can't open '%s'\n" -msgstr "nie można otworzyć ,,%s''\n" +msgstr "nie można otworzyć „%s”\n" #, c-format msgid "key \"%s\" not found: %s\n" -msgstr "klucz ,,%s'' nie został odnaleziony: %s\n" +msgstr "klucz „%s” nie został odnaleziony: %s\n" #, c-format msgid "error reading keyblock: %s\n" @@ -1732,11 +1732,11 @@ msgstr "błąd odczytu bloku kluczy: %s\n" #, c-format msgid "key \"%s\" not found\n" -msgstr "klucz ,,%s'' nie został odnaleziony\n" +msgstr "klucz „%s” nie został odnaleziony\n" #, c-format msgid "can't do this in batch mode without \"--yes\"\n" -msgstr "bez opcji ,,--yes'' nie działa w trybie wsadowym\n" +msgstr "bez opcji „--yes” nie działa w trybie wsadowym\n" #, c-format msgid "(unless you specify the key by fingerprint)\n" @@ -1786,7 +1786,7 @@ msgstr "informacja o zaufaniu dla właściciela klucza została wymazana\n" #, c-format msgid "there is a secret key for public key \"%s\"!\n" -msgstr "dla klucza publicznego ,,%s'' istnieje klucz prywatny!\n" +msgstr "dla klucza publicznego „%s” istnieje klucz prywatny!\n" #, c-format msgid "use option \"--delete-secret-keys\" to delete it first.\n" @@ -1802,7 +1802,7 @@ msgstr "" #, fuzzy, c-format #| msgid "cipher algorithm '%s' may not be used in %s mode\n" msgid "cipher algorithm '%s' may not be used for encryption\n" -msgstr "szyfr ,,%s'' nie może być używany w trybie %s\n" +msgstr "szyfr „%s” nie może być używany w trybie %s\n" #, c-format msgid "(use option \"%s\" to override)\n" @@ -1810,7 +1810,7 @@ msgstr "" #, c-format msgid "cipher algorithm '%s' may not be used in %s mode\n" -msgstr "szyfr ,,%s'' nie może być używany w trybie %s\n" +msgstr "szyfr „%s” nie może być używany w trybie %s\n" #, c-format msgid "WARNING: key %s is not suitable for encryption in %s mode\n" @@ -1833,19 +1833,19 @@ msgstr "szyfrem %s\n" #, c-format msgid "'%s' already compressed\n" -msgstr ",,%s'' już jest skompresowany\n" +msgstr "„%s” już jest skompresowany\n" #, c-format msgid "WARNING: '%s' is an empty file\n" -msgstr "OSTRZEŻENIE: plik ,,%s'' jest pusty\n" +msgstr "OSTRZEŻENIE: plik „%s” jest pusty\n" #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" -msgstr "algorytm skrótu ,,%s'' nie może być używany w trybie %s\n" +msgstr "algorytm skrótu „%s” nie może być używany w trybie %s\n" #, c-format msgid "reading from '%s'\n" -msgstr "odczyt z ,,%s''\n" +msgstr "odczyt z „%s”\n" #, c-format msgid "" @@ -1858,11 +1858,11 @@ msgstr "" #, fuzzy, c-format #| msgid "%s/%s encrypted for: \"%s\"\n" msgid "%s/%s.%s encrypted for: \"%s\"\n" -msgstr "%s/%s zaszyfrowany dla: ,,%s''\n" +msgstr "%s/%s zaszyfrowany dla: „%s”\n" #, c-format msgid "option '%s' may not be used in %s mode\n" -msgstr "opcja ,,%s'' nie może być używana w trybie %s\n" +msgstr "opcja „%s” nie może być używana w trybie %s\n" #, fuzzy, c-format #| msgid "%s encrypted data\n" @@ -1890,7 +1890,7 @@ msgid "export attribute user IDs (generally photo IDs)" msgstr "eksport atrybutów ID użytkownika (ogólnie ID zdjęć)" msgid "export revocation keys marked as \"sensitive\"" -msgstr "eksport kluczy unieważniających oznaczonych jako ,,poufne''" +msgstr "eksport kluczy unieważniających oznaczonych jako „poufne”" msgid "remove unusable parts from key during export" msgstr "usunięcie bezużytecznych części z klucza przy eksporcie" @@ -1916,7 +1916,7 @@ msgstr " - pominięty" #, c-format msgid "writing to '%s'\n" -msgstr "zapis do ,,%s''\n" +msgstr "zapis do „%s”\n" #, c-format msgid "key %s: key material on-card - skipped\n" @@ -1939,11 +1939,11 @@ msgstr "[brak identyfikatora użytkownika]" #, c-format msgid "automatically retrieved '%s' via %s\n" -msgstr "automatycznie pobrano ,,%s'' poprzez %s\n" +msgstr "automatycznie pobrano „%s” poprzez %s\n" #, c-format msgid "error retrieving '%s' via %s: %s\n" -msgstr "błąd pobierania ,,%s'' poprzez %s: %s\n" +msgstr "błąd pobierania „%s” poprzez %s: %s\n" msgid "No fingerprint" msgstr "Brak odcisku" @@ -1954,23 +1954,23 @@ msgstr "szukanie świeżej kopii wygasłego klucza poprzez %s\n" #, c-format msgid "secret key \"%s\" not found: %s\n" -msgstr "klucz prywatny ,,%s'' nie został odnaleziony: %s\n" +msgstr "klucz prywatny „%s” nie został odnaleziony: %s\n" #, c-format msgid "(check argument of option '%s')\n" -msgstr "(sprawdzić argument opcji ,,%s'')\n" +msgstr "(sprawdzić argument opcji „%s”)\n" #, c-format msgid "Warning: not using '%s' as default key: %s\n" -msgstr "Ostrzeżenie: ,,%s'' nie jest użyty jako domyślny klucz: %s\n" +msgstr "Ostrzeżenie: „%s” nie jest użyty jako domyślny klucz: %s\n" #, c-format msgid "using \"%s\" as default secret key for signing\n" -msgstr "użycie ,,%s'' jako domyślnego klucza tajnego do podpisywania\n" +msgstr "użycie „%s” jako domyślnego klucza tajnego do podpisywania\n" #, c-format msgid "all values passed to '%s' ignored\n" -msgstr "wszystkie wartości przekazane do ,,%s'' zostały zignorowane\n" +msgstr "wszystkie wartości przekazane do „%s” zostały zignorowane\n" #, c-format msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n" @@ -1984,7 +1984,7 @@ msgstr "używany jest podklucz %s zamiast klucza głównego %s\n" #, c-format msgid "valid values for option '%s':\n" -msgstr "poprawne argimenty dla opcji ,,%s'':\n" +msgstr "poprawne argimenty dla opcji „%s”:\n" msgid "make a signature" msgstr "złożenie podpisu" @@ -2261,76 +2261,76 @@ msgstr "sprzeczne polecenia\n" #, c-format msgid "no = sign found in group definition '%s'\n" -msgstr "w definicji grupy ,,%s'' brak znaku ,,=''\n" +msgstr "w definicji grupy „%s” brak znaku „=”\n" #, c-format msgid "WARNING: unsafe ownership on homedir '%s'\n" msgstr "" -"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu domowego ,,%s''\n" +"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu domowego „%s”\n" #, c-format msgid "WARNING: unsafe ownership on configuration file '%s'\n" msgstr "" -"OSTRZEŻENIE: niebezpieczne prawa własności do pliku konfiguracyjnego ,,%s''\n" +"OSTRZEŻENIE: niebezpieczne prawa własności do pliku konfiguracyjnego „%s”\n" #, c-format msgid "WARNING: unsafe ownership on extension '%s'\n" -msgstr "OSTRZEŻENIE: niebezpieczne prawa własności do rozszerzenia ,,%s''\n" +msgstr "OSTRZEŻENIE: niebezpieczne prawa własności do rozszerzenia „%s”\n" #, c-format msgid "WARNING: unsafe permissions on homedir '%s'\n" -msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu domowego ,,%s''\n" +msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu domowego „%s”\n" #, c-format msgid "WARNING: unsafe permissions on configuration file '%s'\n" msgstr "" -"OSTRZEŻENIE: niebezpieczne prawa dostępu do pliku konfiguracyjnego ,,%s''\n" +"OSTRZEŻENIE: niebezpieczne prawa dostępu do pliku konfiguracyjnego „%s”\n" #, c-format msgid "WARNING: unsafe permissions on extension '%s'\n" -msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do rozszerzenia ,,%s''\n" +msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do rozszerzenia „%s”\n" #, c-format msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa własności do katalogu zawierającego katalog " -"domowy ,,%s''\n" +"domowy „%s”\n" #, c-format msgid "" "WARNING: unsafe enclosing directory ownership on configuration file '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa własności do katalogu zawierającego plik " -"konfiguracyjny ,,%s''\n" +"konfiguracyjny „%s”\n" #, c-format msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa własności do katalogu zawierającego " -"rozszerzenie ,,%s''\n" +"rozszerzenie „%s”\n" #, c-format msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu zawierającego katalog " -"domowy ,,%s''\n" +"domowy „%s”\n" #, c-format msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu zawierającego plik " -"konfiguracyjny ,,%s''\n" +"konfiguracyjny „%s”\n" #, c-format msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu zawierającego " -"rozszerzenie ,,%s''\n" +"rozszerzenie „%s”\n" #, c-format msgid "unknown configuration item '%s'\n" -msgstr "nieznana opcja konfiguracyjna ,,%s''\n" +msgstr "nieznana opcja konfiguracyjna „%s”\n" msgid "display photo IDs during key listings" msgstr "wyświetlenie ID zdjęć przy wypisywaniu kluczy" @@ -2382,11 +2382,11 @@ msgstr "ustawienia (zaawansowane)" #, c-format msgid "unknown TOFU policy '%s'\n" -msgstr "nieznana polityka TOFU ,,%s''\n" +msgstr "nieznana polityka TOFU „%s”\n" #, c-format msgid "(use \"help\" to list choices)\n" -msgstr "(,,help'' wyświetli listę wyborów)\n" +msgstr "(„help” wyświetli listę wyborów)\n" #, c-format msgid "This command is not allowed while in %s mode.\n" @@ -2398,23 +2398,23 @@ msgstr "Uwaga: %s nie jest do normalnego użytku!\n" #, c-format msgid "'%s' is not a valid signature expiration\n" -msgstr ",,%s'' nie jest poprawnym czasem wygaśnięcia podpisu\n" +msgstr "„%s” nie jest poprawnym czasem wygaśnięcia podpisu\n" #, c-format msgid "\"%s\" is not a proper mail address\n" -msgstr ",,%s'' nie jest niepoprawnym adresem e-mail\n" +msgstr "„%s” nie jest niepoprawnym adresem e-mail\n" #, c-format msgid "invalid pinentry mode '%s'\n" -msgstr "błędny tryb pinentry ,,%s''\n" +msgstr "błędny tryb pinentry „%s”\n" #, c-format msgid "invalid request origin '%s'\n" -msgstr "błędne źródło żądania ,,%s''\n" +msgstr "błędne źródło żądania „%s”\n" #, c-format msgid "'%s' is not a valid character set\n" -msgstr ",,%s'' nie jest poprawną nazwą zestawu znaków\n" +msgstr "„%s” nie jest poprawną nazwą zestawu znaków\n" #, c-format msgid "could not parse keyserver URL\n" @@ -2508,7 +2508,7 @@ msgstr "Niepoprawna lista auto-key-locate\n" #, c-format msgid "invalid argument for option \"%.50s\"\n" -msgstr "błędny argument dla opcji ,,%.50s''\n" +msgstr "błędny argument dla opcji „%.50s”\n" #, c-format msgid "WARNING: program may create a core file!\n" @@ -2603,7 +2603,7 @@ msgstr "%s jeszcze nie działa z %s!\n" #, c-format msgid "compression algorithm '%s' may not be used in %s mode\n" -msgstr "algorytm kompresji ,,%s'' nie może być używany w trybie %s\n" +msgstr "algorytm kompresji „%s” nie może być używany w trybie %s\n" #, c-format msgid "failed to initialize the TrustDB: %s\n" @@ -2615,7 +2615,7 @@ msgstr "OSTRZEŻENIE: podano adresatów (-r) w działaniu które ich nie dotyczy #, c-format msgid "symmetric encryption of '%s' failed: %s\n" -msgstr "szyfrowanie symetryczne ,,%s'' nie powiodło się: %s\n" +msgstr "szyfrowanie symetryczne „%s” nie powiodło się: %s\n" #, c-format msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n" @@ -2667,16 +2667,16 @@ msgstr "opakowywanie ASCII nie powiodło się: %s\n" #, c-format msgid "invalid hash algorithm '%s'\n" -msgstr "niewłaściwy algorytm skrótu ,,%s''\n" +msgstr "niewłaściwy algorytm skrótu „%s”\n" #, c-format msgid "error parsing key specification '%s': %s\n" -msgstr "błąd analizy specyfikacji klucza ,,%s'': %s\n" +msgstr "błąd analizy specyfikacji klucza „%s”: %s\n" #, c-format msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n" msgstr "" -",,%s'' nie wygląda na prawidłowy identyfikator, odcisk ani uchwyt klucza\n" +"„%s” nie wygląda na prawidłowy identyfikator, odcisk ani uchwyt klucza\n" #, c-format msgid "WARNING: no command supplied. Trying to guess what you mean ...\n" @@ -2725,7 +2725,7 @@ msgstr "Pomoc niedostępna" #, c-format msgid "No help available for '%s'" -msgstr "Brak pomocy o ,,%s''" +msgstr "Brak pomocy o „%s”" msgid "import signatures that are marked as local-only" msgstr "import podpisów oznaczonych jako tylko lokalne" @@ -2855,20 +2855,20 @@ msgstr "" #, c-format msgid " \"%s\": preference for cipher algorithm %s\n" -msgstr " ,,%s'': preferowany szyfr %s\n" +msgstr " „%s”: preferowany szyfr %s\n" #, fuzzy, c-format #| msgid " \"%s\": preference for cipher algorithm %s\n" msgid " \"%s\": preference for AEAD algorithm %s\n" -msgstr " ,,%s'': preferowany szyfr %s\n" +msgstr " „%s”: preferowany szyfr %s\n" #, c-format msgid " \"%s\": preference for digest algorithm %s\n" -msgstr " ,,%s'': preferowany algorytm skrótu %s\n" +msgstr " „%s”: preferowany algorytm skrótu %s\n" #, c-format msgid " \"%s\": preference for compression algorithm %s\n" -msgstr " ,,%s'': preferowany algorytm kompresji %s\n" +msgstr " „%s”: preferowany algorytm kompresji %s\n" #, c-format msgid "it is strongly suggested that you update your preferences and\n" @@ -2900,7 +2900,7 @@ msgstr "klucz %s: podklucz uszkodzony przez serwer został naprawiony\n" #, c-format msgid "key %s: accepted non self-signed user ID \"%s\"\n" -msgstr "klucz %s: przyjęto identyfikator nie podpisany nim samym ,,%s''\n" +msgstr "klucz %s: przyjęto identyfikator nie podpisany nim samym „%s”\n" #, c-format msgid "key %s: no valid user IDs\n" @@ -2924,11 +2924,11 @@ msgstr "brak zapisywalnego zbioru kluczy: %s\n" #, c-format msgid "error writing keyring '%s': %s\n" -msgstr "błąd zapisu zbioru kluczy ,,%s'': %s\n" +msgstr "błąd zapisu zbioru kluczy „%s”: %s\n" #, c-format msgid "key %s: public key \"%s\" imported\n" -msgstr "klucz %s: klucz publiczny ,,%s'' wczytano do zbioru\n" +msgstr "klucz %s: klucz publiczny „%s” wczytano do zbioru\n" #, c-format msgid "key %s: doesn't match our copy\n" @@ -2936,47 +2936,47 @@ msgstr "klucz %s: nie zgadza się z lokalną kopią\n" #, c-format msgid "key %s: \"%s\" 1 new user ID\n" -msgstr "klucz %s: ,,%s'' 1 nowy identyfikator użytkownika\n" +msgstr "klucz %s: „%s” 1 nowy identyfikator użytkownika\n" #, c-format msgid "key %s: \"%s\" %d new user IDs\n" -msgstr "klucz %s: ,,%s'' %d nowych identyfikatorów użytkownika\n" +msgstr "klucz %s: „%s” %d nowych identyfikatorów użytkownika\n" #, c-format msgid "key %s: \"%s\" 1 new signature\n" -msgstr "klucz %s: ,,%s'' 1 nowy podpis\n" +msgstr "klucz %s: „%s” 1 nowy podpis\n" #, c-format msgid "key %s: \"%s\" %d new signatures\n" -msgstr "klucz %s: ,,%s'' %d nowych podpisów\n" +msgstr "klucz %s: „%s” %d nowych podpisów\n" #, c-format msgid "key %s: \"%s\" 1 new subkey\n" -msgstr "klucz %s: ,,%s'' 1 nowy podklucz\n" +msgstr "klucz %s: „%s” 1 nowy podklucz\n" #, c-format msgid "key %s: \"%s\" %d new subkeys\n" -msgstr "klucz %s: ,,%s'' %d nowych podkluczy\n" +msgstr "klucz %s: „%s” %d nowych podkluczy\n" #, c-format msgid "key %s: \"%s\" %d signature cleaned\n" -msgstr "klucz %s: ,,%s'' %d podpis wyczyszczony\n" +msgstr "klucz %s: „%s” %d podpis wyczyszczony\n" #, c-format msgid "key %s: \"%s\" %d signatures cleaned\n" -msgstr "klucz %s: ,,%s'' %d podpisów wyczyszczonych\n" +msgstr "klucz %s: „%s” %d podpisów wyczyszczonych\n" #, c-format msgid "key %s: \"%s\" %d user ID cleaned\n" -msgstr "klucz %s: ,,%s'' %d identyfikator użytkownika wyczyszczony\n" +msgstr "klucz %s: „%s” %d identyfikator użytkownika wyczyszczony\n" #, c-format msgid "key %s: \"%s\" %d user IDs cleaned\n" -msgstr "klucz %s: ,,%s'' %d identyfikatorów użytkownika wyczyszczonych\n" +msgstr "klucz %s: „%s” %d identyfikatorów użytkownika wyczyszczonych\n" #, c-format msgid "key %s: \"%s\" not changed\n" -msgstr "klucz %s: ,,%s'' bez zmian\n" +msgstr "klucz %s: „%s” bez zmian\n" #, c-format msgid "key %s: secret key imported\n" @@ -3005,7 +3005,7 @@ msgstr "" #, c-format msgid "To migrate '%s', with each smartcard, run: %s\n" msgstr "" -"Aby zmigrować ,,%s'', dla każdej karty procesorowej należy uruchomić: %s\n" +"Aby zmigrować „%s”, dla każdej karty procesorowej należy uruchomić: %s\n" #, c-format msgid "secret key %s: %s\n" @@ -3062,7 +3062,7 @@ msgstr "klucz %s: niepoprawny certyfikat unieważnienia: %s - odrzucony\n" #, c-format msgid "key %s: \"%s\" revocation certificate imported\n" -msgstr "klucz %s: ,,%s'' certyfikat unieważnienia został już wczytany\n" +msgstr "klucz %s: „%s” certyfikat unieważnienia został już wczytany\n" #, c-format msgid "key %s: no user ID for signature\n" @@ -3070,11 +3070,11 @@ msgstr "klucz %s: brak identyfikatora użytkownika do podpisu\n" #, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" -msgstr "klucz %s: algorytm asymetryczny dla id ,,%s'' nie jest obsługiwany\n" +msgstr "klucz %s: algorytm asymetryczny dla id „%s” nie jest obsługiwany\n" #, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" -msgstr "klucz %s: niepoprawny podpis na identyfikatorze ,,%s''\n" +msgstr "klucz %s: niepoprawny podpis na identyfikatorze „%s”\n" #, c-format msgid "key %s: unsupported public key algorithm\n" @@ -3110,7 +3110,7 @@ msgstr "klucz %s: usunięto wielokrotne unieważnienie podklucza\n" #, c-format msgid "key %s: skipped user ID \"%s\"\n" -msgstr "klucz %s: pominięto identyfikator użytkownika ,,%s''\n" +msgstr "klucz %s: pominięto identyfikator użytkownika „%s”\n" #, c-format msgid "key %s: skipped subkey\n" @@ -3161,7 +3161,7 @@ msgstr "" #, c-format msgid "key %s: \"%s\" revocation certificate added\n" -msgstr "klucz %s: ,,%s'' dodany certyfikat unieważnienia\n" +msgstr "klucz %s: „%s” dodany certyfikat unieważnienia\n" #, c-format msgid "key %s: direct key signature added\n" @@ -3228,23 +3228,23 @@ msgstr "" #, c-format msgid "error creating keybox '%s': %s\n" -msgstr "błąd tworzenia keyboksa ,,%s'': %s\n" +msgstr "błąd tworzenia keyboksa „%s”: %s\n" #, c-format msgid "error creating keyring '%s': %s\n" -msgstr "błąd tworzenia zbioru kluczy ,,%s'': %s\n" +msgstr "błąd tworzenia zbioru kluczy „%s”: %s\n" #, c-format msgid "keybox '%s' created\n" -msgstr "keybox ,,%s'' utworzony\n" +msgstr "keybox „%s” utworzony\n" #, c-format msgid "keyring '%s' created\n" -msgstr "zbiór kluczy ,,%s'' został utworzony\n" +msgstr "zbiór kluczy „%s” został utworzony\n" #, c-format msgid "keyblock resource '%s': %s\n" -msgstr "zasób bloku klucza ,,%s'': %s\n" +msgstr "zasób bloku klucza „%s”: %s\n" #, c-format msgid "failed to rebuild keyring cache: %s\n" @@ -3289,12 +3289,12 @@ msgstr "Proszę wpisać domenę ograniczającą ten podpis lub Enter dla żadnej #, c-format msgid "Skipping user ID \"%s\", which is not a text ID.\n" msgstr "" -"Pominięto identyfikator użytkownika ,,%s'' nie będący identyfikatorem " +"Pominięto identyfikator użytkownika „%s” nie będący identyfikatorem " "tekstowym.\n" #, c-format msgid "User ID \"%s\" is revoked." -msgstr "Identyfikator użytkownika ,,%s'' został unieważniony." +msgstr "Identyfikator użytkownika „%s” został unieważniony." msgid "Are you sure you still want to sign it? (y/N) " msgstr "Czy na pewno chcesz podpisać? (t/N) " @@ -3304,15 +3304,15 @@ msgstr " Nie da się złożyć podpisu.\n" #, c-format msgid "User ID \"%s\" is expired." -msgstr "Identyfikator użytkownika ,,%s'' przekroczył swój termin ważności." +msgstr "Identyfikator użytkownika „%s” przekroczył swój termin ważności." #, c-format msgid "User ID \"%s\" is not self-signed." -msgstr "Identyfikator ,,%s'' nie jest podpisany swoim kluczem." +msgstr "Identyfikator „%s” nie jest podpisany swoim kluczem." #, c-format msgid "User ID \"%s\" is signable. " -msgstr "Identyfikator użytkownika ,,%s'' jest podpisywalny. " +msgstr "Identyfikator użytkownika „%s” jest podpisywalny. " msgid "Sign it? (y/N) " msgstr "Podpisać go? (t/N) " @@ -3322,7 +3322,7 @@ msgid "" "The self-signature on \"%s\"\n" "is a PGP 2.x-style signature.\n" msgstr "" -"Podpis klucza nim samym na ,,%s''\n" +"Podpis klucza nim samym na „%s”\n" "jest podpisem złożonym przez PGP 2.x.\n" msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) " @@ -3333,7 +3333,7 @@ msgid "" "Your current signature on \"%s\"\n" "has expired.\n" msgstr "" -"Twój podpis na ,,%s''\n" +"Twój podpis na „%s”\n" "przekroczył datę ważności.\n" msgid "Do you want to issue a new signature to replace the expired one? (y/N) " @@ -3344,7 +3344,7 @@ msgid "" "Your current signature on \"%s\"\n" "is a local signature.\n" msgstr "" -"Twój podpis na ,,%s''\n" +"Twój podpis na „%s”\n" "jest podpisem prywatnym (lokalnym).\n" msgid "Do you want to promote it to a full exportable signature? (y/N) " @@ -3353,11 +3353,11 @@ msgstr "" #, c-format msgid "\"%s\" was already locally signed by key %s\n" -msgstr ",,%s'' jest już lokalnie podpisany kluczem %s\n" +msgstr "„%s” jest już lokalnie podpisany kluczem %s\n" #, c-format msgid "\"%s\" was already signed by key %s\n" -msgstr ",,%s'' jest już podpisany kluczem %s\n" +msgstr "„%s” jest już podpisany kluczem %s\n" msgid "Do you want to sign it again anyway? (y/N) " msgstr "Czy na pewno chcesz to podpisać jeszcze raz? (t/N) " @@ -3383,7 +3383,7 @@ msgid "" "to the person named above? If you don't know what to answer, enter \"0\".\n" msgstr "" "Jak dokładnie została przez Ciebie sprawdzona tożsamość tej osoby?\n" -"Jeśli nie wiesz co odpowiedzieć, podaj ,,0''.\n" +"Jeśli nie wiesz co odpowiedzieć, podaj „0”.\n" #, c-format msgid " (0) I will not answer.%s\n" @@ -3402,7 +3402,7 @@ msgid " (3) I have done very careful checking.%s\n" msgstr " (3) Bardzo dokładnie.%s\n" msgid "Your selection? (enter '?' for more information): " -msgstr "Wybór (,,?'' podaje więcej informacji): " +msgstr "Wybór („?” podaje więcej informacji): " #, c-format msgid "" @@ -3410,7 +3410,7 @@ msgid "" "key \"%s\" (%s)\n" msgstr "" "Czy jesteś naprawdę pewien, że chcesz podpisać ten klucz\n" -"swoim kluczem ,,%s'' (%s)\n" +"swoim kluczem „%s” (%s)\n" msgid "This will be a self-signature.\n" msgstr "To będzie podpis klucza nim samym.\n" @@ -3610,8 +3610,8 @@ msgid "" " a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures\n" " (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n" msgstr "" -"* Polecenie ,,sign'' można poprzedzić ,,l'' dla lokalnych sygnatur (lsign),\n" -" ,,t'' dla sygnatur zaufania (tsign) albo ,,nr'' dla sygnatur nie\n" +"* Polecenie „sign” można poprzedzić „l” dla lokalnych sygnatur (lsign),\n" +" „t” dla sygnatur zaufania (tsign) albo „nr” dla sygnatur nie\n" " podlegających unieważnieniu (nrsign), albo dowolną ich kombinacją " "(ltsign,\n" " tnrsign itd.).\n" @@ -3631,14 +3631,14 @@ msgstr "Podpowiedź: wybierz identyfikatory użytkownika do podpisania.\n" #, c-format msgid "Unknown signature type '%s'\n" -msgstr "Nieznany rodzaj podpisu ,,%s''\n" +msgstr "Nieznany rodzaj podpisu „%s”\n" msgid "You must select at least one user ID.\n" msgstr "Musisz wybrać co najmniej jeden identyfikator użytkownika.\n" #, c-format msgid "(Use the '%s' command.)\n" -msgstr "(Należy użyć polecenia ,,%s''.)\n" +msgstr "(Należy użyć polecenia „%s”.)\n" msgid "You can't delete the last user ID!\n" msgstr "Nie możesz usunąć ostatniego identyfikatora użytkownika!\n" @@ -3663,11 +3663,11 @@ msgstr "Polecenie oczekuje argumentu będącego nazwą pliku\n" #, c-format msgid "Can't open '%s': %s\n" -msgstr "Nie można otworzyć ,,%s'': %s\n" +msgstr "Nie można otworzyć „%s”: %s\n" #, c-format msgid "Error reading backup key from '%s': %s\n" -msgstr "Błąd podczas odczytu klucza zapasowego z ,,%s'': %s\n" +msgstr "Błąd podczas odczytu klucza zapasowego z „%s”: %s\n" msgid "You must select at least one key.\n" msgstr "Musisz wybrać co najmniej jeden klucz.\n" @@ -3738,15 +3738,15 @@ msgstr "ustawienie głównego identyfikatora użytkownika nie powiodło się: %s #, c-format msgid "\"%s\" is not a fingerprint\n" -msgstr ",,%s'' nie jest odciskiem\n" +msgstr "„%s” nie jest odciskiem\n" #, c-format msgid "\"%s\" is not the primary fingerprint\n" -msgstr ",,%s'' nie jest głównym odciskiem\n" +msgstr "„%s” nie jest głównym odciskiem\n" #, c-format msgid "Invalid user ID '%s': %s\n" -msgstr "Błędny identyfikator użytkownika ,,%s'': %s\n" +msgstr "Błędny identyfikator użytkownika „%s”: %s\n" msgid "No matching user IDs." msgstr "Brak pasującego identyfikatora użytkownika." @@ -3764,15 +3764,15 @@ msgstr "unieważnienie podpisu klucza nie powiodło się: %s\n" #, c-format msgid "'%s' is not a valid expiration time\n" -msgstr ",,%s'' nie jest poprawnym czasem wygaśnięcia\n" +msgstr "„%s” nie jest poprawnym czasem wygaśnięcia\n" #, c-format msgid "\"%s\" is not a proper fingerprint\n" -msgstr ",,%s'' nie jest właściwym odciskiem\n" +msgstr "„%s” nie jest właściwym odciskiem\n" #, c-format msgid "subkey \"%s\" not found\n" -msgstr "podklucz ,,%s'' nie został odnaleziony\n" +msgstr "podklucz „%s” nie został odnaleziony\n" msgid "Preferred keyserver: " msgstr "Preferowany serwer kluczy: " @@ -3909,22 +3909,22 @@ msgstr "niepoprawny" #, c-format msgid "User ID \"%s\" compacted: %s\n" -msgstr "Identyfikator użytkownika ,,%s'' upakowany: %s\n" +msgstr "Identyfikator użytkownika „%s” upakowany: %s\n" #, c-format msgid "User ID \"%s\": %d signature removed\n" msgid_plural "User ID \"%s\": %d signatures removed\n" -msgstr[0] "Identyfikator użytkownika ,,%s'': %d podpis usunięty\n" -msgstr[1] "Identyfikator użytkownika ,,%s'': %d podpisy usunięte\n" -msgstr[2] "Identyfikator użytkownika ,,%s'': %d podpisów usuniętych\n" +msgstr[0] "Identyfikator użytkownika „%s”: %d podpis usunięty\n" +msgstr[1] "Identyfikator użytkownika „%s”: %d podpisy usunięte\n" +msgstr[2] "Identyfikator użytkownika „%s”: %d podpisów usuniętych\n" #, c-format msgid "User ID \"%s\": already minimized\n" -msgstr "Identyfikator użytkownika ,,%s'': już zmniejszony.\n" +msgstr "Identyfikator użytkownika „%s”: już zmniejszony.\n" #, c-format msgid "User ID \"%s\": already clean\n" -msgstr "Identyfikator użytkownika ,,%s'': już czysty.\n" +msgstr "Identyfikator użytkownika „%s”: już czysty.\n" msgid "" "WARNING: This is a PGP 2.x-style key. Adding a designated revoker may " @@ -4009,7 +4009,7 @@ msgstr "Proszę wybrać dokładnie jeden identyfikator użytkownika.\n" #, c-format msgid "skipping v3 self-signature on user ID \"%s\"\n" -msgstr "podpis w wersji 3 na identyfikatorze ,,%s'' zostaje pominięty\n" +msgstr "podpis w wersji 3 na identyfikatorze „%s” zostaje pominięty\n" msgid "Enter your preferred keyserver URL: " msgstr "Podaj preferowany URL serwera kluczy: " @@ -4036,7 +4036,7 @@ msgstr "Brak identyfikatora użytkownika o skrócie %s\n" #, c-format msgid "No subkey with key ID '%s'.\n" -msgstr "Brak podklucza o identyfikatorze ,,%s''.\n" +msgstr "Brak podklucza o identyfikatorze „%s”.\n" #, c-format msgid "No subkey with index %d\n" @@ -4044,7 +4044,7 @@ msgstr "Brak podklucza o numerze %d.\n" #, c-format msgid "user ID: \"%s\"\n" -msgstr "identyfikator użytkownika: ,,%s''\n" +msgstr "identyfikator użytkownika: „%s”\n" #, c-format msgid "signed by your key %s on %s%s%s\n" @@ -4091,7 +4091,7 @@ msgstr "" #, c-format msgid "user ID \"%s\" is already revoked\n" -msgstr "identyfikator użytkownika ,,%s'' został już unieważniony\n" +msgstr "identyfikator użytkownika „%s” został już unieważniony\n" #, c-format msgid "WARNING: a user ID signature is dated %d seconds in the future\n" @@ -4120,11 +4120,11 @@ msgstr "" #, c-format msgid "invalid value for option '%s'\n" -msgstr "błędna wartość dla opcji ,,%s''\n" +msgstr "błędna wartość dla opcji „%s”\n" #, c-format msgid "preference '%s' duplicated\n" -msgstr "ustawienie ,,%s'' powtarza się\n" +msgstr "ustawienie „%s” powtarza się\n" #, c-format msgid "too many cipher preferences\n" @@ -4145,7 +4145,7 @@ msgstr "zbyt wiele ustawień szyfru\n" #, c-format msgid "invalid item '%s' in preference string\n" -msgstr "niewłaściwy element ,,%s'' w tekście ustawień\n" +msgstr "niewłaściwy element „%s” w tekście ustawień\n" #, c-format msgid "writing direct signature\n" @@ -4435,7 +4435,7 @@ msgstr "Niewłaściwy znak w imieniu lub nazwisku\n" #, c-format msgid "The characters '%s' and '%s' may not appear in name\n" -msgstr "Znaki ,,%s'' i ,,%s'' nie mogą występować w inieniu ani nazwisku\n" +msgstr "Znaki „%s” i „%s” nie mogą występować w inieniu ani nazwisku\n" msgid "Email address: " msgstr "Adres poczty elektronicznej: " @@ -4451,7 +4451,7 @@ msgstr "Niewłaściwy znak w komentarzu\n" #, c-format msgid "You are using the '%s' character set.\n" -msgstr "Używany zestaw znaków: ,,%s''.\n" +msgstr "Używany zestaw znaków: „%s”.\n" #, c-format msgid "" @@ -4534,7 +4534,7 @@ msgid "" "\n" msgstr "" "Będzie tworzony klucz dla:\n" -" ,,%s''\n" +" „%s”\n" "\n" msgid "Continue? (Y/n) " @@ -4542,7 +4542,7 @@ msgstr "Kontynuować? (T/n) " #, c-format msgid "A key for \"%s\" already exists\n" -msgstr "klucz dla ,,%s'' już istnieje\n" +msgstr "klucz dla „%s” już istnieje\n" msgid "Create anyway? (y/N) " msgstr "Utworzyć klucz mimo to? (t/N) " @@ -4554,8 +4554,8 @@ msgstr "tworzenie mimo to\n" #, c-format msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n" msgstr "" -"Uwaga: pełną funkcjonalność generowania klucza można uzyskać przez ,,%s " -"%s''.\n" +"Uwaga: pełną funkcjonalność generowania klucza można uzyskać przez „%s " +"%s”.\n" #, c-format msgid "Key generation canceled.\n" @@ -4563,15 +4563,15 @@ msgstr "Procedura generacji klucza została anulowana.\n" #, c-format msgid "can't create backup file '%s': %s\n" -msgstr "nie można utworzyć pliku kopii zapasowej ,,%s'': %s\n" +msgstr "nie można utworzyć pliku kopii zapasowej „%s”: %s\n" #, c-format msgid "Note: backup of card key saved to '%s'\n" -msgstr "Uwaga: kopia zapasowa klucza karty zapisana do ,,%s''\n" +msgstr "Uwaga: kopia zapasowa klucza karty zapisana do „%s”\n" #, c-format msgid "writing public key to '%s'\n" -msgstr "zapis klucza publicznego w ,,%s''\n" +msgstr "zapis klucza publicznego w „%s”\n" #, c-format msgid "no writable public keyring found: %s\n" @@ -4579,7 +4579,7 @@ msgstr "brak zapisywalnego zbioru kluczy publicznych: %s\n" #, c-format msgid "error writing public keyring '%s': %s\n" -msgstr "błąd podczas zapisu zbioru kluczy publicznych ,,%s'': %s\n" +msgstr "błąd podczas zapisu zbioru kluczy publicznych „%s”: %s\n" msgid "public and secret key created and signed.\n" msgstr "klucz publiczny i prywatny (tajny) zostały utworzone i podpisane.\n" @@ -4697,7 +4697,7 @@ msgstr " Nr seryjny karty =" #, c-format msgid "caching keyring '%s'\n" -msgstr "buforowanie zbioru kluczy ,,%s''\n" +msgstr "buforowanie zbioru kluczy „%s”\n" #, c-format msgid "%lu keys cached so far (%lu signature)\n" @@ -4754,7 +4754,7 @@ msgstr "niepoprawny protokół serwera kluczy (nasz %d != moduł obsługi %d)\n" #, c-format msgid "\"%s\" not a key ID: skipping\n" -msgstr ",,%s'' nie jest identyfikatorem klucza - pominięto\n" +msgstr "„%s” nie jest identyfikatorem klucza - pominięto\n" #, c-format msgid "refreshing %d key from %s\n" @@ -4769,7 +4769,7 @@ msgstr "OSTRZEŻENIE: nie można odświeżyć klucza %s przez %s: %s\n" #, c-format msgid "key \"%s\" not found on keyserver\n" -msgstr "klucz ,,%s'' nie został odnaleziony na serwerze kluczy\n" +msgstr "klucz „%s” nie został odnaleziony na serwerze kluczy\n" #, c-format msgid "key not found on keyserver\n" @@ -4785,7 +4785,7 @@ msgstr "brak znanego serwera kluczy\n" #, c-format msgid "skipped \"%s\": %s\n" -msgstr "pominięty ,,%s'': %s\n" +msgstr "pominięty „%s”: %s\n" #, c-format msgid "sending key %s to %s\n" @@ -4793,7 +4793,7 @@ msgstr "wysyłanie klucza %s na %s\n" #, c-format msgid "requesting key from '%s'\n" -msgstr "zapytanie o klucz z ,,%s''\n" +msgstr "zapytanie o klucz z „%s”\n" #, c-format msgid "WARNING: unable to fetch URI %s: %s\n" @@ -4834,7 +4834,7 @@ msgstr "" #, c-format msgid " \"%s\"\n" -msgstr " ,,%s''\n" +msgstr " „%s”\n" #, c-format msgid "encrypted with %s key, ID %s\n" @@ -4883,7 +4883,7 @@ msgstr "" #, c-format msgid "Use the option '%s' to decrypt anyway.\n" -msgstr "Użycie mimo to opcji ,,%s'' do odszyfrowania.\n" +msgstr "Użycie mimo to opcji „%s” do odszyfrowania.\n" #, c-format msgid "decryption forced to fail!\n" @@ -4916,7 +4916,7 @@ msgstr "pierwotna nazwa pliku='%.*s'\n" #, c-format msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" -"osobny certyfikat unieważnienia - użyj ,,gpg --import'' aby go wczytać\n" +"osobny certyfikat unieważnienia - użyj „gpg --import” aby go wczytać\n" #, c-format msgid "no signature found\n" @@ -4924,15 +4924,15 @@ msgstr "nie znaleziono podpisu\n" #, c-format msgid "BAD signature from \"%s\"" -msgstr "NIEPOPRAWNY podpis złożony przez ,,%s''" +msgstr "NIEPOPRAWNY podpis złożony przez „%s”" #, c-format msgid "Expired signature from \"%s\"" -msgstr "Przeterminowany podpis złożony przez ,,%s''" +msgstr "Przeterminowany podpis złożony przez „%s”" #, c-format msgid "Good signature from \"%s\"" -msgstr "Poprawny podpis złożony przez ,,%s''" +msgstr "Poprawny podpis złożony przez „%s”" #, c-format msgid "signature verification suppressed\n" @@ -4956,7 +4956,7 @@ msgstr "Podpisano w %s kluczem %s o numerze %s\n" #, c-format msgid " issuer \"%s\"\n" -msgstr " wystawca ,,%s''\n" +msgstr " wystawca „%s”\n" #, c-format msgid "Key available at: " @@ -4964,14 +4964,14 @@ msgstr "Klucz dostępny w: " #, c-format msgid "Note: Use '%s' to make use of this info\n" -msgstr "Uwaga: aby wykorzystać tę informację, należy użyć ,,%s''\n" +msgstr "Uwaga: aby wykorzystać tę informację, należy użyć „%s”\n" msgid "[uncertain]" msgstr "[niepewne]" #, c-format msgid " aka \"%s\"" -msgstr " alias ,,%s''" +msgstr " alias „%s”" #, c-format msgid "WARNING: This key is not suitable for signing in %s mode\n" @@ -5004,7 +5004,7 @@ msgstr ", algorytm klucza " #, c-format msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n" msgstr "" -"OSTRZEŻENIE: to nie jest oddzielony podpis; plik ,,%s'' NIE został " +"OSTRZEŻENIE: to nie jest oddzielony podpis; plik „%s” NIE został " "zweryfikowany!\n" #, c-format @@ -5031,7 +5031,7 @@ msgstr "podpis starego typu (PGP 2.x).\n" #, c-format msgid "fstat of '%s' failed in %s: %s\n" -msgstr "fstat na ,,%s'' nie powiodło się w %s: %s\n" +msgstr "fstat na „%s” nie powiodło się w %s: %s\n" #, c-format msgid "fstat(%d) failed in %s: %s\n" @@ -5083,27 +5083,27 @@ msgstr "(dalsze informacje: " #, c-format msgid "%s:%d: deprecated option \"%s\"\n" -msgstr "%s:%d: przestarzała opcja ,,%s''\n" +msgstr "%s:%d: przestarzała opcja „%s”\n" #, c-format msgid "please use \"%s%s\" instead\n" -msgstr "w jej miejsce należy użyć ,,%s%s''\n" +msgstr "w jej miejsce należy użyć „%s%s”\n" #, c-format msgid "WARNING: \"%s\" is a deprecated command - do not use it\n" msgstr "" -"OSTRZEŻENIE: ,,%s'' jest przestarzałym poleceniem - nie należy go używać\n" +"OSTRZEŻENIE: „%s” jest przestarzałym poleceniem - nie należy go używać\n" #, c-format msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n" msgstr "" -"%s:%u: ,,%s'' jest przestarzałe w tym pliku - ma znaczenie tylko w %s\n" +"%s:%u: „%s” jest przestarzałe w tym pliku - ma znaczenie tylko w %s\n" #, c-format msgid "" "WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n" msgstr "" -"OSTRZEŻENIE: ,,%s%s'' jest przestarzałą opcją - nie ma efektu z wyjątkiem " +"OSTRZEŻENIE: „%s%s” jest przestarzałą opcją - nie ma efektu z wyjątkiem " "%s\n" msgid "Uncompressed" @@ -5119,11 +5119,11 @@ msgstr "ta wiadomość może nie dać się odczytać za pomocą %s\n" #, c-format msgid "ambiguous option '%s'\n" -msgstr "niejednoznaczna opcja ,,%s''\n" +msgstr "niejednoznaczna opcja „%s”\n" #, c-format msgid "unknown option '%s'\n" -msgstr "nieznana opcja ,,%s''\n" +msgstr "nieznana opcja „%s”\n" #, c-format msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n" @@ -5132,11 +5132,11 @@ msgstr "" #, c-format msgid "unknown weak digest '%s'\n" -msgstr "nieznany słaby skrót ,,%s''\n" +msgstr "nieznany słaby skrót „%s”\n" #, c-format msgid "File '%s' exists. " -msgstr "Plik ,,%s'' istnieje. " +msgstr "Plik „%s” istnieje. " msgid "Overwrite? (y/N) " msgstr "Nadpisać? (t/N) " @@ -5223,7 +5223,7 @@ msgid "" "%s" msgstr "" "%s\n" -",,%.*s''\n" +"„%.*s”\n" "klucz %u-bitowy %s, ID %s,\n" "utworzony %s%s.\n" "%s" @@ -5246,7 +5246,7 @@ msgstr "Nazwa pliku ze zdjęciem w formacie JPEG: " #, c-format msgid "unable to open JPEG file '%s': %s\n" -msgstr "nie można otworzyć pliku JPEG ,,%s'': %s\n" +msgstr "nie można otworzyć pliku JPEG „%s”: %s\n" #, c-format msgid "This JPEG is really large (%d bytes) !\n" @@ -5257,7 +5257,7 @@ msgstr "Czy na pewno chcesz go użyć? (t/N) " #, c-format msgid "'%s' is not a JPEG file\n" -msgstr ",,%s'' nie jest plikiem JPEG\n" +msgstr "„%s” nie jest plikiem JPEG\n" msgid "Is this photo correct (y/N/q)? " msgstr "Czy zdjęcie jest w porządku? (t/N/w) " @@ -5274,7 +5274,7 @@ msgstr "" #, c-format msgid "unable to execute shell '%s': %s\n" -msgstr "nie można uruchomić powłoki ,,%s'': %s\n" +msgstr "nie można uruchomić powłoki „%s”: %s\n" #, c-format msgid "unnatural exit of external program\n" @@ -5286,11 +5286,11 @@ msgstr "błąd systemu podczas wołania programu zewnętrznego: %s\n" #, c-format msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n" -msgstr "OSTRZEŻENIE: nie można skasować pliku tymczasowego (%s) ,,%s'': %s\n" +msgstr "OSTRZEŻENIE: nie można skasować pliku tymczasowego (%s) „%s”: %s\n" #, c-format msgid "WARNING: unable to remove temp directory '%s': %s\n" -msgstr "OSTRZEŻENIE: nie można skasować tymczasowego katalogu ,,%s'': %s\n" +msgstr "OSTRZEŻENIE: nie można skasować tymczasowego katalogu „%s”: %s\n" #, c-format msgid "" @@ -5320,7 +5320,7 @@ msgstr "Brak wartości zaufania dla:\n" #, c-format msgid " aka \"%s\"\n" -msgstr " alias ,,%s''\n" +msgstr " alias „%s”\n" msgid "" "How much do you trust that this key actually belongs to the named user?\n" @@ -5390,7 +5390,7 @@ msgid "" "question with yes.\n" msgstr "" "Ten klucz jest niedobry! Został oznaczony jako niezaufany!\n" -"Jeżeli *naprawdę* wiesz, co robisz, możesz odpowiedzieć ,,tak'' na\n" +"Jeżeli *naprawdę* wiesz, co robisz, możesz odpowiedzieć „tak” na\n" "następne pytanie.\n" msgid "" @@ -5400,7 +5400,7 @@ msgid "" msgstr "" "NIE MA pewności, czy klucz należy do osoby wymienionej w identyfikatorze.\n" "Jeśli nie masz co do tego żadnych wątpliwości i *naprawdę* wiesz co robisz,\n" -"możesz odpowiedzieć ,,tak'' na następne pytanie.\n" +"możesz odpowiedzieć „tak” na następne pytanie.\n" msgid "Use this key anyway? (y/N) " msgstr "Użyć tego klucza pomimo to? (t/N) " @@ -5418,12 +5418,12 @@ msgstr "" #, fuzzy, c-format #| msgid "user ID: \"%s\"\n" msgid "checking User ID \"%s\"\n" -msgstr "identyfikator użytkownika: ,,%s''\n" +msgstr "identyfikator użytkownika: „%s”\n" #, fuzzy, c-format #| msgid "option '%s' given, but option '%s' not given\n" msgid "option %s given but issuer \"%s\" does not match\n" -msgstr "podano opcję ,,%s'', ale nie podano opcji ,,%s''\n" +msgstr "podano opcję „%s”, ale nie podano opcji „%s”\n" #, fuzzy, c-format #| msgid "key %s: doesn't match our copy\n" @@ -5433,7 +5433,7 @@ msgstr "klucz %s: nie zgadza się z lokalną kopią\n" #, fuzzy, c-format #| msgid "option '%s' given, but option '%s' not given\n" msgid "option %s given but no matching User ID found\n" -msgstr "podano opcję ,,%s'', ale nie podano opcji ,,%s''\n" +msgstr "podano opcję „%s”, ale nie podano opcji „%s”\n" #, c-format msgid "WARNING: This key has been revoked by its designated revoker!\n" @@ -5517,18 +5517,18 @@ msgstr "%s: pominięty: został już wybrany w innej opcji\n" #, c-format msgid "can't encrypt to '%s'\n" -msgstr "nie można zaszyfrować do ,,%s''\n" +msgstr "nie można zaszyfrować do „%s”\n" #, c-format msgid "option '%s' given, but no valid default keys given\n" -msgstr "podano opcję ,,%s'', ale nie podano poprawnych kluczy domyślnych\n" +msgstr "podano opcję „%s”, ale nie podano poprawnych kluczy domyślnych\n" #, c-format msgid "option '%s' given, but option '%s' not given\n" -msgstr "podano opcję ,,%s'', ale nie podano opcji ,,%s''\n" +msgstr "podano opcję „%s”, ale nie podano opcji „%s”\n" msgid "You did not specify a user ID. (you may use \"-r\")\n" -msgstr "Nie został podany identyfikator użytkownika (np. za pomocą ,,-r'')\n" +msgstr "Nie został podany identyfikator użytkownika (np. za pomocą „-r”)\n" msgid "Current recipients:\n" msgstr "Aktualni odbiorcy:\n" @@ -5556,7 +5556,7 @@ msgstr "pominięty: został już wybrany w innej opcji\n" #, c-format msgid "unknown default recipient \"%s\"\n" -msgstr "nieznany domyślny adresat ,,%s''\n" +msgstr "nieznany domyślny adresat „%s”\n" #, c-format msgid "no valid addressees\n" @@ -5591,7 +5591,7 @@ msgstr "brak podpisanych danych\n" #, c-format msgid "can't open signed data '%s'\n" -msgstr "nie można otworzyć podpisanego pliku ,,%s''\n" +msgstr "nie można otworzyć podpisanego pliku „%s”\n" #, c-format msgid "can't open signed data fd=%d: %s\n" @@ -5666,7 +5666,7 @@ msgstr "Certyfikat unieważnienia został utworzony.\n" #, c-format msgid "no revocation keys found for \"%s\"\n" -msgstr "brak kluczy unieważniających dla ,,%s''\n" +msgstr "brak kluczy unieważniających dla „%s”\n" msgid "This is a revocation certificate for the OpenPGP key:" msgstr "To certyfikat unieważnienia dla klucza OpenPGP:" @@ -5676,7 +5676,7 @@ msgid "" "declare that a key shall not anymore be used. It is not possible\n" "to retract such a revocation certificate once it has been published." msgstr "" -"Certyfikat unieważnienia to rodzaj ,,wyłącznika awaryjnego,, do\n" +"Certyfikat unieważnienia to rodzaj „wyłącznika awaryjnego” do\n" "publicznego zadeklarowania, że klucz nie powinien być już więcej\n" "używany. Po opublikowaniu takiego certyfikatu nie jest już możliwe\n" "wycofanie go." @@ -5692,7 +5692,7 @@ msgstr "" "klucza tajnego. Co więcej, jeśli klucz tajny jest nadal dostępny,\n" "lepiej wygenerować nowy certyfikat unieważnienia i podać powód\n" "unieważnienia. Więcej szczegółów w opisie polecenia gpg\n" -",,--generate-revocation'' w podręczniku do GnuPG." +"„--generate-revocation” w podręczniku do GnuPG." msgid "" "To avoid an accidental use of this file, a colon has been inserted\n" @@ -5706,18 +5706,18 @@ msgstr "" #, c-format msgid "revocation certificate stored as '%s.rev'\n" -msgstr "certyfikat unieważnienia został zapisany jako ,,%s.rev''\n" +msgstr "certyfikat unieważnienia został zapisany jako „%s.rev”\n" #, c-format msgid "secret key \"%s\" not found\n" -msgstr "klucz prywatny ,,%s'' nie został odnaleziony\n" +msgstr "klucz prywatny „%s” nie został odnaleziony\n" #. TRANSLATORS: The %s prints a key specification which #. for example has been given at the command line. Several lines #. lines with secret key infos are printed after this message. #, c-format msgid "'%s' matches multiple secret keys:\n" -msgstr ",,%s'' pasuje do wielu kluczy tajnych:\n" +msgstr "„%s” pasuje do wielu kluczy tajnych:\n" #, c-format msgid "error searching the keyring: %s\n" @@ -5907,7 +5907,7 @@ msgstr "" #, c-format msgid "%s/%s signature from: \"%s\"\n" -msgstr "podpis %s/%s złożony przez: ,,%s''\n" +msgstr "podpis %s/%s złożony przez: „%s”\n" #, c-format msgid "" @@ -5933,7 +5933,7 @@ msgstr "" #, c-format msgid "skipped \"%s\": duplicated\n" -msgstr "pominięty ,,%s'': duplikat\n" +msgstr "pominięty „%s”: duplikat\n" #, c-format msgid "skipped: secret key already present\n" @@ -5958,7 +5958,7 @@ msgstr "" #, c-format msgid "error in '%s': %s\n" -msgstr "błąd w ,,%s'': %s\n" +msgstr "błąd w „%s”: %s\n" msgid "line too long" msgstr "linia zbyt długa" @@ -5974,11 +5974,11 @@ msgstr "brak wartości zaufania właściciela" #, c-format msgid "error finding trust record in '%s': %s\n" -msgstr "błąd podczas szukania zapisu wartości zaufania w ,,%s'': %s\n" +msgstr "błąd podczas szukania zapisu wartości zaufania w „%s”: %s\n" #, c-format msgid "read error in '%s': %s\n" -msgstr "błąd odczytu w ,,%s'': %s\n" +msgstr "błąd odczytu w „%s”: %s\n" #, c-format msgid "trustdb: sync failed: %s\n" @@ -5986,11 +5986,11 @@ msgstr "baza zaufania: synchronizacja nie powiodła się %s\n" #, c-format msgid "can't create lock for '%s'\n" -msgstr "nie można utworzyć blokady dla ,,%s''\n" +msgstr "nie można utworzyć blokady dla „%s”\n" #, c-format msgid "can't lock '%s'\n" -msgstr "nie można zablokować ,,%s''\n" +msgstr "nie można zablokować „%s”\n" #, c-format msgid "trustdb rec %lu: lseek failed: %s\n" @@ -6010,7 +6010,7 @@ msgstr "%s: katalog nie istnieje!\n" #, c-format msgid "can't access '%s': %s\n" -msgstr "nie można dostać się do ,,%s'': %s\n" +msgstr "nie można dostać się do „%s”: %s\n" #, c-format msgid "%s: failed to create version record: %s" @@ -6130,7 +6130,7 @@ msgstr "błąd inicjowania bazy danych TOFU: %s\n" #, c-format msgid "error opening TOFU database '%s': %s\n" -msgstr "błąd otwierania bazy danych TOFU ,,%s'': %s\n" +msgstr "błąd otwierania bazy danych TOFU „%s”: %s\n" #, c-format msgid "error updating TOFU database: %s\n" @@ -6139,19 +6139,19 @@ msgstr "błąd uaktualniania bazy danych TOFU: %s\n" #, c-format msgid "" "This is the first time the email address \"%s\" is being used with key %s." -msgstr "To pierwsze użycie adresu e-mail ,,%s'' z kluczem %s." +msgstr "To pierwsze użycie adresu e-mail „%s” z kluczem %s." #, c-format msgid "The email address \"%s\" is associated with %d key!" msgid_plural "The email address \"%s\" is associated with %d keys!" -msgstr[0] "Adres e-mail ,,%s'' jest powiązany z %d kluczem!" -msgstr[1] "Adres e-mail ,,%s'' jest powiązany z %d kluczami!" -msgstr[2] "Adres e-mail ,,%s'' jest powiązany z %d kluczami!" +msgstr[0] "Adres e-mail „%s” jest powiązany z %d kluczem!" +msgstr[1] "Adres e-mail „%s” jest powiązany z %d kluczami!" +msgstr[2] "Adres e-mail „%s” jest powiązany z %d kluczami!" msgid " Since this binding's policy was 'auto', it has been changed to 'ask'." msgstr "" -" Ponieważ polityką tego powiązania było ,,auto'', została zmieniona na ,," -"ask''." +" Ponieważ polityką tego powiązania było „auto”, została zmieniona na „" +"ask”." #, c-format msgid "" @@ -6159,7 +6159,7 @@ msgid "" "or whether you think someone is impersonating \"%s\"." msgstr "" "Proszę zdecydować, czy ten adres e-mail powinien być powiązany z kluczem %s, " -"czy raczej ktoś się podszywa za ,,%s''." +"czy raczej ktoś się podszywa za „%s”." #, c-format msgid "error gathering other user IDs: %s\n" @@ -6179,13 +6179,13 @@ msgstr "błąd zbierania statystyk podpisów: %s\n" #, c-format msgid "The email address \"%s\" is associated with %d key:\n" msgid_plural "The email address \"%s\" is associated with %d keys:\n" -msgstr[0] "Adres e-mail ,,%s'' jest powiązany z %d kluczem:\n" -msgstr[1] "Adres e-mail ,,%s'' jest powiązany z %d kluczami:\n" -msgstr[2] "Adres e-mail ,,%s'' jest powiązany z %d kluczami:\n" +msgstr[0] "Adres e-mail „%s” jest powiązany z %d kluczem:\n" +msgstr[1] "Adres e-mail „%s” jest powiązany z %d kluczami:\n" +msgstr[2] "Adres e-mail „%s” jest powiązany z %d kluczami:\n" #, c-format msgid "Statistics for keys with the email address \"%s\":\n" -msgstr "Statystyki dla kluczy o adresie e-mail ,,%s'':\n" +msgstr "Statystyki dla kluczy o adresie e-mail „%s”:\n" msgid "this key" msgstr "ten klucz" @@ -6432,7 +6432,7 @@ msgstr "" #, c-format msgid "'%s' is not a valid long keyID\n" -msgstr ",,%s'' nie jest poprawnym długim identyfikatorem klucza\n" +msgstr "„%s” nie jest poprawnym długim identyfikatorem klucza\n" #, c-format msgid "key %s: accepted as trusted key\n" @@ -6485,11 +6485,11 @@ msgstr "następne sprawdzanie bazy odbędzie się %s\n" #, c-format msgid "no need for a trustdb check with '%s' trust model\n" -msgstr "nie ma potrzeby sprawdzania trustdb przy modelu zaufania ,,%s''\n" +msgstr "nie ma potrzeby sprawdzania trustdb przy modelu zaufania „%s”\n" #, c-format msgid "no need for a trustdb update with '%s' trust model\n" -msgstr "nie ma potrzeby uaktualniania trustdb przy modelu zaufania ,,%s''\n" +msgstr "nie ma potrzeby uaktualniania trustdb przy modelu zaufania „%s”\n" #, c-format msgid "public key %s not found: %s\n" @@ -6497,7 +6497,7 @@ msgstr "klucz publiczny %s nie odnaleziony: %s\n" #, c-format msgid "please do a --check-trustdb\n" -msgstr "należy uruchomić gpg z opcją ,,--check-trustdb''\n" +msgstr "należy uruchomić gpg z opcją „--check-trustdb”\n" #, c-format msgid "checking the trustdb\n" @@ -6614,7 +6614,7 @@ msgstr "OSTRZEŻENIE: wiadomość nie była zabezpieczona przed manipulacją\n" #, fuzzy, c-format #| msgid "ambiguous option '%s'\n" msgid "Hint: Do not use option %s\n" -msgstr "niejednoznaczna opcja ,,%s''\n" +msgstr "niejednoznaczna opcja „%s”\n" msgid "set debugging flags" msgstr "ustawienie flag diagnostycznych" @@ -7001,7 +7001,7 @@ msgstr "" #, c-format msgid "please use the option '--daemon' to run the program in the background\n" -msgstr "proszę użyć opcji ,,--daemon'' do uruchomienia programu w tle\n" +msgstr "proszę użyć opcji „--daemon” do uruchomienia programu w tle\n" #, c-format msgid "handler for fd %d started\n" @@ -7041,7 +7041,7 @@ msgstr "polityka oznaczona jako krytyczna bez skonfigurowanych polityk" #, c-format msgid "failed to open '%s': %s\n" -msgstr "nie udało się otworzyć ,,%s'': %s\n" +msgstr "nie udało się otworzyć „%s”: %s\n" #, c-format msgid "Note: non-critical certificate policy not allowed" @@ -7092,7 +7092,7 @@ msgstr "status certyfikatu jest nieznany" #, c-format msgid "please make sure that the \"dirmngr\" is properly installed\n" -msgstr "proszę upewnić się, że ,,dirmngr'' jest poprawnie zainstalowany\n" +msgstr "proszę upewnić się, że „dirmngr” jest poprawnie zainstalowany\n" #, c-format msgid "checking the CRL failed: %s" @@ -7262,7 +7262,7 @@ msgid "" "created %s, expires %s.\n" msgstr "" "Proszę wprowadzić hasło aby odbezpieczyć klucz tajny certyfikatu X.509:\n" -",,%s''\n" +"„%s”\n" "S/N %s, ID 0x%08lX,\n" "stworzony %s, wygasa %s.\n" @@ -7313,11 +7313,11 @@ msgstr "linia %d: nie podano nazwy przedmiotu\n" #, c-format msgid "line %d: invalid subject name label '%.*s'\n" -msgstr "linia %d: niewłaściwa etykieta nazwy przedmiotu ,,%.*s''\n" +msgstr "linia %d: niewłaściwa etykieta nazwy przedmiotu „%.*s”\n" #, c-format msgid "line %d: invalid subject name '%s' at pos %d\n" -msgstr "linia %d: niewłaściwa nazwa przedmiotu ,,%s'' na pozycji %d\n" +msgstr "linia %d: niewłaściwa nazwa przedmiotu „%s” na pozycji %d\n" #, c-format msgid "line %d: not a valid email address\n" @@ -7329,11 +7329,11 @@ msgstr "linia %d: niewłaściwy numer seryjny\n" #, c-format msgid "line %d: invalid issuer name label '%.*s'\n" -msgstr "linia %d: niewłaściwa etykieta nazwy wystawcy ,,%.*s''\n" +msgstr "linia %d: niewłaściwa etykieta nazwy wystawcy „%.*s”\n" #, c-format msgid "line %d: invalid issuer name '%s' at pos %d\n" -msgstr "linia %d: niewłaściwa nazwa wystawcy ,,%s'' na pozycji %d\n" +msgstr "linia %d: niewłaściwa nazwa wystawcy „%s” na pozycji %d\n" #, c-format msgid "line %d: invalid date given\n" @@ -7341,7 +7341,7 @@ msgstr "linia %d: podano niewłaściwą datę\n" #, c-format msgid "line %d: error getting signing key by keygrip '%s': %s\n" -msgstr "linia %d: błąd pobierania klucza podpisującego z uchwytu ,,%s'': %s\n" +msgstr "linia %d: błąd pobierania klucza podpisującego z uchwytu „%s”: %s\n" #, c-format msgid "line %d: invalid hash algorithm given\n" @@ -7361,11 +7361,11 @@ msgstr "linia %d: niewłaściwa składnia rozszerzenia\n" #, c-format msgid "line %d: error reading key '%s' from card: %s\n" -msgstr "linia %d: błąd odczytu klucza ,,%s'' z karty: %s\n" +msgstr "linia %d: błąd odczytu klucza „%s” z karty: %s\n" #, c-format msgid "line %d: error getting key by keygrip '%s': %s\n" -msgstr "linia %d: błąd pobierania klucza z uchwytu ,,%s'': %s\n" +msgstr "linia %d: błąd pobierania klucza z uchwytu „%s”: %s\n" #, c-format msgid "line %d: key generation failed: %s <%s>\n" @@ -7410,7 +7410,7 @@ msgstr "Nie podano nazwy przedmiotu\n" #, c-format msgid "Invalid subject name label '%.*s'\n" -msgstr "Nieprawidłowa etykieta nazwy przedmiotu ,,%.*s''\n" +msgstr "Nieprawidłowa etykieta nazwy przedmiotu „%.*s”\n" #. TRANSLATORS: The 22 in the second string is the #. length of the first string up to the "%s". Please @@ -7419,7 +7419,7 @@ msgstr "Nieprawidłowa etykieta nazwy przedmiotu ,,%.*s''\n" #. drop everything after the number. #, c-format msgid "Invalid subject name '%s'\n" -msgstr "Nieprawidłowa nazwa przedmiotu ,,%s''\n" +msgstr "Nieprawidłowa nazwa przedmiotu „%s”\n" msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty" msgstr "33" @@ -7484,7 +7484,7 @@ msgstr "zaszyfrowano kluczem %s o identyfikatorze %s\n" #, c-format msgid "certificate '%s' not found: %s\n" -msgstr "nie znaleziono certyfikatu ,,%s'': %s\n" +msgstr "nie znaleziono certyfikatu „%s”: %s\n" #, c-format msgid "error locking keybox: %s\n" @@ -7492,15 +7492,15 @@ msgstr "błąd blokowania keyboksa: %s\n" #, c-format msgid "duplicated certificate '%s' deleted\n" -msgstr "powtórzony certyfikat ,,%s'' usunięty\n" +msgstr "powtórzony certyfikat „%s” usunięty\n" #, c-format msgid "certificate '%s' deleted\n" -msgstr "certyfikat ,,%s'' usunięty\n" +msgstr "certyfikat „%s” usunięty\n" #, c-format msgid "deleting certificate \"%s\" failed: %s\n" -msgstr "usunięcie certyfikatu ,,%s'' nie powiodło się: %s\n" +msgstr "usunięcie certyfikatu „%s” nie powiodło się: %s\n" #, c-format msgid "no valid recipients given\n" @@ -7582,10 +7582,10 @@ msgid "batch mode: never ask" msgstr "tryb wsadowy: bez żadnych pytań" msgid "assume yes on most questions" -msgstr "przyjęcie odpowiedzi ,,tak'' na większość pytań" +msgstr "przyjęcie odpowiedzi „tak” na większość pytań" msgid "assume no on most questions" -msgstr "przyjęcie odpowiedzi ,,nie'' na większość pytań" +msgstr "przyjęcie odpowiedzi „nie” na większość pytań" msgid "|FILE|write an audit log to FILE" msgstr "|PLIK|zapisanie logów audytowych do PLIKU" @@ -7605,19 +7605,19 @@ msgstr "" #, c-format msgid "Note: won't be able to encrypt to '%s': %s\n" -msgstr "Uwaga: nie można zaszyfrować do ,,%s'': %s\n" +msgstr "Uwaga: nie można zaszyfrować do „%s”: %s\n" #, c-format msgid "unknown validation model '%s'\n" -msgstr "nieznany model poprawności ,,%s''\n" +msgstr "nieznany model poprawności „%s”\n" #, c-format msgid "importing common certificates '%s'\n" -msgstr "import wspólnych certyfikatów ,,%s''\n" +msgstr "import wspólnych certyfikatów „%s”\n" #, c-format msgid "can't sign using '%s': %s\n" -msgstr "nie można podpisać z użyciem ,,%s'': %s\n" +msgstr "nie można podpisać z użyciem „%s”: %s\n" #, c-format msgid "invalid command (there is no implicit command)\n" @@ -7687,11 +7687,11 @@ msgstr "" #, c-format msgid "invalid formatted fingerprint in '%s', line %d\n" -msgstr "niewłaściwie sformatowany odcisk w ,,%s'', w linii %d\n" +msgstr "niewłaściwie sformatowany odcisk w „%s”, w linii %d\n" #, c-format msgid "invalid country code in '%s', line %d\n" -msgstr "niewłaściwy kod kraju w ,,%s'', w linii %d\n" +msgstr "niewłaściwy kod kraju w „%s”, w linii %d\n" #, c-format msgid "" @@ -7703,7 +7703,7 @@ msgid "" "%s%sAre you really sure that you want to do this?" msgstr "" "Ta operacja złoży podpis przy użyciu certyfikatu:\n" -",,%s''\n" +"„%s”\n" "Utworzy to kwalifikowany podpis równoważny prawnie podpisowi odręcznemu.\n" "\n" "%s%sNa pewno chcesz to zrobić?" @@ -7723,7 +7723,7 @@ msgid "" "Note, that this certificate will NOT create a qualified signature!" msgstr "" "Ta operacja złoży podpis przy użyciu certyfikatu:\n" -",,%s''\n" +"„%s”\n" "Należy zauważyć, że ten certyfikat NIE utworzy kwalifikowanego podpisu!" #, c-format @@ -7798,19 +7798,19 @@ msgstr "porzucanie %u certyfikatów z pamięci podręcznej\n" #, c-format msgid "can't parse certificate '%s': %s\n" -msgstr "nie można przeanalizować certyfikatu ,,%s'': %s\n" +msgstr "nie można przeanalizować certyfikatu „%s”: %s\n" #, c-format msgid "certificate '%s' already cached\n" -msgstr "certyfikat ,,%s'' jest już w pamięci podręcznej\n" +msgstr "certyfikat „%s” jest już w pamięci podręcznej\n" #, c-format msgid "trusted certificate '%s' loaded\n" -msgstr "certyfikat zaufany ,,%s'' załadowany\n" +msgstr "certyfikat zaufany „%s” załadowany\n" #, c-format msgid "certificate '%s' loaded\n" -msgstr "certyfikat ,,%s'' załadowany\n" +msgstr "certyfikat „%s” załadowany\n" #, c-format msgid " SHA1 fingerprint = %s\n" @@ -7824,7 +7824,7 @@ msgstr " przedmiot =" #, c-format msgid "error loading certificate '%s': %s\n" -msgstr "błąd ładowania certyfikatu ,,%s'': %s\n" +msgstr "błąd ładowania certyfikatu „%s”: %s\n" #, c-format msgid "permanently loaded certificates: %u\n" @@ -7852,7 +7852,7 @@ msgstr "błąd zapisu certyfikatu w pamięci podręcznej: %s\n" #, c-format msgid "invalid SHA1 fingerprint string '%s'\n" -msgstr "niewłaściwy łańcuch odcisku SHA1 ,,%s''\n" +msgstr "niewłaściwy łańcuch odcisku SHA1 „%s”\n" #, c-format msgid "error fetching certificate by S/N: %s\n" @@ -7872,27 +7872,27 @@ msgstr "błąd pobierania authorityKeyIdentifier: %s\n" #, c-format msgid "creating directory '%s'\n" -msgstr "tworzenie katalogu ,,%s''\n" +msgstr "tworzenie katalogu „%s”\n" #, c-format msgid "error creating directory '%s': %s\n" -msgstr "błąd tworzenia katalogu ,,%s'': %s\n" +msgstr "błąd tworzenia katalogu „%s”: %s\n" #, c-format msgid "ignoring database dir '%s'\n" -msgstr "zignorowano katalog bazy danych ,,%s''\n" +msgstr "zignorowano katalog bazy danych „%s”\n" #, c-format msgid "error reading directory '%s': %s\n" -msgstr "błąd odczytu katalogu ,,%s'': %s\n" +msgstr "błąd odczytu katalogu „%s”: %s\n" #, c-format msgid "removing cache file '%s'\n" -msgstr "usuwanie pliku pamięci podręcznej ,,%s''\n" +msgstr "usuwanie pliku pamięci podręcznej „%s”\n" #, c-format msgid "not removing file '%s'\n" -msgstr "bez usuwania pliku ,,%s''\n" +msgstr "bez usuwania pliku „%s”\n" #, c-format msgid "error closing cache file: %s\n" @@ -7900,33 +7900,33 @@ msgstr "błąd zamykania pliku pamięci podręcznej: %s\n" #, c-format msgid "failed to open cache dir file '%s': %s\n" -msgstr "nie udało się otworzyć pliku katalogu pamięci podręcznej ,,%s'': %s\n" +msgstr "nie udało się otworzyć pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "error creating new cache dir file '%s': %s\n" -msgstr "błąd tworzenia nowego pliku katalogu pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd tworzenia nowego pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "error writing new cache dir file '%s': %s\n" msgstr "" -"błąd podczas zapisu nowego pliku katalogu pamięci podręcznej ,,%s'': %s\n" +"błąd podczas zapisu nowego pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "error closing new cache dir file '%s': %s\n" -msgstr "błąd zamykania nowego pliku katalogu pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd zamykania nowego pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "new cache dir file '%s' created\n" -msgstr "nowy plik katalogu pamięci podręcznej ,,%s'' został utworzony\n" +msgstr "nowy plik katalogu pamięci podręcznej „%s” został utworzony\n" #, c-format msgid "failed to re-open cache dir file '%s': %s\n" msgstr "" -"nie udało ponownie otworzyć pliku katalogu pamięci podręcznej ,,%s'': %s\n" +"nie udało ponownie otworzyć pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "first record of '%s' is not the version\n" -msgstr "pierwszy rekord ,,%s'' nie jest wersją\n" +msgstr "pierwszy rekord „%s” nie jest wersją\n" #, c-format msgid "old version of cache directory - cleaning up\n" @@ -7938,36 +7938,36 @@ msgstr "stara wersja katalogu pamięci podręcznej - poddaję się\n" #, c-format msgid "extra field detected in crl record of '%s' line %u\n" -msgstr "wykryto nadmiarowe pole w rekordzie CRL ,,%s'', linia %u\n" +msgstr "wykryto nadmiarowe pole w rekordzie CRL „%s”, linia %u\n" #, c-format msgid "invalid line detected in '%s' line %u\n" -msgstr "wykryto niewłaściwą linię w ,,%s'', linia %u\n" +msgstr "wykryto niewłaściwą linię w „%s”, linia %u\n" #, c-format msgid "duplicate entry detected in '%s' line %u\n" -msgstr "wykryto powtórzony wpis w ,,%s'', linia %u\n" +msgstr "wykryto powtórzony wpis w „%s”, linia %u\n" #, c-format msgid "unsupported record type in '%s' line %u skipped\n" -msgstr "pominięto nieobsługiwany typ rekordu w ,,%s'', linia %u\n" +msgstr "pominięto nieobsługiwany typ rekordu w „%s”, linia %u\n" #, c-format msgid "invalid issuer hash in '%s' line %u\n" -msgstr "nieprawidłowy skrót wystawcy w ,,%s'', linia %u\n" +msgstr "nieprawidłowy skrót wystawcy w „%s”, linia %u\n" #, c-format msgid "no issuer DN in '%s' line %u\n" -msgstr "brak DN wystawcy w ,,%s'', linia %u\n" +msgstr "brak DN wystawcy w „%s”, linia %u\n" #, c-format msgid "invalid timestamp in '%s' line %u\n" -msgstr "nieprawidłowy znacznik czasu w ,,%s'', linia %u\n" +msgstr "nieprawidłowy znacznik czasu w „%s”, linia %u\n" #, c-format msgid "WARNING: invalid cache file hash in '%s' line %u\n" msgstr "" -"UWAGA: nieprawidłowy skrót pliku pamięci podręcznej w ,,%s'', linia %u\n" +"UWAGA: nieprawidłowy skrót pliku pamięci podręcznej w „%s”, linia %u\n" #, c-format msgid "detected errors in cache dir file\n" @@ -7980,16 +7980,16 @@ msgstr "proszę sprawdzić przyczynę i ręcznie usunąć ten plik\n" #, c-format msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "" -"nie udało się utworzyć pliku tymczasowego katalogu pamięci podręcznej ,," -"%s'': %s\n" +"nie udało się utworzyć pliku tymczasowego katalogu pamięci podręcznej „" +"%s”: %s\n" #, c-format msgid "error renaming '%s' to '%s': %s\n" -msgstr "błąd zmiany nazwy ,,%s'' na ,,%s'': %s\n" +msgstr "błąd zmiany nazwy „%s” na „%s”: %s\n" #, c-format msgid "can't hash '%s': %s\n" -msgstr "nie można policzyć skrótu ,,%s'': %s\n" +msgstr "nie można policzyć skrótu „%s”: %s\n" #, c-format msgid "error setting up MD5 hash context: %s\n" @@ -7997,11 +7997,11 @@ msgstr "błąd ustawiania kontekstu skrótu MD5: %s\n" #, c-format msgid "error hashing '%s': %s\n" -msgstr "błąd liczenia skrótu ,,%s'': %s\n" +msgstr "błąd liczenia skrótu „%s”: %s\n" #, c-format msgid "invalid formatted checksum for '%s'\n" -msgstr "niewłaściwie sformatowana suma kontrolna ,,%s''\n" +msgstr "niewłaściwie sformatowana suma kontrolna „%s”\n" #, c-format msgid "too many open cache files; can't open anymore\n" @@ -8010,15 +8010,15 @@ msgstr "" #, c-format msgid "opening cache file '%s'\n" -msgstr "otwieranie pliku pamięci podręcznej ,,%s''\n" +msgstr "otwieranie pliku pamięci podręcznej „%s”\n" #, c-format msgid "error opening cache file '%s': %s\n" -msgstr "błąd otwierania pliku pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd otwierania pliku pamięci podręcznej „%s”: %s\n" #, c-format msgid "error initializing cache file '%s' for reading: %s\n" -msgstr "błąd inicjowania pliku pamięci podręcznej ,,%s'' do odczytu: %s\n" +msgstr "błąd inicjowania pliku pamięci podręcznej „%s” do odczytu: %s\n" #, c-format msgid "calling unlock_db_file on a closed file\n" @@ -8094,7 +8094,7 @@ msgstr "konwersja S-wyrażenia nie powiodła się: %s\n" #, c-format msgid "unknown hash algorithm '%s'\n" -msgstr "niewłaściwy algorytm skrótu ,,%s''\n" +msgstr "niewłaściwy algorytm skrótu „%s”\n" #, c-format msgid "gcry_md_open for algorithm %d failed: %s\n" @@ -8155,17 +8155,17 @@ msgstr "ksba_crl_set_reader nie powiodło się: %s\n" #, c-format msgid "removed stale temporary cache file '%s'\n" -msgstr "usunięto zleżały plik tymczasowy pamięci podręcznej ,,%s''\n" +msgstr "usunięto zleżały plik tymczasowy pamięci podręcznej „%s”\n" #, c-format msgid "problem removing stale temporary cache file '%s': %s\n" msgstr "" -"problem z usunięciem zleżałego pliku tymczasowego pamięci podręcznej ,,%s'': " +"problem z usunięciem zleżałego pliku tymczasowego pamięci podręcznej „%s”: " "%s\n" #, c-format msgid "error creating temporary cache file '%s': %s\n" -msgstr "błąd tworzenia pliku tymczasowego pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd tworzenia pliku tymczasowego pamięci podręcznej „%s”: %s\n" #, c-format msgid "crl_parse_insert failed: %s\n" @@ -8173,11 +8173,11 @@ msgstr "crl_parse_insert nie powiodło się: %s\n" #, c-format msgid "error finishing temporary cache file '%s': %s\n" -msgstr "błąd finalizacji pliku tymczasowego pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd finalizacji pliku tymczasowego pamięci podręcznej „%s”: %s\n" #, c-format msgid "error closing temporary cache file '%s': %s\n" -msgstr "błąd zamykania pliku tymczasowego pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd zamykania pliku tymczasowego pamięci podręcznej „%s”: %s\n" #, c-format msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n" @@ -8198,11 +8198,11 @@ msgstr "błąd odczytu rozszerzeń CRL: %s\n" #, c-format msgid "creating cache file '%s'\n" -msgstr "błąd tworzenia pliku pamięci podręcznej ,,%s''\n" +msgstr "błąd tworzenia pliku pamięci podręcznej „%s”\n" #, c-format msgid "problem renaming '%s' to '%s': %s\n" -msgstr "problem ze zmianą nazwy ,,%s'' na ,,%s'': %s\n" +msgstr "problem ze zmianą nazwy „%s” na „%s”: %s\n" #, c-format msgid "" @@ -8280,7 +8280,7 @@ msgstr "Dostęp do CRL niemożliwy z powodu wyłączonego %s\n" #, c-format msgid "error retrieving '%s': %s\n" -msgstr "błąd odtwarzania ,,%s'': %s\n" +msgstr "błąd odtwarzania „%s”: %s\n" #, c-format msgid "error initializing reader object: %s\n" @@ -8345,7 +8345,7 @@ msgstr "błąd odczytu certyfikatu ze standardowego wejścia: %s\n" #, c-format msgid "error reading certificate from '%s': %s\n" -msgstr "błąd odczytu certyfikatu z ,,%s'': %s\n" +msgstr "błąd odczytu certyfikatu z „%s”: %s\n" #, c-format msgid "certificate too large to make any sense\n" @@ -8361,7 +8361,7 @@ msgstr "wyszukanie nie powiodło się: %s\n" #, c-format msgid "loading CRL '%s' failed: %s\n" -msgstr "załadowanie CRL ,,%s'' nie powiodła się: %s\n" +msgstr "załadowanie CRL „%s” nie powiodła się: %s\n" #, c-format msgid "a dirmngr daemon is up and running\n" @@ -8385,7 +8385,7 @@ msgstr "sprawdzenie certyfikatu nie powiodło się: %s\n" #, c-format msgid "got status: '%s'\n" -msgstr "otrzymano status: ,,%s''\n" +msgstr "otrzymano status: „%s”\n" #, c-format msgid "error writing base64 encoding: %s\n" @@ -8393,7 +8393,7 @@ msgstr "błąd zapisu kodowania base64: %s\n" #, c-format msgid "unsupported inquiry '%s'\n" -msgstr "nieobsługiwane zapytanie ,,%s''\n" +msgstr "nieobsługiwane zapytanie „%s”\n" #, c-format msgid "absolute file name expected\n" @@ -8401,7 +8401,7 @@ msgstr "oczekiwano bezwzględnej nazwy pliku\n" #, c-format msgid "looking up '%s'\n" -msgstr "wyszukiwanie ,,%s''\n" +msgstr "wyszukiwanie „%s”\n" msgid "list the contents of the CRL cache" msgstr "lista zawartości pamięci podręcznej CRL" @@ -8511,7 +8511,7 @@ msgid "" "options)\n" msgstr "" "@\n" -"(pełną listę poleceń i opcji można znaleźć w podręczniku ,,info'')\n" +"(pełną listę poleceń i opcji można znaleźć w podręczniku „info”)\n" msgid "Usage: @DIRMNGR@ [options] (-h for help)" msgstr "Składnia: @DIRMNGR@ [opcje] (-h wyświetla pomoc)" @@ -8537,11 +8537,11 @@ msgstr "dwukropki nie są dozwolone w nazwie gniazda\n" #, c-format msgid "fetching CRL from '%s' failed: %s\n" -msgstr "pobranie CRL z ,,%s'' nie powiodło się: %s\n" +msgstr "pobranie CRL z „%s” nie powiodło się: %s\n" #, c-format msgid "processing CRL from '%s' failed: %s\n" -msgstr "przetworzenie CRL z ,,%s'' nie powiodło się: %s\n" +msgstr "przetworzenie CRL z „%s” nie powiodło się: %s\n" #, c-format msgid "%s:%u: line too long - skipped\n" @@ -8590,11 +8590,11 @@ msgstr "otrzymano sygnał %d - nie zdefiniowano akcji\n" #, c-format msgid "error accessing '%s': http status %u\n" -msgstr "błąd dostępu do ,,%s'': status http %u\n" +msgstr "błąd dostępu do „%s”: status http %u\n" #, c-format msgid "URL '%s' redirected to '%s' (%u)\n" -msgstr "URL ,,%s'' przekierowany na ,,%s'' (%u)\n" +msgstr "URL „%s” przekierowany na „%s” (%u)\n" #, c-format msgid "too many redirections\n" @@ -8602,7 +8602,7 @@ msgstr "za dużo przekierowań\n" #, c-format msgid "redirection changed to '%s'\n" -msgstr "przekierowanie zmienione na ,,%s''\n" +msgstr "przekierowanie zmienione na „%s”\n" #, c-format msgid "error printing log line: %s\n" @@ -8638,7 +8638,7 @@ msgstr "błędny znak 0x%02x w nazwie hosta - nie dodano\n" #, c-format msgid "adding '%s:%d' to the ldap server list\n" -msgstr "dodano ,,%s:%d'' do listy serwerów LDAP\n" +msgstr "dodano „%s:%d” do listy serwerów LDAP\n" #, c-format msgid "malloc failed: %s\n" @@ -8646,11 +8646,11 @@ msgstr "malloc nie powiodło się: %s\n" #, c-format msgid "'%s' is not an LDAP URL\n" -msgstr ",,%s'' nie jest URL-em LDAP\n" +msgstr "„%s” nie jest URL-em LDAP\n" #, c-format msgid "'%s' is an invalid LDAP URL\n" -msgstr ",,%s'' jest nieprawidłowym URL-em LDAP\n" +msgstr "„%s” jest nieprawidłowym URL-em LDAP\n" #, c-format msgid "ldap_search hit the size limit of the server\n" @@ -8711,19 +8711,19 @@ msgstr "błąd budowania żądania OCSP: %s\n" #, c-format msgid "error connecting to '%s': %s\n" -msgstr "błąd połączenia z ,,%s'': %s\n" +msgstr "błąd połączenia z „%s”: %s\n" #, c-format msgid "error reading HTTP response for '%s': %s\n" -msgstr "błąd odczytu odpowiedzi HTTP dla ,,%s'': %s\n" +msgstr "błąd odczytu odpowiedzi HTTP dla „%s”: %s\n" #, c-format msgid "error parsing OCSP response for '%s': %s\n" -msgstr "błąd przetwarzania odpowiedzi OCSP dla ,,%s'': %s\n" +msgstr "błąd przetwarzania odpowiedzi OCSP dla „%s”: %s\n" #, c-format msgid "OCSP responder at '%s' status: %s\n" -msgstr "status respondera OCSP pod ,,%s'': %s\n" +msgstr "status respondera OCSP pod „%s”: %s\n" #, c-format msgid "failed to establish a hashing context for OCSP: %s\n" @@ -8731,7 +8731,7 @@ msgstr "nie udało się ustanowić kontekstu haszowania dla OCSP: %s\n" #, c-format msgid "hashing the OCSP response for '%s' failed: %s\n" -msgstr "liczenie skrótu odpowiedzi OCSP dla ,,%s'' nie powiodło się: %s\n" +msgstr "liczenie skrótu odpowiedzi OCSP dla „%s” nie powiodło się: %s\n" #, c-format msgid "not signed by a default OCSP signer's certificate" @@ -8776,11 +8776,11 @@ msgstr "nie zdefiniowano domyślnego podpisującego OCSP\n" #, c-format msgid "using default OCSP responder '%s'\n" -msgstr "użycie domyślnego respondera OCSP ,,%s''\n" +msgstr "użycie domyślnego respondera OCSP „%s”\n" #, c-format msgid "using OCSP responder '%s'\n" -msgstr "użycie respondera OCSP ,,%s''\n" +msgstr "użycie respondera OCSP „%s”\n" #, c-format msgid "error getting OCSP status for target certificate: %s\n" @@ -8937,11 +8937,11 @@ msgstr "" #, c-format msgid "option \"%s\" requires a program and optional arguments\n" -msgstr "opcja ,,%s'' wymaga programu i opcjonalnych argumentów\n" +msgstr "opcja „%s” wymaga programu i opcjonalnych argumentów\n" #, c-format msgid "option \"%s\" ignored due to \"%s\"\n" -msgstr "opcja ,,%s'' zignorowana z powodu ,,%s''\n" +msgstr "opcja „%s” zignorowana z powodu „%s”\n" #, c-format msgid "receiving line failed: %s\n" @@ -8957,7 +8957,7 @@ msgstr "linia skrócona z powodu osadzonego znaku Nul\n" #, c-format msgid "unknown command '%s'\n" -msgstr "nieznane polecenie ,,%s''\n" +msgstr "nieznane polecenie „%s”\n" #, c-format msgid "sending line failed: %s\n" @@ -9007,7 +9007,7 @@ msgstr "Plik konfiguracyjny komponentu %s jest uszkodzony\n" #, c-format msgid "Note: Use the command \"%s%s\" to get details.\n" -msgstr "Podpowiedź: można użyć polecenia ,,%s%s'', aby uzyskać szczegóły.\n" +msgstr "Podpowiedź: można użyć polecenia „%s%s”, aby uzyskać szczegóły.\n" #, c-format msgid "External verification of component %s failed" @@ -9018,11 +9018,11 @@ msgstr "Uwaga, określenia grup są ignorowane\n" #, c-format msgid "error closing '%s'\n" -msgstr "błąd zamykania ,,%s''\n" +msgstr "błąd zamykania „%s”\n" #, c-format msgid "error parsing '%s'\n" -msgstr "błąd analizy ,,%s''\n" +msgstr "błąd analizy „%s”\n" msgid "list all components" msgstr "lista wszystkich komponentów" @@ -9182,7 +9182,7 @@ msgstr "" #, fuzzy #~| msgid "cipher algorithm '%s' may not be used in %s mode\n" #~ msgid "AEAD algorithm '%s' may not be used in %s mode\n" -#~ msgstr "szyfr ,,%s'' nie może być używany w trybie %s\n" +#~ msgstr "szyfr „%s” nie może być używany w trybie %s\n" #~ msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" #~ msgstr "wymuszone użycie szyfru %s (%d) kłóci się z ustawieniami adresata\n" @@ -9263,74 +9263,74 @@ msgstr "" #~ msgstr "błędny numer portu %d\n" #~ msgid "scanning result for attribute '%s'\n" -#~ msgstr "przeszukiwanie wyniku pod kątem atrybutu ,,%s''\n" +#~ msgstr "przeszukiwanie wyniku pod kątem atrybutu „%s”\n" #~ msgid "error writing to stdout: %s\n" #~ msgstr "błąd zapisu na standardowe wyjście: %s\n" #~ msgid " available attribute '%s'\n" -#~ msgstr " dostępny atrybut ,,%s''\n" +#~ msgstr " dostępny atrybut „%s”\n" #~ msgid "attribute '%s' not found\n" -#~ msgstr "nie znaleziono atrybutu ,,%s''\n" +#~ msgstr "nie znaleziono atrybutu „%s”\n" #~ msgid "found attribute '%s'\n" -#~ msgstr "znaleziono atrybut ,,%s''\n" +#~ msgstr "znaleziono atrybut „%s”\n" #~ msgid "processing url '%s'\n" -#~ msgstr "przetwarzanie URL-a ,,%s''\n" +#~ msgstr "przetwarzanie URL-a „%s”\n" #~ msgid " user '%s'\n" -#~ msgstr " użytkownik ,,%s''\n" +#~ msgstr " użytkownik „%s”\n" #~ msgid " pass '%s'\n" -#~ msgstr " hasło ,,%s''\n" +#~ msgstr " hasło „%s”\n" #~ msgid " host '%s'\n" -#~ msgstr " host ,,%s''\n" +#~ msgstr " host „%s”\n" #~ msgid " port %d\n" #~ msgstr " port %d\n" #~ msgid " DN '%s'\n" -#~ msgstr " DN ,,%s''\n" +#~ msgstr " DN „%s”\n" #~ msgid " filter '%s'\n" -#~ msgstr " filtr ,,%s''\n" +#~ msgstr " filtr „%s”\n" #~ msgid " attr '%s'\n" -#~ msgstr " atrybut ,,%s''\n" +#~ msgstr " atrybut „%s”\n" #~ msgid "no host name in '%s'\n" -#~ msgstr "brak nazwy hosta w ,,%s''\n" +#~ msgstr "brak nazwy hosta w „%s”\n" #~ msgid "no attribute given for query '%s'\n" -#~ msgstr "nie podano atrybutu dla zapytania ,,%s''\n" +#~ msgstr "nie podano atrybutu dla zapytania „%s”\n" #~ msgid "WARNING: using first attribute only\n" #~ msgstr "OSTRZEŻENIE: użyto tylko pierwszego atrybutu\n" #~ msgid "LDAP init to '%s:%d' failed: %s\n" -#~ msgstr "nie udało się zainicjować LDAP na ,,%s:%d'': %s\n" +#~ msgstr "nie udało się zainicjować LDAP na „%s:%d”: %s\n" #, fuzzy #~| msgid "LDAP init to '%s:%d' failed: %s\n" #~ msgid "LDAP init to '%s' failed: %s\n" -#~ msgstr "nie udało się zainicjować LDAP na ,,%s:%d'': %s\n" +#~ msgstr "nie udało się zainicjować LDAP na „%s:%d”: %s\n" #, fuzzy #~| msgid "LDAP init to '%s:%d' failed: %s\n" #~ msgid "LDAP init to '%s' done\n" -#~ msgstr "nie udało się zainicjować LDAP na ,,%s:%d'': %s\n" +#~ msgstr "nie udało się zainicjować LDAP na „%s:%d”: %s\n" #~ msgid "binding to '%s:%d' failed: %s\n" -#~ msgstr "dowiązanie do ,,%s:%d'' nie powiodło się: %s\n" +#~ msgstr "dowiązanie do „%s:%d” nie powiodło się: %s\n" #~ msgid "searching '%s' failed: %s\n" -#~ msgstr "szukanie ,,%s'' nie powiodło się: %s\n" +#~ msgstr "szukanie „%s” nie powiodło się: %s\n" #~ msgid "start_cert_fetch: invalid pattern '%s'\n" -#~ msgstr "start_cert_fetch: błędny wzorzec ,,%s''\n" +#~ msgstr "start_cert_fetch: błędny wzorzec „%s”\n" #~ msgid "ldapserver missing" #~ msgstr "brak pola ldapserver" @@ -9353,7 +9353,7 @@ msgstr "" #~ msgstr "użycie pliku loga dla serwera" #~ msgid "no running gpg-agent - starting '%s'\n" -#~ msgstr "gpg-agent nie działa - uruchamianie ,,%s''\n" +#~ msgstr "gpg-agent nie działa - uruchamianie „%s”\n" #~ msgid "argument not expected" #~ msgstr "nieoczekiwany argument" @@ -9387,7 +9387,7 @@ msgstr "" #, fuzzy #~| msgid "unknown command '%s'\n" #~ msgid "unknown meta command" -#~ msgstr "nieznane polecenie ,,%s''\n" +#~ msgstr "nieznane polecenie „%s”\n" #, fuzzy #~| msgid "unexpected armor: " @@ -9398,31 +9398,31 @@ msgstr "" #~ msgstr "błędna opcja" #~ msgid "missing argument for option \"%.50s\"\n" -#~ msgstr "brak argumentu dla opcji ,,%.50s''\n" +#~ msgstr "brak argumentu dla opcji „%.50s”\n" #~ msgid "option \"%.50s\" does not expect an argument\n" -#~ msgstr "opcja ,,%.50s'' nie może mieć argumentów\n" +#~ msgstr "opcja „%.50s” nie może mieć argumentów\n" #~ msgid "invalid command \"%.50s\"\n" -#~ msgstr "błędne polecenie ,,%.50s''\n" +#~ msgstr "błędne polecenie „%.50s”\n" #~ msgid "option \"%.50s\" is ambiguous\n" -#~ msgstr "opcja ,,%.50s'' jest niejednoznaczna\n" +#~ msgstr "opcja „%.50s” jest niejednoznaczna\n" #~ msgid "command \"%.50s\" is ambiguous\n" -#~ msgstr "polecenie ,,%.50s'' jest niejednoznaczne\n" +#~ msgstr "polecenie „%.50s” jest niejednoznaczne\n" #~ msgid "invalid option \"%.50s\"\n" -#~ msgstr "błędna opcja ,,%.50s''\n" +#~ msgstr "błędna opcja „%.50s”\n" #~ msgid "Note: no default option file '%s'\n" -#~ msgstr "Uwaga: brak domyślnego pliku opcji ,,%s''\n" +#~ msgstr "Uwaga: brak domyślnego pliku opcji „%s”\n" #~ msgid "option file '%s': %s\n" -#~ msgstr "plik opcji ,,%s'': %s\n" +#~ msgstr "plik opcji „%s”: %s\n" #~ msgid "unable to execute program '%s': %s\n" -#~ msgstr "nie można uruchomić programu ,,%s'': %s\n" +#~ msgstr "nie można uruchomić programu „%s”: %s\n" #~ msgid "unable to execute external program\n" #~ msgstr "nie można uruchomić zewnętrznego programu\n" @@ -9443,10 +9443,10 @@ msgstr "" #~ msgstr "honorowanie rekordu PKA ustawionego w kluczu przy pobieraniu kluczy" #~ msgid "Note: Verified signer's address is '%s'\n" -#~ msgstr "Uwaga: Sprawdzony adres pospisującego to ,,%s''\n" +#~ msgstr "Uwaga: Sprawdzony adres pospisującego to „%s”\n" #~ msgid "Note: Signer's address '%s' does not match DNS entry\n" -#~ msgstr "Uwaga: Adres podpisującego ,,%s'' nie pasuje do wpisu DNS\n" +#~ msgstr "Uwaga: Adres podpisującego „%s” nie pasuje do wpisu DNS\n" #~ msgid "trustlevel adjusted to FULL due to valid PKA info\n" #~ msgstr "" @@ -9476,7 +9476,7 @@ msgstr "" #~ msgstr "lista serwerów LDAP" #~ msgid "Note: old default options file '%s' ignored\n" -#~ msgstr "Uwaga: stary domyślny plik opcji ,,%s'' został zignorowany\n" +#~ msgstr "Uwaga: stary domyślny plik opcji „%s” został zignorowany\n" #~ msgid "" #~ "@\n" @@ -9524,7 +9524,7 @@ msgstr "" #~ msgstr "%s na %s nie powiódł się ze stanem %i\n" #~ msgid "can't create temporary directory '%s': %s\n" -#~ msgstr "nie można utworzyć katalogu tymczasowego ,,%s'': %s\n" +#~ msgstr "nie można utworzyć katalogu tymczasowego „%s”: %s\n" #~ msgid "could not open %s for writing: %s\n" #~ msgstr "nie udało się otworzyć %s do zapisu: %s\n" From 1ded50dd5b58a81a53579ef273ab0b7208310753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahelenia=20Ziemia=C5=84ska?= Date: Thu, 7 Dec 2023 11:56:54 +0900 Subject: [PATCH 267/869] po: Fix quotes in Polish Translation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -- Cherry-pick from 2.4 commit of: fa677a37cef007cad4ae772c96849b03931c5263 Signed-off-by: Ahelenia Ziemiańska --- po/pl.po | 790 +++++++++++++++++++++++++++---------------------------- 1 file changed, 395 insertions(+), 395 deletions(-) diff --git a/po/pl.po b/po/pl.po index 555da9661..dcbab2240 100644 --- a/po/pl.po +++ b/po/pl.po @@ -194,11 +194,11 @@ msgstr "klucze ssh większe niż %d bitów nie są obsługiwane\n" #, c-format msgid "can't create '%s': %s\n" -msgstr "nie można utworzyć ,,%s'': %s\n" +msgstr "nie można utworzyć „%s”: %s\n" #, c-format msgid "can't open '%s': %s\n" -msgstr "nie można otworzyć ,,%s'': %s\n" +msgstr "nie można otworzyć „%s”: %s\n" #, c-format msgid "no suitable card key found: %s\n" @@ -429,7 +429,7 @@ msgid "disallow the use of an external password cache" msgstr "niezezwalanie na użycie zewnętrznej pamięci podręcznej haseł" msgid "disallow clients to mark keys as \"trusted\"" -msgstr "niezezwalanie klientom na oznaczanie kluczy jako ,,zaufanych''" +msgstr "niezezwalanie klientom na oznaczanie kluczy jako „zaufanych”" msgid "allow presetting passphrase" msgstr "zezwolenie na predefiniowane hasło" @@ -496,7 +496,7 @@ msgstr "" #, c-format msgid "invalid debug-level '%s' given\n" -msgstr "podano błędny poziom diagnostyki ,,%s''\n" +msgstr "podano błędny poziom diagnostyki „%s”\n" #, c-format msgid "selected digest algorithm is invalid\n" @@ -504,15 +504,15 @@ msgstr "wybrany algorytm skrótów wiadomości jest niepoprawny\n" #, c-format msgid "reading options from '%s'\n" -msgstr "odczyt opcji z ,,%s''\n" +msgstr "odczyt opcji z „%s”\n" #, c-format msgid "Note: '%s' is not considered an option\n" -msgstr "Uwaga: ,,%s'' nie jest uznane za opcję\n" +msgstr "Uwaga: „%s” nie jest uznane za opcję\n" #, c-format msgid "WARNING: \"%s\" is a deprecated option\n" -msgstr "OSTRZEŻENIE: ,,%s'' jest przestarzałą opcją.\n" +msgstr "OSTRZEŻENIE: „%s” jest przestarzałą opcją.\n" #, c-format msgid "can't create socket: %s\n" @@ -520,7 +520,7 @@ msgstr "nie można utworzyć gniazda: %s\n" #, c-format msgid "socket name '%s' is too long\n" -msgstr "nazwa gniazda ,,%s'' zbyt długa\n" +msgstr "nazwa gniazda „%s” zbyt długa\n" #, c-format msgid "trying to steal socket from running %s\n" @@ -536,31 +536,31 @@ msgstr "błąd podczas pobierania nonce z gniazda\n" #, c-format msgid "error binding socket to '%s': %s\n" -msgstr "błąd podczas przypisywania gniazda do ,,%s'': %s\n" +msgstr "błąd podczas przypisywania gniazda do „%s”: %s\n" #, c-format msgid "can't set permissions of '%s': %s\n" -msgstr "nie można ustawić praw dostępu do ,,%s'': %s\n" +msgstr "nie można ustawić praw dostępu do „%s”: %s\n" #, c-format msgid "listening on socket '%s'\n" -msgstr "nasłuchiwanie na gnieździe ,,%s''\n" +msgstr "nasłuchiwanie na gnieździe „%s”\n" #, c-format msgid "can't create directory '%s': %s\n" -msgstr "nie można utworzyć katalogu ,,%s'': %s\n" +msgstr "nie można utworzyć katalogu „%s”: %s\n" #, c-format msgid "directory '%s' created\n" -msgstr "katalog ,,%s'' utworzony\n" +msgstr "katalog „%s” utworzony\n" #, c-format msgid "stat() failed for '%s': %s\n" -msgstr "stat() nie powiodło się dla ,,%s'': %s\n" +msgstr "stat() nie powiodło się dla „%s”: %s\n" #, c-format msgid "can't use '%s' as home directory\n" -msgstr "nie można użyć ,,%s'' jako katalogu domowego\n" +msgstr "nie można użyć „%s” jako katalogu domowego\n" #, c-format msgid "error reading nonce on fd %d: %s\n" @@ -667,31 +667,31 @@ msgstr "błąd podczas pytania o hasło: %s\n" #, c-format msgid "error opening '%s': %s\n" -msgstr "błąd podczas otwierania ,,%s'': %s\n" +msgstr "błąd podczas otwierania „%s”: %s\n" #, c-format msgid "file '%s', line %d: %s\n" -msgstr "plik ,,%s'', linia %d: %s\n" +msgstr "plik „%s”, linia %d: %s\n" #, c-format msgid "statement \"%s\" ignored in '%s', line %d\n" -msgstr "instrukcja \"%s\" zignorowana w ,,%s'', w linii %d\n" +msgstr "instrukcja \"%s\" zignorowana w „%s”, w linii %d\n" #, c-format msgid "system trustlist '%s' not available\n" -msgstr "systemowa lista zaufania ,,%s'' niedostępna\n" +msgstr "systemowa lista zaufania „%s” niedostępna\n" #, c-format msgid "bad fingerprint in '%s', line %d\n" -msgstr "błędny odcisk w ,,%s'', w linii %d\n" +msgstr "błędny odcisk w „%s”, w linii %d\n" #, c-format msgid "invalid keyflag in '%s', line %d\n" -msgstr "nieprawidłowa flaga klucza w ,,%s'', w linii %d\n" +msgstr "nieprawidłowa flaga klucza w „%s”, w linii %d\n" #, c-format msgid "error reading '%s', line %d: %s\n" -msgstr "błąd odczytu ,,%s'', w linii %d: %s\n" +msgstr "błąd odczytu „%s”, w linii %d: %s\n" #, c-format msgid "error reading list of trusted root certificates\n" @@ -710,7 +710,7 @@ msgid "" "Do you ultimately trust%%0A \"%s\"%%0Ato correctly certify user " "certificates?" msgstr "" -"Czy absolutnie ufasz, że%%0A ,,%s''%%0Apoprawnie poświadcza certyfikaty " +"Czy absolutnie ufasz, że%%0A „%s”%%0Apoprawnie poświadcza certyfikaty " "użytkowników?" msgid "Yes" @@ -732,7 +732,7 @@ msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " "fingerprint:%%0A %s" msgstr "" -"Proszę sprawdzić, że certyfikat zidentyfikowany jako:%%0a ,,%s''%%0Ama " +"Proszę sprawdzić, że certyfikat zidentyfikowany jako:%%0a „%s”%%0Ama " "odcisk:%%0A %s" #. TRANSLATORS: "Correct" is the label of a button and intended @@ -839,15 +839,15 @@ msgstr "oczekiwanie na zakończenie procesu %d nie powiodło się: %s\n" #, c-format msgid "error running '%s': probably not installed\n" -msgstr "błąd uruchamiania ,,%s'': prawdopodobnie nie zainstalowany\n" +msgstr "błąd uruchamiania „%s”: prawdopodobnie nie zainstalowany\n" #, c-format msgid "error running '%s': exit status %d\n" -msgstr "błąd uruchamiania ,,%s'': kod wyjścia %d\n" +msgstr "błąd uruchamiania „%s”: kod wyjścia %d\n" #, c-format msgid "error running '%s': terminated\n" -msgstr "błąd uruchamiania ,,%s'': zakończono\n" +msgstr "błąd uruchamiania „%s”: zakończono\n" #, c-format msgid "waiting for processes to terminate failed: %s\n" @@ -859,7 +859,7 @@ msgstr "błąd odczytu kodu zakończenia procesu %d: %s\n" #, c-format msgid "can't connect to '%s': %s\n" -msgstr "nie można się połączyć z ,,%s'': %s\n" +msgstr "nie można się połączyć z „%s”: %s\n" #, c-format msgid "problem setting the gpg-agent options\n" @@ -871,19 +871,19 @@ msgstr "nie można wyłączyć zrzutów pamięci: %s\n" #, c-format msgid "Warning: unsafe ownership on %s \"%s\"\n" -msgstr "Ostrzeżenie: niebezpieczne prawa własności do %s ,,%s''\n" +msgstr "Ostrzeżenie: niebezpieczne prawa własności do %s „%s”\n" #, c-format msgid "Warning: unsafe permissions on %s \"%s\"\n" -msgstr "Ostrzeżenie: niebezpieczne prawa dostępu do %s ,,%s''\n" +msgstr "Ostrzeżenie: niebezpieczne prawa dostępu do %s „%s”\n" #, c-format msgid "waiting for file '%s' to become accessible ...\n" -msgstr "oczekiwanie aż plik ,,%s'' stanie się dostępny...\n" +msgstr "oczekiwanie aż plik „%s” stanie się dostępny...\n" #, c-format msgid "renaming '%s' to '%s' failed: %s\n" -msgstr "zmiana nazwy ,,%s'' na ,,%s'' nie powiodła się: %s\n" +msgstr "zmiana nazwy „%s” na „%s” nie powiodła się: %s\n" #. TRANSLATORS: See doc/TRANSLATE about this string. msgid "yes" @@ -934,15 +934,15 @@ msgstr "błąd przydzielania wystarczającej ilości pamięci: %s\n" #, c-format msgid "%s:%u: obsolete option \"%s\" - it has no effect\n" -msgstr "%s:%u: przestarzała opcja ,,%s'' - nie ma efektu\n" +msgstr "%s:%u: przestarzała opcja „%s” - nie ma efektu\n" #, c-format msgid "WARNING: \"%s%s\" is an obsolete option - it has no effect\n" -msgstr "OSTRZEŻENIE: ,,%s%s'' jest przestarzałą opcją - nie ma efektu\n" +msgstr "OSTRZEŻENIE: „%s%s” jest przestarzałą opcją - nie ma efektu\n" #, c-format msgid "unknown debug flag '%s' ignored\n" -msgstr "nieznana flaga diagnostyczna ,,%s'' zignorowana\n" +msgstr "nieznana flaga diagnostyczna „%s” zignorowana\n" #, fuzzy, c-format #| msgid "waiting for the %s to come up ... (%ds)\n" @@ -977,7 +977,7 @@ msgstr "ustanowiono połączenie z procesem %s\n" #, fuzzy, c-format #| msgid "no running Dirmngr - starting '%s'\n" msgid "no running %s - starting '%s'\n" -msgstr "Dirmngr nie działa - uruchamianie ,,%s''\n" +msgstr "Dirmngr nie działa - uruchamianie „%s”\n" #, fuzzy, c-format #| msgid "connection to agent is in restricted mode\n" @@ -986,11 +986,11 @@ msgstr "połączenie z agentem jest w trybie ograniczonym\n" #, c-format msgid "error getting version from '%s': %s\n" -msgstr "błąd pobierania wersji z ,,%s'': %s\n" +msgstr "błąd pobierania wersji z „%s”: %s\n" #, c-format msgid "server '%s' is older than us (%s < %s)" -msgstr "serwer ,,%s'' jest starszy niż nasz (%s < %s)" +msgstr "serwer „%s” jest starszy niż nasz (%s < %s)" #, c-format msgid "WARNING: %s\n" @@ -1003,7 +1003,7 @@ msgstr "" #, c-format msgid "Note: Use the command \"%s\" to restart them.\n" -msgstr "Uwaga: do restartu ich należy użyć polecenia ,,%s''.\n" +msgstr "Uwaga: do restartu ich należy użyć polecenia „%s”.\n" #. TRANSLATORS: Copy the prefix between the vertical bars #. verbatim. It will not be printed. @@ -1140,7 +1140,7 @@ msgstr "Dirmngr sprawny" #, c-format msgid "No help available for '%s'." -msgstr "Brak pomocy dla ,,%s''." +msgstr "Brak pomocy dla „%s”." msgid "ignoring garbage line" msgstr "zignorowano błędną linię" @@ -1170,7 +1170,7 @@ msgstr "" #, c-format msgid "conversion from '%s' to '%s' not available\n" -msgstr "konwersja z ,,%s'' do ,,%s'' niedostępna\n" +msgstr "konwersja z „%s” do „%s” niedostępna\n" #, c-format msgid "iconv_open failed: %s\n" @@ -1178,15 +1178,15 @@ msgstr "iconv_open nie powiodło się: %s\n" #, c-format msgid "conversion from '%s' to '%s' failed: %s\n" -msgstr "konwersja z ,,%s'' do ,,%s'' nie powiodła się: %s\n" +msgstr "konwersja z „%s” do „%s” nie powiodła się: %s\n" #, c-format msgid "failed to create temporary file '%s': %s\n" -msgstr "nie udało się utworzyć pliku tymczasowego ,,%s'': %s\n" +msgstr "nie udało się utworzyć pliku tymczasowego „%s”: %s\n" #, c-format msgid "error writing to '%s': %s\n" -msgstr "błąd zapisu do ,,%s'': %s\n" +msgstr "błąd zapisu do „%s”: %s\n" #, c-format msgid "removing stale lockfile (created by %d)\n" @@ -1201,7 +1201,7 @@ msgstr "(zakleszczenie?) " #, c-format msgid "lock '%s' not made: %s\n" -msgstr "blokada ,,%s'' nie założona: %s\n" +msgstr "blokada „%s” nie założona: %s\n" #, c-format msgid "waiting for lock %s...\n" @@ -1213,11 +1213,11 @@ msgstr "biblioteka %s jest zbyt stara (wymagana %s, zainstalowana %s)\n" #, c-format msgid "error creating '%s': %s\n" -msgstr "błąd tworzenia ,,%s'': %s\n" +msgstr "błąd tworzenia „%s”: %s\n" #, c-format msgid "error closing '%s': %s\n" -msgstr "błąd zamykania ,,%s'': %s\n" +msgstr "błąd zamykania „%s”: %s\n" #, c-format msgid "armor: %s\n" @@ -1253,7 +1253,7 @@ msgstr "niepoprawne oznaczenie linii minusami: " #, c-format msgid "invalid radix64 character %02X skipped\n" -msgstr "niewłaściwy znak formatu radix64 ,,%02X'' został pominięty\n" +msgstr "niewłaściwy znak formatu radix64 „%02X” został pominięty\n" #, c-format msgid "premature eof (no CRC)\n" @@ -1304,15 +1304,15 @@ msgid "" "an '='\n" msgstr "" "nazwa adnotacji musi zawierać tylko znaki drukowalne lub spacje i kończyć " -"się znakiem ,,=''\n" +"się znakiem „=”\n" #, c-format msgid "a user notation name must contain the '@' character\n" -msgstr "nazwa adnotacji użytkownika musi zawierać znak ,,@''\n" +msgstr "nazwa adnotacji użytkownika musi zawierać znak „@”\n" #, c-format msgid "a notation name must not contain more than one '@' character\n" -msgstr "nazwa adnotacjinie może zawierać więcej niż jednego znaku ,,@''\n" +msgstr "nazwa adnotacjinie może zawierać więcej niż jednego znaku „@”\n" #, c-format msgid "a notation value must not use any control characters\n" @@ -1320,7 +1320,7 @@ msgstr "wartość adnotacji nie może zawierać żadnych znaków sterujących\n" #, c-format msgid "a notation name may not contain an '=' character\n" -msgstr "nazwa adnotacji nie może zawierać znaku ,,=''\n" +msgstr "nazwa adnotacji nie może zawierać znaku „=”\n" #, c-format msgid "a notation name must have only printable characters or spaces\n" @@ -1357,7 +1357,7 @@ msgstr "brak działającego dirmngr w tej sesji\n" #, fuzzy, c-format #| msgid "keyserver option \"%s\" may not be used in %s mode\n" msgid "keyserver option \"honor-keyserver-url\" may not be used in Tor mode\n" -msgstr "opcja serwera kluczy ,,%s'' nie może być używana w trybie %s\n" +msgstr "opcja serwera kluczy „%s” nie może być używana w trybie %s\n" msgid "WKD uses a cached result" msgstr "WKD używa zapamiętanego wyniku" @@ -1430,7 +1430,7 @@ msgid "Error: Only plain ASCII is currently allowed.\n" msgstr "Błąd: aktualnie dopuszczalne jest tylko czyste ASCII.\n" msgid "Error: The \"<\" character may not be used.\n" -msgstr "Błąd: znak ,,<'' nie może być użyty.\n" +msgstr "Błąd: znak „<” nie może być użyty.\n" msgid "Error: Double spaces are not allowed.\n" msgstr "Błąd: podwójne spacje nie są dopuszczalne.\n" @@ -1450,11 +1450,11 @@ msgstr "URL do odczytania klucza publicznego: " #, c-format msgid "error reading '%s': %s\n" -msgstr "błąd odczytu ,,%s'': %s\n" +msgstr "błąd odczytu „%s”: %s\n" #, c-format msgid "error writing '%s': %s\n" -msgstr "błąd zapisu ,,%s'': %s\n" +msgstr "błąd zapisu „%s”: %s\n" msgid "Login data (account name): " msgstr "Dane logowania (nazwa konta): " @@ -1590,7 +1590,7 @@ msgid "" "You should change them using the command --change-pin\n" msgstr "" "Fabryczne ustawienia PIN-ów to\n" -" PIN = ,,%s'' PIN administracyjny = ,,%s''\n" +" PIN = „%s” PIN administracyjny = „%s”\n" "Należy je zmienić przy użyciu polecenia --change-pin\n" msgid "Please select the type of key to generate:\n" @@ -1620,7 +1620,7 @@ msgid "Continue? (y/N) " msgstr "Kontynuować? (t/N) " msgid "Really do a factory reset? (enter \"yes\") " -msgstr "Naprawdę przywrócić stan fabryczny? (proszę wpisać ,,yes'') " +msgstr "Naprawdę przywrócić stan fabryczny? (proszę wpisać „yes”) " #, c-format msgid "error for setup KDF: %s\n" @@ -1712,7 +1712,7 @@ msgstr "Polecenia dla administratora nie są dozwolone\n" #, c-format msgid "Invalid command (try \"help\")\n" -msgstr "Niepoprawne polecenie (spróbuj ,,help'')\n" +msgstr "Niepoprawne polecenie (spróbuj „help”)\n" #, c-format msgid "--output doesn't work for this command\n" @@ -1720,11 +1720,11 @@ msgstr "opcja --output nie działa z tym poleceniem\n" #, c-format msgid "can't open '%s'\n" -msgstr "nie można otworzyć ,,%s''\n" +msgstr "nie można otworzyć „%s”\n" #, c-format msgid "key \"%s\" not found: %s\n" -msgstr "klucz ,,%s'' nie został odnaleziony: %s\n" +msgstr "klucz „%s” nie został odnaleziony: %s\n" #, c-format msgid "error reading keyblock: %s\n" @@ -1732,11 +1732,11 @@ msgstr "błąd odczytu bloku kluczy: %s\n" #, c-format msgid "key \"%s\" not found\n" -msgstr "klucz ,,%s'' nie został odnaleziony\n" +msgstr "klucz „%s” nie został odnaleziony\n" #, c-format msgid "can't do this in batch mode without \"--yes\"\n" -msgstr "bez opcji ,,--yes'' nie działa w trybie wsadowym\n" +msgstr "bez opcji „--yes” nie działa w trybie wsadowym\n" #, c-format msgid "(unless you specify the key by fingerprint)\n" @@ -1786,7 +1786,7 @@ msgstr "informacja o zaufaniu dla właściciela klucza została wymazana\n" #, c-format msgid "there is a secret key for public key \"%s\"!\n" -msgstr "dla klucza publicznego ,,%s'' istnieje klucz prywatny!\n" +msgstr "dla klucza publicznego „%s” istnieje klucz prywatny!\n" #, c-format msgid "use option \"--delete-secret-keys\" to delete it first.\n" @@ -1802,7 +1802,7 @@ msgstr "" #, fuzzy, c-format #| msgid "cipher algorithm '%s' may not be used in %s mode\n" msgid "cipher algorithm '%s' may not be used for encryption\n" -msgstr "szyfr ,,%s'' nie może być używany w trybie %s\n" +msgstr "szyfr „%s” nie może być używany w trybie %s\n" #, c-format msgid "(use option \"%s\" to override)\n" @@ -1810,7 +1810,7 @@ msgstr "" #, c-format msgid "cipher algorithm '%s' may not be used in %s mode\n" -msgstr "szyfr ,,%s'' nie może być używany w trybie %s\n" +msgstr "szyfr „%s” nie może być używany w trybie %s\n" #, c-format msgid "WARNING: key %s is not suitable for encryption in %s mode\n" @@ -1833,19 +1833,19 @@ msgstr "szyfrem %s\n" #, c-format msgid "'%s' already compressed\n" -msgstr ",,%s'' już jest skompresowany\n" +msgstr "„%s” już jest skompresowany\n" #, c-format msgid "WARNING: '%s' is an empty file\n" -msgstr "OSTRZEŻENIE: plik ,,%s'' jest pusty\n" +msgstr "OSTRZEŻENIE: plik „%s” jest pusty\n" #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" -msgstr "algorytm skrótu ,,%s'' nie może być używany w trybie %s\n" +msgstr "algorytm skrótu „%s” nie może być używany w trybie %s\n" #, c-format msgid "reading from '%s'\n" -msgstr "odczyt z ,,%s''\n" +msgstr "odczyt z „%s”\n" #, c-format msgid "" @@ -1858,11 +1858,11 @@ msgstr "" #, fuzzy, c-format #| msgid "%s/%s encrypted for: \"%s\"\n" msgid "%s/%s.%s encrypted for: \"%s\"\n" -msgstr "%s/%s zaszyfrowany dla: ,,%s''\n" +msgstr "%s/%s zaszyfrowany dla: „%s”\n" #, c-format msgid "option '%s' may not be used in %s mode\n" -msgstr "opcja ,,%s'' nie może być używana w trybie %s\n" +msgstr "opcja „%s” nie może być używana w trybie %s\n" #, fuzzy, c-format #| msgid "%s encrypted data\n" @@ -1890,7 +1890,7 @@ msgid "export attribute user IDs (generally photo IDs)" msgstr "eksport atrybutów ID użytkownika (ogólnie ID zdjęć)" msgid "export revocation keys marked as \"sensitive\"" -msgstr "eksport kluczy unieważniających oznaczonych jako ,,poufne''" +msgstr "eksport kluczy unieważniających oznaczonych jako „poufne”" msgid "remove unusable parts from key during export" msgstr "usunięcie bezużytecznych części z klucza przy eksporcie" @@ -1916,7 +1916,7 @@ msgstr " - pominięty" #, c-format msgid "writing to '%s'\n" -msgstr "zapis do ,,%s''\n" +msgstr "zapis do „%s”\n" #, c-format msgid "key %s: key material on-card - skipped\n" @@ -1939,11 +1939,11 @@ msgstr "[brak identyfikatora użytkownika]" #, c-format msgid "automatically retrieved '%s' via %s\n" -msgstr "automatycznie pobrano ,,%s'' poprzez %s\n" +msgstr "automatycznie pobrano „%s” poprzez %s\n" #, c-format msgid "error retrieving '%s' via %s: %s\n" -msgstr "błąd pobierania ,,%s'' poprzez %s: %s\n" +msgstr "błąd pobierania „%s” poprzez %s: %s\n" msgid "No fingerprint" msgstr "Brak odcisku" @@ -1954,23 +1954,23 @@ msgstr "szukanie świeżej kopii wygasłego klucza poprzez %s\n" #, c-format msgid "secret key \"%s\" not found: %s\n" -msgstr "klucz prywatny ,,%s'' nie został odnaleziony: %s\n" +msgstr "klucz prywatny „%s” nie został odnaleziony: %s\n" #, c-format msgid "(check argument of option '%s')\n" -msgstr "(sprawdzić argument opcji ,,%s'')\n" +msgstr "(sprawdzić argument opcji „%s”)\n" #, c-format msgid "Warning: not using '%s' as default key: %s\n" -msgstr "Ostrzeżenie: ,,%s'' nie jest użyty jako domyślny klucz: %s\n" +msgstr "Ostrzeżenie: „%s” nie jest użyty jako domyślny klucz: %s\n" #, c-format msgid "using \"%s\" as default secret key for signing\n" -msgstr "użycie ,,%s'' jako domyślnego klucza tajnego do podpisywania\n" +msgstr "użycie „%s” jako domyślnego klucza tajnego do podpisywania\n" #, c-format msgid "all values passed to '%s' ignored\n" -msgstr "wszystkie wartości przekazane do ,,%s'' zostały zignorowane\n" +msgstr "wszystkie wartości przekazane do „%s” zostały zignorowane\n" #, c-format msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n" @@ -1984,7 +1984,7 @@ msgstr "używany jest podklucz %s zamiast klucza głównego %s\n" #, c-format msgid "valid values for option '%s':\n" -msgstr "poprawne argimenty dla opcji ,,%s'':\n" +msgstr "poprawne argimenty dla opcji „%s”:\n" msgid "make a signature" msgstr "złożenie podpisu" @@ -2261,76 +2261,76 @@ msgstr "sprzeczne polecenia\n" #, c-format msgid "no = sign found in group definition '%s'\n" -msgstr "w definicji grupy ,,%s'' brak znaku ,,=''\n" +msgstr "w definicji grupy „%s” brak znaku „=”\n" #, c-format msgid "WARNING: unsafe ownership on homedir '%s'\n" msgstr "" -"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu domowego ,,%s''\n" +"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu domowego „%s”\n" #, c-format msgid "WARNING: unsafe ownership on configuration file '%s'\n" msgstr "" -"OSTRZEŻENIE: niebezpieczne prawa własności do pliku konfiguracyjnego ,,%s''\n" +"OSTRZEŻENIE: niebezpieczne prawa własności do pliku konfiguracyjnego „%s”\n" #, c-format msgid "WARNING: unsafe ownership on extension '%s'\n" -msgstr "OSTRZEŻENIE: niebezpieczne prawa własności do rozszerzenia ,,%s''\n" +msgstr "OSTRZEŻENIE: niebezpieczne prawa własności do rozszerzenia „%s”\n" #, c-format msgid "WARNING: unsafe permissions on homedir '%s'\n" -msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu domowego ,,%s''\n" +msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu domowego „%s”\n" #, c-format msgid "WARNING: unsafe permissions on configuration file '%s'\n" msgstr "" -"OSTRZEŻENIE: niebezpieczne prawa dostępu do pliku konfiguracyjnego ,,%s''\n" +"OSTRZEŻENIE: niebezpieczne prawa dostępu do pliku konfiguracyjnego „%s”\n" #, c-format msgid "WARNING: unsafe permissions on extension '%s'\n" -msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do rozszerzenia ,,%s''\n" +msgstr "OSTRZEŻENIE: niebezpieczne prawa dostępu do rozszerzenia „%s”\n" #, c-format msgid "WARNING: unsafe enclosing directory ownership on homedir '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa własności do katalogu zawierającego katalog " -"domowy ,,%s''\n" +"domowy „%s”\n" #, c-format msgid "" "WARNING: unsafe enclosing directory ownership on configuration file '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa własności do katalogu zawierającego plik " -"konfiguracyjny ,,%s''\n" +"konfiguracyjny „%s”\n" #, c-format msgid "WARNING: unsafe enclosing directory ownership on extension '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa własności do katalogu zawierającego " -"rozszerzenie ,,%s''\n" +"rozszerzenie „%s”\n" #, c-format msgid "WARNING: unsafe enclosing directory permissions on homedir '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu zawierającego katalog " -"domowy ,,%s''\n" +"domowy „%s”\n" #, c-format msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu zawierającego plik " -"konfiguracyjny ,,%s''\n" +"konfiguracyjny „%s”\n" #, c-format msgid "WARNING: unsafe enclosing directory permissions on extension '%s'\n" msgstr "" "OSTRZEŻENIE: niebezpieczne prawa dostępu do katalogu zawierającego " -"rozszerzenie ,,%s''\n" +"rozszerzenie „%s”\n" #, c-format msgid "unknown configuration item '%s'\n" -msgstr "nieznana opcja konfiguracyjna ,,%s''\n" +msgstr "nieznana opcja konfiguracyjna „%s”\n" msgid "display photo IDs during key listings" msgstr "wyświetlenie ID zdjęć przy wypisywaniu kluczy" @@ -2382,11 +2382,11 @@ msgstr "ustawienia (zaawansowane)" #, c-format msgid "unknown TOFU policy '%s'\n" -msgstr "nieznana polityka TOFU ,,%s''\n" +msgstr "nieznana polityka TOFU „%s”\n" #, c-format msgid "(use \"help\" to list choices)\n" -msgstr "(,,help'' wyświetli listę wyborów)\n" +msgstr "(„help” wyświetli listę wyborów)\n" #, c-format msgid "This command is not allowed while in %s mode.\n" @@ -2398,23 +2398,23 @@ msgstr "Uwaga: %s nie jest do normalnego użytku!\n" #, c-format msgid "'%s' is not a valid signature expiration\n" -msgstr ",,%s'' nie jest poprawnym czasem wygaśnięcia podpisu\n" +msgstr "„%s” nie jest poprawnym czasem wygaśnięcia podpisu\n" #, c-format msgid "\"%s\" is not a proper mail address\n" -msgstr ",,%s'' nie jest niepoprawnym adresem e-mail\n" +msgstr "„%s” nie jest niepoprawnym adresem e-mail\n" #, c-format msgid "invalid pinentry mode '%s'\n" -msgstr "błędny tryb pinentry ,,%s''\n" +msgstr "błędny tryb pinentry „%s”\n" #, c-format msgid "invalid request origin '%s'\n" -msgstr "błędne źródło żądania ,,%s''\n" +msgstr "błędne źródło żądania „%s”\n" #, c-format msgid "'%s' is not a valid character set\n" -msgstr ",,%s'' nie jest poprawną nazwą zestawu znaków\n" +msgstr "„%s” nie jest poprawną nazwą zestawu znaków\n" #, c-format msgid "could not parse keyserver URL\n" @@ -2508,7 +2508,7 @@ msgstr "Niepoprawna lista auto-key-locate\n" #, c-format msgid "invalid argument for option \"%.50s\"\n" -msgstr "błędny argument dla opcji ,,%.50s''\n" +msgstr "błędny argument dla opcji „%.50s”\n" #, c-format msgid "WARNING: program may create a core file!\n" @@ -2603,7 +2603,7 @@ msgstr "%s jeszcze nie działa z %s!\n" #, c-format msgid "compression algorithm '%s' may not be used in %s mode\n" -msgstr "algorytm kompresji ,,%s'' nie może być używany w trybie %s\n" +msgstr "algorytm kompresji „%s” nie może być używany w trybie %s\n" #, c-format msgid "failed to initialize the TrustDB: %s\n" @@ -2615,7 +2615,7 @@ msgstr "OSTRZEŻENIE: podano adresatów (-r) w działaniu które ich nie dotyczy #, c-format msgid "symmetric encryption of '%s' failed: %s\n" -msgstr "szyfrowanie symetryczne ,,%s'' nie powiodło się: %s\n" +msgstr "szyfrowanie symetryczne „%s” nie powiodło się: %s\n" #, c-format msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n" @@ -2667,16 +2667,16 @@ msgstr "opakowywanie ASCII nie powiodło się: %s\n" #, c-format msgid "invalid hash algorithm '%s'\n" -msgstr "niewłaściwy algorytm skrótu ,,%s''\n" +msgstr "niewłaściwy algorytm skrótu „%s”\n" #, c-format msgid "error parsing key specification '%s': %s\n" -msgstr "błąd analizy specyfikacji klucza ,,%s'': %s\n" +msgstr "błąd analizy specyfikacji klucza „%s”: %s\n" #, c-format msgid "'%s' does not appear to be a valid key ID, fingerprint or keygrip\n" msgstr "" -",,%s'' nie wygląda na prawidłowy identyfikator, odcisk ani uchwyt klucza\n" +"„%s” nie wygląda na prawidłowy identyfikator, odcisk ani uchwyt klucza\n" #, c-format msgid "WARNING: no command supplied. Trying to guess what you mean ...\n" @@ -2725,7 +2725,7 @@ msgstr "Pomoc niedostępna" #, c-format msgid "No help available for '%s'" -msgstr "Brak pomocy o ,,%s''" +msgstr "Brak pomocy o „%s”" msgid "import signatures that are marked as local-only" msgstr "import podpisów oznaczonych jako tylko lokalne" @@ -2855,20 +2855,20 @@ msgstr "" #, c-format msgid " \"%s\": preference for cipher algorithm %s\n" -msgstr " ,,%s'': preferowany szyfr %s\n" +msgstr " „%s”: preferowany szyfr %s\n" #, fuzzy, c-format #| msgid " \"%s\": preference for cipher algorithm %s\n" msgid " \"%s\": preference for AEAD algorithm %s\n" -msgstr " ,,%s'': preferowany szyfr %s\n" +msgstr " „%s”: preferowany szyfr %s\n" #, c-format msgid " \"%s\": preference for digest algorithm %s\n" -msgstr " ,,%s'': preferowany algorytm skrótu %s\n" +msgstr " „%s”: preferowany algorytm skrótu %s\n" #, c-format msgid " \"%s\": preference for compression algorithm %s\n" -msgstr " ,,%s'': preferowany algorytm kompresji %s\n" +msgstr " „%s”: preferowany algorytm kompresji %s\n" #, c-format msgid "it is strongly suggested that you update your preferences and\n" @@ -2900,7 +2900,7 @@ msgstr "klucz %s: podklucz uszkodzony przez serwer został naprawiony\n" #, c-format msgid "key %s: accepted non self-signed user ID \"%s\"\n" -msgstr "klucz %s: przyjęto identyfikator nie podpisany nim samym ,,%s''\n" +msgstr "klucz %s: przyjęto identyfikator nie podpisany nim samym „%s”\n" #, c-format msgid "key %s: no valid user IDs\n" @@ -2924,11 +2924,11 @@ msgstr "brak zapisywalnego zbioru kluczy: %s\n" #, c-format msgid "error writing keyring '%s': %s\n" -msgstr "błąd zapisu zbioru kluczy ,,%s'': %s\n" +msgstr "błąd zapisu zbioru kluczy „%s”: %s\n" #, c-format msgid "key %s: public key \"%s\" imported\n" -msgstr "klucz %s: klucz publiczny ,,%s'' wczytano do zbioru\n" +msgstr "klucz %s: klucz publiczny „%s” wczytano do zbioru\n" #, c-format msgid "key %s: doesn't match our copy\n" @@ -2936,47 +2936,47 @@ msgstr "klucz %s: nie zgadza się z lokalną kopią\n" #, c-format msgid "key %s: \"%s\" 1 new user ID\n" -msgstr "klucz %s: ,,%s'' 1 nowy identyfikator użytkownika\n" +msgstr "klucz %s: „%s” 1 nowy identyfikator użytkownika\n" #, c-format msgid "key %s: \"%s\" %d new user IDs\n" -msgstr "klucz %s: ,,%s'' %d nowych identyfikatorów użytkownika\n" +msgstr "klucz %s: „%s” %d nowych identyfikatorów użytkownika\n" #, c-format msgid "key %s: \"%s\" 1 new signature\n" -msgstr "klucz %s: ,,%s'' 1 nowy podpis\n" +msgstr "klucz %s: „%s” 1 nowy podpis\n" #, c-format msgid "key %s: \"%s\" %d new signatures\n" -msgstr "klucz %s: ,,%s'' %d nowych podpisów\n" +msgstr "klucz %s: „%s” %d nowych podpisów\n" #, c-format msgid "key %s: \"%s\" 1 new subkey\n" -msgstr "klucz %s: ,,%s'' 1 nowy podklucz\n" +msgstr "klucz %s: „%s” 1 nowy podklucz\n" #, c-format msgid "key %s: \"%s\" %d new subkeys\n" -msgstr "klucz %s: ,,%s'' %d nowych podkluczy\n" +msgstr "klucz %s: „%s” %d nowych podkluczy\n" #, c-format msgid "key %s: \"%s\" %d signature cleaned\n" -msgstr "klucz %s: ,,%s'' %d podpis wyczyszczony\n" +msgstr "klucz %s: „%s” %d podpis wyczyszczony\n" #, c-format msgid "key %s: \"%s\" %d signatures cleaned\n" -msgstr "klucz %s: ,,%s'' %d podpisów wyczyszczonych\n" +msgstr "klucz %s: „%s” %d podpisów wyczyszczonych\n" #, c-format msgid "key %s: \"%s\" %d user ID cleaned\n" -msgstr "klucz %s: ,,%s'' %d identyfikator użytkownika wyczyszczony\n" +msgstr "klucz %s: „%s” %d identyfikator użytkownika wyczyszczony\n" #, c-format msgid "key %s: \"%s\" %d user IDs cleaned\n" -msgstr "klucz %s: ,,%s'' %d identyfikatorów użytkownika wyczyszczonych\n" +msgstr "klucz %s: „%s” %d identyfikatorów użytkownika wyczyszczonych\n" #, c-format msgid "key %s: \"%s\" not changed\n" -msgstr "klucz %s: ,,%s'' bez zmian\n" +msgstr "klucz %s: „%s” bez zmian\n" #, c-format msgid "key %s: secret key imported\n" @@ -3005,7 +3005,7 @@ msgstr "" #, c-format msgid "To migrate '%s', with each smartcard, run: %s\n" msgstr "" -"Aby zmigrować ,,%s'', dla każdej karty procesorowej należy uruchomić: %s\n" +"Aby zmigrować „%s”, dla każdej karty procesorowej należy uruchomić: %s\n" #, c-format msgid "secret key %s: %s\n" @@ -3062,7 +3062,7 @@ msgstr "klucz %s: niepoprawny certyfikat unieważnienia: %s - odrzucony\n" #, c-format msgid "key %s: \"%s\" revocation certificate imported\n" -msgstr "klucz %s: ,,%s'' certyfikat unieważnienia został już wczytany\n" +msgstr "klucz %s: „%s” certyfikat unieważnienia został już wczytany\n" #, c-format msgid "key %s: no user ID for signature\n" @@ -3070,11 +3070,11 @@ msgstr "klucz %s: brak identyfikatora użytkownika do podpisu\n" #, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" -msgstr "klucz %s: algorytm asymetryczny dla id ,,%s'' nie jest obsługiwany\n" +msgstr "klucz %s: algorytm asymetryczny dla id „%s” nie jest obsługiwany\n" #, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" -msgstr "klucz %s: niepoprawny podpis na identyfikatorze ,,%s''\n" +msgstr "klucz %s: niepoprawny podpis na identyfikatorze „%s”\n" #, c-format msgid "key %s: unsupported public key algorithm\n" @@ -3110,7 +3110,7 @@ msgstr "klucz %s: usunięto wielokrotne unieważnienie podklucza\n" #, c-format msgid "key %s: skipped user ID \"%s\"\n" -msgstr "klucz %s: pominięto identyfikator użytkownika ,,%s''\n" +msgstr "klucz %s: pominięto identyfikator użytkownika „%s”\n" #, c-format msgid "key %s: skipped subkey\n" @@ -3161,7 +3161,7 @@ msgstr "" #, c-format msgid "key %s: \"%s\" revocation certificate added\n" -msgstr "klucz %s: ,,%s'' dodany certyfikat unieważnienia\n" +msgstr "klucz %s: „%s” dodany certyfikat unieważnienia\n" #, c-format msgid "key %s: direct key signature added\n" @@ -3228,23 +3228,23 @@ msgstr "" #, c-format msgid "error creating keybox '%s': %s\n" -msgstr "błąd tworzenia keyboksa ,,%s'': %s\n" +msgstr "błąd tworzenia keyboksa „%s”: %s\n" #, c-format msgid "error creating keyring '%s': %s\n" -msgstr "błąd tworzenia zbioru kluczy ,,%s'': %s\n" +msgstr "błąd tworzenia zbioru kluczy „%s”: %s\n" #, c-format msgid "keybox '%s' created\n" -msgstr "keybox ,,%s'' utworzony\n" +msgstr "keybox „%s” utworzony\n" #, c-format msgid "keyring '%s' created\n" -msgstr "zbiór kluczy ,,%s'' został utworzony\n" +msgstr "zbiór kluczy „%s” został utworzony\n" #, c-format msgid "keyblock resource '%s': %s\n" -msgstr "zasób bloku klucza ,,%s'': %s\n" +msgstr "zasób bloku klucza „%s”: %s\n" #, c-format msgid "failed to rebuild keyring cache: %s\n" @@ -3289,12 +3289,12 @@ msgstr "Proszę wpisać domenę ograniczającą ten podpis lub Enter dla żadnej #, c-format msgid "Skipping user ID \"%s\", which is not a text ID.\n" msgstr "" -"Pominięto identyfikator użytkownika ,,%s'' nie będący identyfikatorem " +"Pominięto identyfikator użytkownika „%s” nie będący identyfikatorem " "tekstowym.\n" #, c-format msgid "User ID \"%s\" is revoked." -msgstr "Identyfikator użytkownika ,,%s'' został unieważniony." +msgstr "Identyfikator użytkownika „%s” został unieważniony." msgid "Are you sure you still want to sign it? (y/N) " msgstr "Czy na pewno chcesz podpisać? (t/N) " @@ -3304,15 +3304,15 @@ msgstr " Nie da się złożyć podpisu.\n" #, c-format msgid "User ID \"%s\" is expired." -msgstr "Identyfikator użytkownika ,,%s'' przekroczył swój termin ważności." +msgstr "Identyfikator użytkownika „%s” przekroczył swój termin ważności." #, c-format msgid "User ID \"%s\" is not self-signed." -msgstr "Identyfikator ,,%s'' nie jest podpisany swoim kluczem." +msgstr "Identyfikator „%s” nie jest podpisany swoim kluczem." #, c-format msgid "User ID \"%s\" is signable. " -msgstr "Identyfikator użytkownika ,,%s'' jest podpisywalny. " +msgstr "Identyfikator użytkownika „%s” jest podpisywalny. " msgid "Sign it? (y/N) " msgstr "Podpisać go? (t/N) " @@ -3322,7 +3322,7 @@ msgid "" "The self-signature on \"%s\"\n" "is a PGP 2.x-style signature.\n" msgstr "" -"Podpis klucza nim samym na ,,%s''\n" +"Podpis klucza nim samym na „%s”\n" "jest podpisem złożonym przez PGP 2.x.\n" msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) " @@ -3333,7 +3333,7 @@ msgid "" "Your current signature on \"%s\"\n" "has expired.\n" msgstr "" -"Twój podpis na ,,%s''\n" +"Twój podpis na „%s”\n" "przekroczył datę ważności.\n" msgid "Do you want to issue a new signature to replace the expired one? (y/N) " @@ -3344,7 +3344,7 @@ msgid "" "Your current signature on \"%s\"\n" "is a local signature.\n" msgstr "" -"Twój podpis na ,,%s''\n" +"Twój podpis na „%s”\n" "jest podpisem prywatnym (lokalnym).\n" msgid "Do you want to promote it to a full exportable signature? (y/N) " @@ -3353,11 +3353,11 @@ msgstr "" #, c-format msgid "\"%s\" was already locally signed by key %s\n" -msgstr ",,%s'' jest już lokalnie podpisany kluczem %s\n" +msgstr "„%s” jest już lokalnie podpisany kluczem %s\n" #, c-format msgid "\"%s\" was already signed by key %s\n" -msgstr ",,%s'' jest już podpisany kluczem %s\n" +msgstr "„%s” jest już podpisany kluczem %s\n" msgid "Do you want to sign it again anyway? (y/N) " msgstr "Czy na pewno chcesz to podpisać jeszcze raz? (t/N) " @@ -3383,7 +3383,7 @@ msgid "" "to the person named above? If you don't know what to answer, enter \"0\".\n" msgstr "" "Jak dokładnie została przez Ciebie sprawdzona tożsamość tej osoby?\n" -"Jeśli nie wiesz co odpowiedzieć, podaj ,,0''.\n" +"Jeśli nie wiesz co odpowiedzieć, podaj „0”.\n" #, c-format msgid " (0) I will not answer.%s\n" @@ -3402,7 +3402,7 @@ msgid " (3) I have done very careful checking.%s\n" msgstr " (3) Bardzo dokładnie.%s\n" msgid "Your selection? (enter '?' for more information): " -msgstr "Wybór (,,?'' podaje więcej informacji): " +msgstr "Wybór („?” podaje więcej informacji): " #, c-format msgid "" @@ -3410,7 +3410,7 @@ msgid "" "key \"%s\" (%s)\n" msgstr "" "Czy jesteś naprawdę pewien, że chcesz podpisać ten klucz\n" -"swoim kluczem ,,%s'' (%s)\n" +"swoim kluczem „%s” (%s)\n" msgid "This will be a self-signature.\n" msgstr "To będzie podpis klucza nim samym.\n" @@ -3610,8 +3610,8 @@ msgid "" " a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures\n" " (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n" msgstr "" -"* Polecenie ,,sign'' można poprzedzić ,,l'' dla lokalnych sygnatur (lsign),\n" -" ,,t'' dla sygnatur zaufania (tsign) albo ,,nr'' dla sygnatur nie\n" +"* Polecenie „sign” można poprzedzić „l” dla lokalnych sygnatur (lsign),\n" +" „t” dla sygnatur zaufania (tsign) albo „nr” dla sygnatur nie\n" " podlegających unieważnieniu (nrsign), albo dowolną ich kombinacją " "(ltsign,\n" " tnrsign itd.).\n" @@ -3631,14 +3631,14 @@ msgstr "Podpowiedź: wybierz identyfikatory użytkownika do podpisania.\n" #, c-format msgid "Unknown signature type '%s'\n" -msgstr "Nieznany rodzaj podpisu ,,%s''\n" +msgstr "Nieznany rodzaj podpisu „%s”\n" msgid "You must select at least one user ID.\n" msgstr "Musisz wybrać co najmniej jeden identyfikator użytkownika.\n" #, c-format msgid "(Use the '%s' command.)\n" -msgstr "(Należy użyć polecenia ,,%s''.)\n" +msgstr "(Należy użyć polecenia „%s”.)\n" msgid "You can't delete the last user ID!\n" msgstr "Nie możesz usunąć ostatniego identyfikatora użytkownika!\n" @@ -3663,11 +3663,11 @@ msgstr "Polecenie oczekuje argumentu będącego nazwą pliku\n" #, c-format msgid "Can't open '%s': %s\n" -msgstr "Nie można otworzyć ,,%s'': %s\n" +msgstr "Nie można otworzyć „%s”: %s\n" #, c-format msgid "Error reading backup key from '%s': %s\n" -msgstr "Błąd podczas odczytu klucza zapasowego z ,,%s'': %s\n" +msgstr "Błąd podczas odczytu klucza zapasowego z „%s”: %s\n" msgid "You must select at least one key.\n" msgstr "Musisz wybrać co najmniej jeden klucz.\n" @@ -3738,15 +3738,15 @@ msgstr "ustawienie głównego identyfikatora użytkownika nie powiodło się: %s #, c-format msgid "\"%s\" is not a fingerprint\n" -msgstr ",,%s'' nie jest odciskiem\n" +msgstr "„%s” nie jest odciskiem\n" #, c-format msgid "\"%s\" is not the primary fingerprint\n" -msgstr ",,%s'' nie jest głównym odciskiem\n" +msgstr "„%s” nie jest głównym odciskiem\n" #, c-format msgid "Invalid user ID '%s': %s\n" -msgstr "Błędny identyfikator użytkownika ,,%s'': %s\n" +msgstr "Błędny identyfikator użytkownika „%s”: %s\n" msgid "No matching user IDs." msgstr "Brak pasującego identyfikatora użytkownika." @@ -3764,15 +3764,15 @@ msgstr "unieważnienie podpisu klucza nie powiodło się: %s\n" #, c-format msgid "'%s' is not a valid expiration time\n" -msgstr ",,%s'' nie jest poprawnym czasem wygaśnięcia\n" +msgstr "„%s” nie jest poprawnym czasem wygaśnięcia\n" #, c-format msgid "\"%s\" is not a proper fingerprint\n" -msgstr ",,%s'' nie jest właściwym odciskiem\n" +msgstr "„%s” nie jest właściwym odciskiem\n" #, c-format msgid "subkey \"%s\" not found\n" -msgstr "podklucz ,,%s'' nie został odnaleziony\n" +msgstr "podklucz „%s” nie został odnaleziony\n" msgid "Preferred keyserver: " msgstr "Preferowany serwer kluczy: " @@ -3909,22 +3909,22 @@ msgstr "niepoprawny" #, c-format msgid "User ID \"%s\" compacted: %s\n" -msgstr "Identyfikator użytkownika ,,%s'' upakowany: %s\n" +msgstr "Identyfikator użytkownika „%s” upakowany: %s\n" #, c-format msgid "User ID \"%s\": %d signature removed\n" msgid_plural "User ID \"%s\": %d signatures removed\n" -msgstr[0] "Identyfikator użytkownika ,,%s'': %d podpis usunięty\n" -msgstr[1] "Identyfikator użytkownika ,,%s'': %d podpisy usunięte\n" -msgstr[2] "Identyfikator użytkownika ,,%s'': %d podpisów usuniętych\n" +msgstr[0] "Identyfikator użytkownika „%s”: %d podpis usunięty\n" +msgstr[1] "Identyfikator użytkownika „%s”: %d podpisy usunięte\n" +msgstr[2] "Identyfikator użytkownika „%s”: %d podpisów usuniętych\n" #, c-format msgid "User ID \"%s\": already minimized\n" -msgstr "Identyfikator użytkownika ,,%s'': już zmniejszony.\n" +msgstr "Identyfikator użytkownika „%s”: już zmniejszony.\n" #, c-format msgid "User ID \"%s\": already clean\n" -msgstr "Identyfikator użytkownika ,,%s'': już czysty.\n" +msgstr "Identyfikator użytkownika „%s”: już czysty.\n" msgid "" "WARNING: This is a PGP 2.x-style key. Adding a designated revoker may " @@ -4009,7 +4009,7 @@ msgstr "Proszę wybrać dokładnie jeden identyfikator użytkownika.\n" #, c-format msgid "skipping v3 self-signature on user ID \"%s\"\n" -msgstr "podpis w wersji 3 na identyfikatorze ,,%s'' zostaje pominięty\n" +msgstr "podpis w wersji 3 na identyfikatorze „%s” zostaje pominięty\n" msgid "Enter your preferred keyserver URL: " msgstr "Podaj preferowany URL serwera kluczy: " @@ -4036,7 +4036,7 @@ msgstr "Brak identyfikatora użytkownika o skrócie %s\n" #, c-format msgid "No subkey with key ID '%s'.\n" -msgstr "Brak podklucza o identyfikatorze ,,%s''.\n" +msgstr "Brak podklucza o identyfikatorze „%s”.\n" #, c-format msgid "No subkey with index %d\n" @@ -4044,7 +4044,7 @@ msgstr "Brak podklucza o numerze %d.\n" #, c-format msgid "user ID: \"%s\"\n" -msgstr "identyfikator użytkownika: ,,%s''\n" +msgstr "identyfikator użytkownika: „%s”\n" #, c-format msgid "signed by your key %s on %s%s%s\n" @@ -4091,7 +4091,7 @@ msgstr "" #, c-format msgid "user ID \"%s\" is already revoked\n" -msgstr "identyfikator użytkownika ,,%s'' został już unieważniony\n" +msgstr "identyfikator użytkownika „%s” został już unieważniony\n" #, c-format msgid "WARNING: a user ID signature is dated %d seconds in the future\n" @@ -4120,11 +4120,11 @@ msgstr "" #, c-format msgid "invalid value for option '%s'\n" -msgstr "błędna wartość dla opcji ,,%s''\n" +msgstr "błędna wartość dla opcji „%s”\n" #, c-format msgid "preference '%s' duplicated\n" -msgstr "ustawienie ,,%s'' powtarza się\n" +msgstr "ustawienie „%s” powtarza się\n" #, c-format msgid "too many cipher preferences\n" @@ -4145,7 +4145,7 @@ msgstr "zbyt wiele ustawień szyfru\n" #, c-format msgid "invalid item '%s' in preference string\n" -msgstr "niewłaściwy element ,,%s'' w tekście ustawień\n" +msgstr "niewłaściwy element „%s” w tekście ustawień\n" #, c-format msgid "writing direct signature\n" @@ -4435,7 +4435,7 @@ msgstr "Niewłaściwy znak w imieniu lub nazwisku\n" #, c-format msgid "The characters '%s' and '%s' may not appear in name\n" -msgstr "Znaki ,,%s'' i ,,%s'' nie mogą występować w inieniu ani nazwisku\n" +msgstr "Znaki „%s” i „%s” nie mogą występować w inieniu ani nazwisku\n" msgid "Email address: " msgstr "Adres poczty elektronicznej: " @@ -4451,7 +4451,7 @@ msgstr "Niewłaściwy znak w komentarzu\n" #, c-format msgid "You are using the '%s' character set.\n" -msgstr "Używany zestaw znaków: ,,%s''.\n" +msgstr "Używany zestaw znaków: „%s”.\n" #, c-format msgid "" @@ -4534,7 +4534,7 @@ msgid "" "\n" msgstr "" "Będzie tworzony klucz dla:\n" -" ,,%s''\n" +" „%s”\n" "\n" msgid "Continue? (Y/n) " @@ -4542,7 +4542,7 @@ msgstr "Kontynuować? (T/n) " #, c-format msgid "A key for \"%s\" already exists\n" -msgstr "klucz dla ,,%s'' już istnieje\n" +msgstr "klucz dla „%s” już istnieje\n" msgid "Create anyway? (y/N) " msgstr "Utworzyć klucz mimo to? (t/N) " @@ -4554,8 +4554,8 @@ msgstr "tworzenie mimo to\n" #, c-format msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n" msgstr "" -"Uwaga: pełną funkcjonalność generowania klucza można uzyskać przez ,,%s " -"%s''.\n" +"Uwaga: pełną funkcjonalność generowania klucza można uzyskać przez „%s " +"%s”.\n" #, c-format msgid "Key generation canceled.\n" @@ -4563,15 +4563,15 @@ msgstr "Procedura generacji klucza została anulowana.\n" #, c-format msgid "can't create backup file '%s': %s\n" -msgstr "nie można utworzyć pliku kopii zapasowej ,,%s'': %s\n" +msgstr "nie można utworzyć pliku kopii zapasowej „%s”: %s\n" #, c-format msgid "Note: backup of card key saved to '%s'\n" -msgstr "Uwaga: kopia zapasowa klucza karty zapisana do ,,%s''\n" +msgstr "Uwaga: kopia zapasowa klucza karty zapisana do „%s”\n" #, c-format msgid "writing public key to '%s'\n" -msgstr "zapis klucza publicznego w ,,%s''\n" +msgstr "zapis klucza publicznego w „%s”\n" #, c-format msgid "no writable public keyring found: %s\n" @@ -4579,7 +4579,7 @@ msgstr "brak zapisywalnego zbioru kluczy publicznych: %s\n" #, c-format msgid "error writing public keyring '%s': %s\n" -msgstr "błąd podczas zapisu zbioru kluczy publicznych ,,%s'': %s\n" +msgstr "błąd podczas zapisu zbioru kluczy publicznych „%s”: %s\n" msgid "public and secret key created and signed.\n" msgstr "klucz publiczny i prywatny (tajny) zostały utworzone i podpisane.\n" @@ -4697,7 +4697,7 @@ msgstr " Nr seryjny karty =" #, c-format msgid "caching keyring '%s'\n" -msgstr "buforowanie zbioru kluczy ,,%s''\n" +msgstr "buforowanie zbioru kluczy „%s”\n" #, c-format msgid "%lu keys cached so far (%lu signature)\n" @@ -4754,7 +4754,7 @@ msgstr "niepoprawny protokół serwera kluczy (nasz %d != moduł obsługi %d)\n" #, c-format msgid "\"%s\" not a key ID: skipping\n" -msgstr ",,%s'' nie jest identyfikatorem klucza - pominięto\n" +msgstr "„%s” nie jest identyfikatorem klucza - pominięto\n" #, c-format msgid "refreshing %d key from %s\n" @@ -4769,7 +4769,7 @@ msgstr "OSTRZEŻENIE: nie można odświeżyć klucza %s przez %s: %s\n" #, c-format msgid "key \"%s\" not found on keyserver\n" -msgstr "klucz ,,%s'' nie został odnaleziony na serwerze kluczy\n" +msgstr "klucz „%s” nie został odnaleziony na serwerze kluczy\n" #, c-format msgid "key not found on keyserver\n" @@ -4785,7 +4785,7 @@ msgstr "brak znanego serwera kluczy\n" #, c-format msgid "skipped \"%s\": %s\n" -msgstr "pominięty ,,%s'': %s\n" +msgstr "pominięty „%s”: %s\n" #, c-format msgid "sending key %s to %s\n" @@ -4793,7 +4793,7 @@ msgstr "wysyłanie klucza %s na %s\n" #, c-format msgid "requesting key from '%s'\n" -msgstr "zapytanie o klucz z ,,%s''\n" +msgstr "zapytanie o klucz z „%s”\n" #, c-format msgid "WARNING: unable to fetch URI %s: %s\n" @@ -4834,7 +4834,7 @@ msgstr "" #, c-format msgid " \"%s\"\n" -msgstr " ,,%s''\n" +msgstr " „%s”\n" #, c-format msgid "encrypted with %s key, ID %s\n" @@ -4883,7 +4883,7 @@ msgstr "" #, c-format msgid "Use the option '%s' to decrypt anyway.\n" -msgstr "Użycie mimo to opcji ,,%s'' do odszyfrowania.\n" +msgstr "Użycie mimo to opcji „%s” do odszyfrowania.\n" #, c-format msgid "decryption forced to fail!\n" @@ -4916,7 +4916,7 @@ msgstr "pierwotna nazwa pliku='%.*s'\n" #, c-format msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" -"osobny certyfikat unieważnienia - użyj ,,gpg --import'' aby go wczytać\n" +"osobny certyfikat unieważnienia - użyj „gpg --import” aby go wczytać\n" #, c-format msgid "no signature found\n" @@ -4924,15 +4924,15 @@ msgstr "nie znaleziono podpisu\n" #, c-format msgid "BAD signature from \"%s\"" -msgstr "NIEPOPRAWNY podpis złożony przez ,,%s''" +msgstr "NIEPOPRAWNY podpis złożony przez „%s”" #, c-format msgid "Expired signature from \"%s\"" -msgstr "Przeterminowany podpis złożony przez ,,%s''" +msgstr "Przeterminowany podpis złożony przez „%s”" #, c-format msgid "Good signature from \"%s\"" -msgstr "Poprawny podpis złożony przez ,,%s''" +msgstr "Poprawny podpis złożony przez „%s”" #, c-format msgid "signature verification suppressed\n" @@ -4956,7 +4956,7 @@ msgstr "Podpisano w %s kluczem %s o numerze %s\n" #, c-format msgid " issuer \"%s\"\n" -msgstr " wystawca ,,%s''\n" +msgstr " wystawca „%s”\n" #, c-format msgid "Key available at: " @@ -4964,14 +4964,14 @@ msgstr "Klucz dostępny w: " #, c-format msgid "Note: Use '%s' to make use of this info\n" -msgstr "Uwaga: aby wykorzystać tę informację, należy użyć ,,%s''\n" +msgstr "Uwaga: aby wykorzystać tę informację, należy użyć „%s”\n" msgid "[uncertain]" msgstr "[niepewne]" #, c-format msgid " aka \"%s\"" -msgstr " alias ,,%s''" +msgstr " alias „%s”" #, c-format msgid "WARNING: This key is not suitable for signing in %s mode\n" @@ -5004,7 +5004,7 @@ msgstr ", algorytm klucza " #, c-format msgid "WARNING: not a detached signature; file '%s' was NOT verified!\n" msgstr "" -"OSTRZEŻENIE: to nie jest oddzielony podpis; plik ,,%s'' NIE został " +"OSTRZEŻENIE: to nie jest oddzielony podpis; plik „%s” NIE został " "zweryfikowany!\n" #, c-format @@ -5031,7 +5031,7 @@ msgstr "podpis starego typu (PGP 2.x).\n" #, c-format msgid "fstat of '%s' failed in %s: %s\n" -msgstr "fstat na ,,%s'' nie powiodło się w %s: %s\n" +msgstr "fstat na „%s” nie powiodło się w %s: %s\n" #, c-format msgid "fstat(%d) failed in %s: %s\n" @@ -5083,27 +5083,27 @@ msgstr "(dalsze informacje: " #, c-format msgid "%s:%d: deprecated option \"%s\"\n" -msgstr "%s:%d: przestarzała opcja ,,%s''\n" +msgstr "%s:%d: przestarzała opcja „%s”\n" #, c-format msgid "please use \"%s%s\" instead\n" -msgstr "w jej miejsce należy użyć ,,%s%s''\n" +msgstr "w jej miejsce należy użyć „%s%s”\n" #, c-format msgid "WARNING: \"%s\" is a deprecated command - do not use it\n" msgstr "" -"OSTRZEŻENIE: ,,%s'' jest przestarzałym poleceniem - nie należy go używać\n" +"OSTRZEŻENIE: „%s” jest przestarzałym poleceniem - nie należy go używać\n" #, c-format msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n" msgstr "" -"%s:%u: ,,%s'' jest przestarzałe w tym pliku - ma znaczenie tylko w %s\n" +"%s:%u: „%s” jest przestarzałe w tym pliku - ma znaczenie tylko w %s\n" #, c-format msgid "" "WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n" msgstr "" -"OSTRZEŻENIE: ,,%s%s'' jest przestarzałą opcją - nie ma efektu z wyjątkiem " +"OSTRZEŻENIE: „%s%s” jest przestarzałą opcją - nie ma efektu z wyjątkiem " "%s\n" msgid "Uncompressed" @@ -5119,11 +5119,11 @@ msgstr "ta wiadomość może nie dać się odczytać za pomocą %s\n" #, c-format msgid "ambiguous option '%s'\n" -msgstr "niejednoznaczna opcja ,,%s''\n" +msgstr "niejednoznaczna opcja „%s”\n" #, c-format msgid "unknown option '%s'\n" -msgstr "nieznana opcja ,,%s''\n" +msgstr "nieznana opcja „%s”\n" #, c-format msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n" @@ -5132,11 +5132,11 @@ msgstr "" #, c-format msgid "unknown weak digest '%s'\n" -msgstr "nieznany słaby skrót ,,%s''\n" +msgstr "nieznany słaby skrót „%s”\n" #, c-format msgid "File '%s' exists. " -msgstr "Plik ,,%s'' istnieje. " +msgstr "Plik „%s” istnieje. " msgid "Overwrite? (y/N) " msgstr "Nadpisać? (t/N) " @@ -5223,7 +5223,7 @@ msgid "" "%s" msgstr "" "%s\n" -",,%.*s''\n" +"„%.*s”\n" "klucz %u-bitowy %s, ID %s,\n" "utworzony %s%s.\n" "%s" @@ -5246,7 +5246,7 @@ msgstr "Nazwa pliku ze zdjęciem w formacie JPEG: " #, c-format msgid "unable to open JPEG file '%s': %s\n" -msgstr "nie można otworzyć pliku JPEG ,,%s'': %s\n" +msgstr "nie można otworzyć pliku JPEG „%s”: %s\n" #, c-format msgid "This JPEG is really large (%d bytes) !\n" @@ -5257,7 +5257,7 @@ msgstr "Czy na pewno chcesz go użyć? (t/N) " #, c-format msgid "'%s' is not a JPEG file\n" -msgstr ",,%s'' nie jest plikiem JPEG\n" +msgstr "„%s” nie jest plikiem JPEG\n" msgid "Is this photo correct (y/N/q)? " msgstr "Czy zdjęcie jest w porządku? (t/N/w) " @@ -5274,7 +5274,7 @@ msgstr "" #, c-format msgid "unable to execute shell '%s': %s\n" -msgstr "nie można uruchomić powłoki ,,%s'': %s\n" +msgstr "nie można uruchomić powłoki „%s”: %s\n" #, c-format msgid "unnatural exit of external program\n" @@ -5286,11 +5286,11 @@ msgstr "błąd systemu podczas wołania programu zewnętrznego: %s\n" #, c-format msgid "WARNING: unable to remove tempfile (%s) '%s': %s\n" -msgstr "OSTRZEŻENIE: nie można skasować pliku tymczasowego (%s) ,,%s'': %s\n" +msgstr "OSTRZEŻENIE: nie można skasować pliku tymczasowego (%s) „%s”: %s\n" #, c-format msgid "WARNING: unable to remove temp directory '%s': %s\n" -msgstr "OSTRZEŻENIE: nie można skasować tymczasowego katalogu ,,%s'': %s\n" +msgstr "OSTRZEŻENIE: nie można skasować tymczasowego katalogu „%s”: %s\n" #, c-format msgid "" @@ -5320,7 +5320,7 @@ msgstr "Brak wartości zaufania dla:\n" #, c-format msgid " aka \"%s\"\n" -msgstr " alias ,,%s''\n" +msgstr " alias „%s”\n" msgid "" "How much do you trust that this key actually belongs to the named user?\n" @@ -5390,7 +5390,7 @@ msgid "" "question with yes.\n" msgstr "" "Ten klucz jest niedobry! Został oznaczony jako niezaufany!\n" -"Jeżeli *naprawdę* wiesz, co robisz, możesz odpowiedzieć ,,tak'' na\n" +"Jeżeli *naprawdę* wiesz, co robisz, możesz odpowiedzieć „tak” na\n" "następne pytanie.\n" msgid "" @@ -5400,7 +5400,7 @@ msgid "" msgstr "" "NIE MA pewności, czy klucz należy do osoby wymienionej w identyfikatorze.\n" "Jeśli nie masz co do tego żadnych wątpliwości i *naprawdę* wiesz co robisz,\n" -"możesz odpowiedzieć ,,tak'' na następne pytanie.\n" +"możesz odpowiedzieć „tak” na następne pytanie.\n" msgid "Use this key anyway? (y/N) " msgstr "Użyć tego klucza pomimo to? (t/N) " @@ -5418,12 +5418,12 @@ msgstr "" #, fuzzy, c-format #| msgid "user ID: \"%s\"\n" msgid "checking User ID \"%s\"\n" -msgstr "identyfikator użytkownika: ,,%s''\n" +msgstr "identyfikator użytkownika: „%s”\n" #, fuzzy, c-format #| msgid "option '%s' given, but option '%s' not given\n" msgid "option %s given but issuer \"%s\" does not match\n" -msgstr "podano opcję ,,%s'', ale nie podano opcji ,,%s''\n" +msgstr "podano opcję „%s”, ale nie podano opcji „%s”\n" #, fuzzy, c-format #| msgid "key %s: doesn't match our copy\n" @@ -5433,7 +5433,7 @@ msgstr "klucz %s: nie zgadza się z lokalną kopią\n" #, fuzzy, c-format #| msgid "option '%s' given, but option '%s' not given\n" msgid "option %s given but no matching User ID found\n" -msgstr "podano opcję ,,%s'', ale nie podano opcji ,,%s''\n" +msgstr "podano opcję „%s”, ale nie podano opcji „%s”\n" #, c-format msgid "WARNING: This key has been revoked by its designated revoker!\n" @@ -5517,18 +5517,18 @@ msgstr "%s: pominięty: został już wybrany w innej opcji\n" #, c-format msgid "can't encrypt to '%s'\n" -msgstr "nie można zaszyfrować do ,,%s''\n" +msgstr "nie można zaszyfrować do „%s”\n" #, c-format msgid "option '%s' given, but no valid default keys given\n" -msgstr "podano opcję ,,%s'', ale nie podano poprawnych kluczy domyślnych\n" +msgstr "podano opcję „%s”, ale nie podano poprawnych kluczy domyślnych\n" #, c-format msgid "option '%s' given, but option '%s' not given\n" -msgstr "podano opcję ,,%s'', ale nie podano opcji ,,%s''\n" +msgstr "podano opcję „%s”, ale nie podano opcji „%s”\n" msgid "You did not specify a user ID. (you may use \"-r\")\n" -msgstr "Nie został podany identyfikator użytkownika (np. za pomocą ,,-r'')\n" +msgstr "Nie został podany identyfikator użytkownika (np. za pomocą „-r”)\n" msgid "Current recipients:\n" msgstr "Aktualni odbiorcy:\n" @@ -5556,7 +5556,7 @@ msgstr "pominięty: został już wybrany w innej opcji\n" #, c-format msgid "unknown default recipient \"%s\"\n" -msgstr "nieznany domyślny adresat ,,%s''\n" +msgstr "nieznany domyślny adresat „%s”\n" #, c-format msgid "no valid addressees\n" @@ -5591,7 +5591,7 @@ msgstr "brak podpisanych danych\n" #, c-format msgid "can't open signed data '%s'\n" -msgstr "nie można otworzyć podpisanego pliku ,,%s''\n" +msgstr "nie można otworzyć podpisanego pliku „%s”\n" #, c-format msgid "can't open signed data fd=%d: %s\n" @@ -5666,7 +5666,7 @@ msgstr "Certyfikat unieważnienia został utworzony.\n" #, c-format msgid "no revocation keys found for \"%s\"\n" -msgstr "brak kluczy unieważniających dla ,,%s''\n" +msgstr "brak kluczy unieważniających dla „%s”\n" msgid "This is a revocation certificate for the OpenPGP key:" msgstr "To certyfikat unieważnienia dla klucza OpenPGP:" @@ -5676,7 +5676,7 @@ msgid "" "declare that a key shall not anymore be used. It is not possible\n" "to retract such a revocation certificate once it has been published." msgstr "" -"Certyfikat unieważnienia to rodzaj ,,wyłącznika awaryjnego,, do\n" +"Certyfikat unieważnienia to rodzaj „wyłącznika awaryjnego” do\n" "publicznego zadeklarowania, że klucz nie powinien być już więcej\n" "używany. Po opublikowaniu takiego certyfikatu nie jest już możliwe\n" "wycofanie go." @@ -5692,7 +5692,7 @@ msgstr "" "klucza tajnego. Co więcej, jeśli klucz tajny jest nadal dostępny,\n" "lepiej wygenerować nowy certyfikat unieważnienia i podać powód\n" "unieważnienia. Więcej szczegółów w opisie polecenia gpg\n" -",,--generate-revocation'' w podręczniku do GnuPG." +"„--generate-revocation” w podręczniku do GnuPG." msgid "" "To avoid an accidental use of this file, a colon has been inserted\n" @@ -5706,18 +5706,18 @@ msgstr "" #, c-format msgid "revocation certificate stored as '%s.rev'\n" -msgstr "certyfikat unieważnienia został zapisany jako ,,%s.rev''\n" +msgstr "certyfikat unieważnienia został zapisany jako „%s.rev”\n" #, c-format msgid "secret key \"%s\" not found\n" -msgstr "klucz prywatny ,,%s'' nie został odnaleziony\n" +msgstr "klucz prywatny „%s” nie został odnaleziony\n" #. TRANSLATORS: The %s prints a key specification which #. for example has been given at the command line. Several lines #. lines with secret key infos are printed after this message. #, c-format msgid "'%s' matches multiple secret keys:\n" -msgstr ",,%s'' pasuje do wielu kluczy tajnych:\n" +msgstr "„%s” pasuje do wielu kluczy tajnych:\n" #, c-format msgid "error searching the keyring: %s\n" @@ -5907,7 +5907,7 @@ msgstr "" #, c-format msgid "%s/%s signature from: \"%s\"\n" -msgstr "podpis %s/%s złożony przez: ,,%s''\n" +msgstr "podpis %s/%s złożony przez: „%s”\n" #, c-format msgid "" @@ -5933,7 +5933,7 @@ msgstr "" #, c-format msgid "skipped \"%s\": duplicated\n" -msgstr "pominięty ,,%s'': duplikat\n" +msgstr "pominięty „%s”: duplikat\n" #, c-format msgid "skipped: secret key already present\n" @@ -5958,7 +5958,7 @@ msgstr "" #, c-format msgid "error in '%s': %s\n" -msgstr "błąd w ,,%s'': %s\n" +msgstr "błąd w „%s”: %s\n" msgid "line too long" msgstr "linia zbyt długa" @@ -5974,11 +5974,11 @@ msgstr "brak wartości zaufania właściciela" #, c-format msgid "error finding trust record in '%s': %s\n" -msgstr "błąd podczas szukania zapisu wartości zaufania w ,,%s'': %s\n" +msgstr "błąd podczas szukania zapisu wartości zaufania w „%s”: %s\n" #, c-format msgid "read error in '%s': %s\n" -msgstr "błąd odczytu w ,,%s'': %s\n" +msgstr "błąd odczytu w „%s”: %s\n" #, c-format msgid "trustdb: sync failed: %s\n" @@ -5986,11 +5986,11 @@ msgstr "baza zaufania: synchronizacja nie powiodła się %s\n" #, c-format msgid "can't create lock for '%s'\n" -msgstr "nie można utworzyć blokady dla ,,%s''\n" +msgstr "nie można utworzyć blokady dla „%s”\n" #, c-format msgid "can't lock '%s'\n" -msgstr "nie można zablokować ,,%s''\n" +msgstr "nie można zablokować „%s”\n" #, c-format msgid "trustdb rec %lu: lseek failed: %s\n" @@ -6010,7 +6010,7 @@ msgstr "%s: katalog nie istnieje!\n" #, c-format msgid "can't access '%s': %s\n" -msgstr "nie można dostać się do ,,%s'': %s\n" +msgstr "nie można dostać się do „%s”: %s\n" #, c-format msgid "%s: failed to create version record: %s" @@ -6130,7 +6130,7 @@ msgstr "błąd inicjowania bazy danych TOFU: %s\n" #, c-format msgid "error opening TOFU database '%s': %s\n" -msgstr "błąd otwierania bazy danych TOFU ,,%s'': %s\n" +msgstr "błąd otwierania bazy danych TOFU „%s”: %s\n" #, c-format msgid "error updating TOFU database: %s\n" @@ -6139,19 +6139,19 @@ msgstr "błąd uaktualniania bazy danych TOFU: %s\n" #, c-format msgid "" "This is the first time the email address \"%s\" is being used with key %s." -msgstr "To pierwsze użycie adresu e-mail ,,%s'' z kluczem %s." +msgstr "To pierwsze użycie adresu e-mail „%s” z kluczem %s." #, c-format msgid "The email address \"%s\" is associated with %d key!" msgid_plural "The email address \"%s\" is associated with %d keys!" -msgstr[0] "Adres e-mail ,,%s'' jest powiązany z %d kluczem!" -msgstr[1] "Adres e-mail ,,%s'' jest powiązany z %d kluczami!" -msgstr[2] "Adres e-mail ,,%s'' jest powiązany z %d kluczami!" +msgstr[0] "Adres e-mail „%s” jest powiązany z %d kluczem!" +msgstr[1] "Adres e-mail „%s” jest powiązany z %d kluczami!" +msgstr[2] "Adres e-mail „%s” jest powiązany z %d kluczami!" msgid " Since this binding's policy was 'auto', it has been changed to 'ask'." msgstr "" -" Ponieważ polityką tego powiązania było ,,auto'', została zmieniona na ,," -"ask''." +" Ponieważ polityką tego powiązania było „auto”, została zmieniona na „" +"ask”." #, c-format msgid "" @@ -6159,7 +6159,7 @@ msgid "" "or whether you think someone is impersonating \"%s\"." msgstr "" "Proszę zdecydować, czy ten adres e-mail powinien być powiązany z kluczem %s, " -"czy raczej ktoś się podszywa za ,,%s''." +"czy raczej ktoś się podszywa za „%s”." #, c-format msgid "error gathering other user IDs: %s\n" @@ -6179,13 +6179,13 @@ msgstr "błąd zbierania statystyk podpisów: %s\n" #, c-format msgid "The email address \"%s\" is associated with %d key:\n" msgid_plural "The email address \"%s\" is associated with %d keys:\n" -msgstr[0] "Adres e-mail ,,%s'' jest powiązany z %d kluczem:\n" -msgstr[1] "Adres e-mail ,,%s'' jest powiązany z %d kluczami:\n" -msgstr[2] "Adres e-mail ,,%s'' jest powiązany z %d kluczami:\n" +msgstr[0] "Adres e-mail „%s” jest powiązany z %d kluczem:\n" +msgstr[1] "Adres e-mail „%s” jest powiązany z %d kluczami:\n" +msgstr[2] "Adres e-mail „%s” jest powiązany z %d kluczami:\n" #, c-format msgid "Statistics for keys with the email address \"%s\":\n" -msgstr "Statystyki dla kluczy o adresie e-mail ,,%s'':\n" +msgstr "Statystyki dla kluczy o adresie e-mail „%s”:\n" msgid "this key" msgstr "ten klucz" @@ -6432,7 +6432,7 @@ msgstr "" #, c-format msgid "'%s' is not a valid long keyID\n" -msgstr ",,%s'' nie jest poprawnym długim identyfikatorem klucza\n" +msgstr "„%s” nie jest poprawnym długim identyfikatorem klucza\n" #, c-format msgid "key %s: accepted as trusted key\n" @@ -6485,11 +6485,11 @@ msgstr "następne sprawdzanie bazy odbędzie się %s\n" #, c-format msgid "no need for a trustdb check with '%s' trust model\n" -msgstr "nie ma potrzeby sprawdzania trustdb przy modelu zaufania ,,%s''\n" +msgstr "nie ma potrzeby sprawdzania trustdb przy modelu zaufania „%s”\n" #, c-format msgid "no need for a trustdb update with '%s' trust model\n" -msgstr "nie ma potrzeby uaktualniania trustdb przy modelu zaufania ,,%s''\n" +msgstr "nie ma potrzeby uaktualniania trustdb przy modelu zaufania „%s”\n" #, c-format msgid "public key %s not found: %s\n" @@ -6497,7 +6497,7 @@ msgstr "klucz publiczny %s nie odnaleziony: %s\n" #, c-format msgid "please do a --check-trustdb\n" -msgstr "należy uruchomić gpg z opcją ,,--check-trustdb''\n" +msgstr "należy uruchomić gpg z opcją „--check-trustdb”\n" #, c-format msgid "checking the trustdb\n" @@ -6614,7 +6614,7 @@ msgstr "OSTRZEŻENIE: wiadomość nie była zabezpieczona przed manipulacją\n" #, fuzzy, c-format #| msgid "ambiguous option '%s'\n" msgid "Hint: Do not use option %s\n" -msgstr "niejednoznaczna opcja ,,%s''\n" +msgstr "niejednoznaczna opcja „%s”\n" msgid "set debugging flags" msgstr "ustawienie flag diagnostycznych" @@ -7001,7 +7001,7 @@ msgstr "" #, c-format msgid "please use the option '--daemon' to run the program in the background\n" -msgstr "proszę użyć opcji ,,--daemon'' do uruchomienia programu w tle\n" +msgstr "proszę użyć opcji „--daemon” do uruchomienia programu w tle\n" #, c-format msgid "handler for fd %d started\n" @@ -7041,7 +7041,7 @@ msgstr "polityka oznaczona jako krytyczna bez skonfigurowanych polityk" #, c-format msgid "failed to open '%s': %s\n" -msgstr "nie udało się otworzyć ,,%s'': %s\n" +msgstr "nie udało się otworzyć „%s”: %s\n" #, c-format msgid "Note: non-critical certificate policy not allowed" @@ -7092,7 +7092,7 @@ msgstr "status certyfikatu jest nieznany" #, c-format msgid "please make sure that the \"dirmngr\" is properly installed\n" -msgstr "proszę upewnić się, że ,,dirmngr'' jest poprawnie zainstalowany\n" +msgstr "proszę upewnić się, że „dirmngr” jest poprawnie zainstalowany\n" #, c-format msgid "checking the CRL failed: %s" @@ -7262,7 +7262,7 @@ msgid "" "created %s, expires %s.\n" msgstr "" "Proszę wprowadzić hasło aby odbezpieczyć klucz tajny certyfikatu X.509:\n" -",,%s''\n" +"„%s”\n" "S/N %s, ID 0x%08lX,\n" "stworzony %s, wygasa %s.\n" @@ -7313,11 +7313,11 @@ msgstr "linia %d: nie podano nazwy przedmiotu\n" #, c-format msgid "line %d: invalid subject name label '%.*s'\n" -msgstr "linia %d: niewłaściwa etykieta nazwy przedmiotu ,,%.*s''\n" +msgstr "linia %d: niewłaściwa etykieta nazwy przedmiotu „%.*s”\n" #, c-format msgid "line %d: invalid subject name '%s' at pos %d\n" -msgstr "linia %d: niewłaściwa nazwa przedmiotu ,,%s'' na pozycji %d\n" +msgstr "linia %d: niewłaściwa nazwa przedmiotu „%s” na pozycji %d\n" #, c-format msgid "line %d: not a valid email address\n" @@ -7329,11 +7329,11 @@ msgstr "linia %d: niewłaściwy numer seryjny\n" #, c-format msgid "line %d: invalid issuer name label '%.*s'\n" -msgstr "linia %d: niewłaściwa etykieta nazwy wystawcy ,,%.*s''\n" +msgstr "linia %d: niewłaściwa etykieta nazwy wystawcy „%.*s”\n" #, c-format msgid "line %d: invalid issuer name '%s' at pos %d\n" -msgstr "linia %d: niewłaściwa nazwa wystawcy ,,%s'' na pozycji %d\n" +msgstr "linia %d: niewłaściwa nazwa wystawcy „%s” na pozycji %d\n" #, c-format msgid "line %d: invalid date given\n" @@ -7341,7 +7341,7 @@ msgstr "linia %d: podano niewłaściwą datę\n" #, c-format msgid "line %d: error getting signing key by keygrip '%s': %s\n" -msgstr "linia %d: błąd pobierania klucza podpisującego z uchwytu ,,%s'': %s\n" +msgstr "linia %d: błąd pobierania klucza podpisującego z uchwytu „%s”: %s\n" #, c-format msgid "line %d: invalid hash algorithm given\n" @@ -7361,11 +7361,11 @@ msgstr "linia %d: niewłaściwa składnia rozszerzenia\n" #, c-format msgid "line %d: error reading key '%s' from card: %s\n" -msgstr "linia %d: błąd odczytu klucza ,,%s'' z karty: %s\n" +msgstr "linia %d: błąd odczytu klucza „%s” z karty: %s\n" #, c-format msgid "line %d: error getting key by keygrip '%s': %s\n" -msgstr "linia %d: błąd pobierania klucza z uchwytu ,,%s'': %s\n" +msgstr "linia %d: błąd pobierania klucza z uchwytu „%s”: %s\n" #, c-format msgid "line %d: key generation failed: %s <%s>\n" @@ -7410,7 +7410,7 @@ msgstr "Nie podano nazwy przedmiotu\n" #, c-format msgid "Invalid subject name label '%.*s'\n" -msgstr "Nieprawidłowa etykieta nazwy przedmiotu ,,%.*s''\n" +msgstr "Nieprawidłowa etykieta nazwy przedmiotu „%.*s”\n" #. TRANSLATORS: The 22 in the second string is the #. length of the first string up to the "%s". Please @@ -7419,7 +7419,7 @@ msgstr "Nieprawidłowa etykieta nazwy przedmiotu ,,%.*s''\n" #. drop everything after the number. #, c-format msgid "Invalid subject name '%s'\n" -msgstr "Nieprawidłowa nazwa przedmiotu ,,%s''\n" +msgstr "Nieprawidłowa nazwa przedmiotu „%s”\n" msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty" msgstr "33" @@ -7484,7 +7484,7 @@ msgstr "zaszyfrowano kluczem %s o identyfikatorze %s\n" #, c-format msgid "certificate '%s' not found: %s\n" -msgstr "nie znaleziono certyfikatu ,,%s'': %s\n" +msgstr "nie znaleziono certyfikatu „%s”: %s\n" #, c-format msgid "error locking keybox: %s\n" @@ -7492,15 +7492,15 @@ msgstr "błąd blokowania keyboksa: %s\n" #, c-format msgid "duplicated certificate '%s' deleted\n" -msgstr "powtórzony certyfikat ,,%s'' usunięty\n" +msgstr "powtórzony certyfikat „%s” usunięty\n" #, c-format msgid "certificate '%s' deleted\n" -msgstr "certyfikat ,,%s'' usunięty\n" +msgstr "certyfikat „%s” usunięty\n" #, c-format msgid "deleting certificate \"%s\" failed: %s\n" -msgstr "usunięcie certyfikatu ,,%s'' nie powiodło się: %s\n" +msgstr "usunięcie certyfikatu „%s” nie powiodło się: %s\n" #, c-format msgid "no valid recipients given\n" @@ -7582,10 +7582,10 @@ msgid "batch mode: never ask" msgstr "tryb wsadowy: bez żadnych pytań" msgid "assume yes on most questions" -msgstr "przyjęcie odpowiedzi ,,tak'' na większość pytań" +msgstr "przyjęcie odpowiedzi „tak” na większość pytań" msgid "assume no on most questions" -msgstr "przyjęcie odpowiedzi ,,nie'' na większość pytań" +msgstr "przyjęcie odpowiedzi „nie” na większość pytań" msgid "|FILE|write an audit log to FILE" msgstr "|PLIK|zapisanie logów audytowych do PLIKU" @@ -7605,19 +7605,19 @@ msgstr "" #, c-format msgid "Note: won't be able to encrypt to '%s': %s\n" -msgstr "Uwaga: nie można zaszyfrować do ,,%s'': %s\n" +msgstr "Uwaga: nie można zaszyfrować do „%s”: %s\n" #, c-format msgid "unknown validation model '%s'\n" -msgstr "nieznany model poprawności ,,%s''\n" +msgstr "nieznany model poprawności „%s”\n" #, c-format msgid "importing common certificates '%s'\n" -msgstr "import wspólnych certyfikatów ,,%s''\n" +msgstr "import wspólnych certyfikatów „%s”\n" #, c-format msgid "can't sign using '%s': %s\n" -msgstr "nie można podpisać z użyciem ,,%s'': %s\n" +msgstr "nie można podpisać z użyciem „%s”: %s\n" #, c-format msgid "invalid command (there is no implicit command)\n" @@ -7687,11 +7687,11 @@ msgstr "" #, c-format msgid "invalid formatted fingerprint in '%s', line %d\n" -msgstr "niewłaściwie sformatowany odcisk w ,,%s'', w linii %d\n" +msgstr "niewłaściwie sformatowany odcisk w „%s”, w linii %d\n" #, c-format msgid "invalid country code in '%s', line %d\n" -msgstr "niewłaściwy kod kraju w ,,%s'', w linii %d\n" +msgstr "niewłaściwy kod kraju w „%s”, w linii %d\n" #, c-format msgid "" @@ -7703,7 +7703,7 @@ msgid "" "%s%sAre you really sure that you want to do this?" msgstr "" "Ta operacja złoży podpis przy użyciu certyfikatu:\n" -",,%s''\n" +"„%s”\n" "Utworzy to kwalifikowany podpis równoważny prawnie podpisowi odręcznemu.\n" "\n" "%s%sNa pewno chcesz to zrobić?" @@ -7723,7 +7723,7 @@ msgid "" "Note, that this certificate will NOT create a qualified signature!" msgstr "" "Ta operacja złoży podpis przy użyciu certyfikatu:\n" -",,%s''\n" +"„%s”\n" "Należy zauważyć, że ten certyfikat NIE utworzy kwalifikowanego podpisu!" #, c-format @@ -7798,19 +7798,19 @@ msgstr "porzucanie %u certyfikatów z pamięci podręcznej\n" #, c-format msgid "can't parse certificate '%s': %s\n" -msgstr "nie można przeanalizować certyfikatu ,,%s'': %s\n" +msgstr "nie można przeanalizować certyfikatu „%s”: %s\n" #, c-format msgid "certificate '%s' already cached\n" -msgstr "certyfikat ,,%s'' jest już w pamięci podręcznej\n" +msgstr "certyfikat „%s” jest już w pamięci podręcznej\n" #, c-format msgid "trusted certificate '%s' loaded\n" -msgstr "certyfikat zaufany ,,%s'' załadowany\n" +msgstr "certyfikat zaufany „%s” załadowany\n" #, c-format msgid "certificate '%s' loaded\n" -msgstr "certyfikat ,,%s'' załadowany\n" +msgstr "certyfikat „%s” załadowany\n" #, c-format msgid " SHA1 fingerprint = %s\n" @@ -7824,7 +7824,7 @@ msgstr " przedmiot =" #, c-format msgid "error loading certificate '%s': %s\n" -msgstr "błąd ładowania certyfikatu ,,%s'': %s\n" +msgstr "błąd ładowania certyfikatu „%s”: %s\n" #, c-format msgid "permanently loaded certificates: %u\n" @@ -7852,7 +7852,7 @@ msgstr "błąd zapisu certyfikatu w pamięci podręcznej: %s\n" #, c-format msgid "invalid SHA1 fingerprint string '%s'\n" -msgstr "niewłaściwy łańcuch odcisku SHA1 ,,%s''\n" +msgstr "niewłaściwy łańcuch odcisku SHA1 „%s”\n" #, c-format msgid "error fetching certificate by S/N: %s\n" @@ -7872,27 +7872,27 @@ msgstr "błąd pobierania authorityKeyIdentifier: %s\n" #, c-format msgid "creating directory '%s'\n" -msgstr "tworzenie katalogu ,,%s''\n" +msgstr "tworzenie katalogu „%s”\n" #, c-format msgid "error creating directory '%s': %s\n" -msgstr "błąd tworzenia katalogu ,,%s'': %s\n" +msgstr "błąd tworzenia katalogu „%s”: %s\n" #, c-format msgid "ignoring database dir '%s'\n" -msgstr "zignorowano katalog bazy danych ,,%s''\n" +msgstr "zignorowano katalog bazy danych „%s”\n" #, c-format msgid "error reading directory '%s': %s\n" -msgstr "błąd odczytu katalogu ,,%s'': %s\n" +msgstr "błąd odczytu katalogu „%s”: %s\n" #, c-format msgid "removing cache file '%s'\n" -msgstr "usuwanie pliku pamięci podręcznej ,,%s''\n" +msgstr "usuwanie pliku pamięci podręcznej „%s”\n" #, c-format msgid "not removing file '%s'\n" -msgstr "bez usuwania pliku ,,%s''\n" +msgstr "bez usuwania pliku „%s”\n" #, c-format msgid "error closing cache file: %s\n" @@ -7900,33 +7900,33 @@ msgstr "błąd zamykania pliku pamięci podręcznej: %s\n" #, c-format msgid "failed to open cache dir file '%s': %s\n" -msgstr "nie udało się otworzyć pliku katalogu pamięci podręcznej ,,%s'': %s\n" +msgstr "nie udało się otworzyć pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "error creating new cache dir file '%s': %s\n" -msgstr "błąd tworzenia nowego pliku katalogu pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd tworzenia nowego pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "error writing new cache dir file '%s': %s\n" msgstr "" -"błąd podczas zapisu nowego pliku katalogu pamięci podręcznej ,,%s'': %s\n" +"błąd podczas zapisu nowego pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "error closing new cache dir file '%s': %s\n" -msgstr "błąd zamykania nowego pliku katalogu pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd zamykania nowego pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "new cache dir file '%s' created\n" -msgstr "nowy plik katalogu pamięci podręcznej ,,%s'' został utworzony\n" +msgstr "nowy plik katalogu pamięci podręcznej „%s” został utworzony\n" #, c-format msgid "failed to re-open cache dir file '%s': %s\n" msgstr "" -"nie udało ponownie otworzyć pliku katalogu pamięci podręcznej ,,%s'': %s\n" +"nie udało ponownie otworzyć pliku katalogu pamięci podręcznej „%s”: %s\n" #, c-format msgid "first record of '%s' is not the version\n" -msgstr "pierwszy rekord ,,%s'' nie jest wersją\n" +msgstr "pierwszy rekord „%s” nie jest wersją\n" #, c-format msgid "old version of cache directory - cleaning up\n" @@ -7938,36 +7938,36 @@ msgstr "stara wersja katalogu pamięci podręcznej - poddaję się\n" #, c-format msgid "extra field detected in crl record of '%s' line %u\n" -msgstr "wykryto nadmiarowe pole w rekordzie CRL ,,%s'', linia %u\n" +msgstr "wykryto nadmiarowe pole w rekordzie CRL „%s”, linia %u\n" #, c-format msgid "invalid line detected in '%s' line %u\n" -msgstr "wykryto niewłaściwą linię w ,,%s'', linia %u\n" +msgstr "wykryto niewłaściwą linię w „%s”, linia %u\n" #, c-format msgid "duplicate entry detected in '%s' line %u\n" -msgstr "wykryto powtórzony wpis w ,,%s'', linia %u\n" +msgstr "wykryto powtórzony wpis w „%s”, linia %u\n" #, c-format msgid "unsupported record type in '%s' line %u skipped\n" -msgstr "pominięto nieobsługiwany typ rekordu w ,,%s'', linia %u\n" +msgstr "pominięto nieobsługiwany typ rekordu w „%s”, linia %u\n" #, c-format msgid "invalid issuer hash in '%s' line %u\n" -msgstr "nieprawidłowy skrót wystawcy w ,,%s'', linia %u\n" +msgstr "nieprawidłowy skrót wystawcy w „%s”, linia %u\n" #, c-format msgid "no issuer DN in '%s' line %u\n" -msgstr "brak DN wystawcy w ,,%s'', linia %u\n" +msgstr "brak DN wystawcy w „%s”, linia %u\n" #, c-format msgid "invalid timestamp in '%s' line %u\n" -msgstr "nieprawidłowy znacznik czasu w ,,%s'', linia %u\n" +msgstr "nieprawidłowy znacznik czasu w „%s”, linia %u\n" #, c-format msgid "WARNING: invalid cache file hash in '%s' line %u\n" msgstr "" -"UWAGA: nieprawidłowy skrót pliku pamięci podręcznej w ,,%s'', linia %u\n" +"UWAGA: nieprawidłowy skrót pliku pamięci podręcznej w „%s”, linia %u\n" #, c-format msgid "detected errors in cache dir file\n" @@ -7980,16 +7980,16 @@ msgstr "proszę sprawdzić przyczynę i ręcznie usunąć ten plik\n" #, c-format msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "" -"nie udało się utworzyć pliku tymczasowego katalogu pamięci podręcznej ,," -"%s'': %s\n" +"nie udało się utworzyć pliku tymczasowego katalogu pamięci podręcznej „" +"%s”: %s\n" #, c-format msgid "error renaming '%s' to '%s': %s\n" -msgstr "błąd zmiany nazwy ,,%s'' na ,,%s'': %s\n" +msgstr "błąd zmiany nazwy „%s” na „%s”: %s\n" #, c-format msgid "can't hash '%s': %s\n" -msgstr "nie można policzyć skrótu ,,%s'': %s\n" +msgstr "nie można policzyć skrótu „%s”: %s\n" #, c-format msgid "error setting up MD5 hash context: %s\n" @@ -7997,11 +7997,11 @@ msgstr "błąd ustawiania kontekstu skrótu MD5: %s\n" #, c-format msgid "error hashing '%s': %s\n" -msgstr "błąd liczenia skrótu ,,%s'': %s\n" +msgstr "błąd liczenia skrótu „%s”: %s\n" #, c-format msgid "invalid formatted checksum for '%s'\n" -msgstr "niewłaściwie sformatowana suma kontrolna ,,%s''\n" +msgstr "niewłaściwie sformatowana suma kontrolna „%s”\n" #, c-format msgid "too many open cache files; can't open anymore\n" @@ -8010,15 +8010,15 @@ msgstr "" #, c-format msgid "opening cache file '%s'\n" -msgstr "otwieranie pliku pamięci podręcznej ,,%s''\n" +msgstr "otwieranie pliku pamięci podręcznej „%s”\n" #, c-format msgid "error opening cache file '%s': %s\n" -msgstr "błąd otwierania pliku pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd otwierania pliku pamięci podręcznej „%s”: %s\n" #, c-format msgid "error initializing cache file '%s' for reading: %s\n" -msgstr "błąd inicjowania pliku pamięci podręcznej ,,%s'' do odczytu: %s\n" +msgstr "błąd inicjowania pliku pamięci podręcznej „%s” do odczytu: %s\n" #, c-format msgid "calling unlock_db_file on a closed file\n" @@ -8094,7 +8094,7 @@ msgstr "konwersja S-wyrażenia nie powiodła się: %s\n" #, c-format msgid "unknown hash algorithm '%s'\n" -msgstr "niewłaściwy algorytm skrótu ,,%s''\n" +msgstr "niewłaściwy algorytm skrótu „%s”\n" #, c-format msgid "gcry_md_open for algorithm %d failed: %s\n" @@ -8155,17 +8155,17 @@ msgstr "ksba_crl_set_reader nie powiodło się: %s\n" #, c-format msgid "removed stale temporary cache file '%s'\n" -msgstr "usunięto zleżały plik tymczasowy pamięci podręcznej ,,%s''\n" +msgstr "usunięto zleżały plik tymczasowy pamięci podręcznej „%s”\n" #, c-format msgid "problem removing stale temporary cache file '%s': %s\n" msgstr "" -"problem z usunięciem zleżałego pliku tymczasowego pamięci podręcznej ,,%s'': " +"problem z usunięciem zleżałego pliku tymczasowego pamięci podręcznej „%s”: " "%s\n" #, c-format msgid "error creating temporary cache file '%s': %s\n" -msgstr "błąd tworzenia pliku tymczasowego pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd tworzenia pliku tymczasowego pamięci podręcznej „%s”: %s\n" #, c-format msgid "crl_parse_insert failed: %s\n" @@ -8173,11 +8173,11 @@ msgstr "crl_parse_insert nie powiodło się: %s\n" #, c-format msgid "error finishing temporary cache file '%s': %s\n" -msgstr "błąd finalizacji pliku tymczasowego pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd finalizacji pliku tymczasowego pamięci podręcznej „%s”: %s\n" #, c-format msgid "error closing temporary cache file '%s': %s\n" -msgstr "błąd zamykania pliku tymczasowego pamięci podręcznej ,,%s'': %s\n" +msgstr "błąd zamykania pliku tymczasowego pamięci podręcznej „%s”: %s\n" #, c-format msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n" @@ -8198,11 +8198,11 @@ msgstr "błąd odczytu rozszerzeń CRL: %s\n" #, c-format msgid "creating cache file '%s'\n" -msgstr "błąd tworzenia pliku pamięci podręcznej ,,%s''\n" +msgstr "błąd tworzenia pliku pamięci podręcznej „%s”\n" #, c-format msgid "problem renaming '%s' to '%s': %s\n" -msgstr "problem ze zmianą nazwy ,,%s'' na ,,%s'': %s\n" +msgstr "problem ze zmianą nazwy „%s” na „%s”: %s\n" #, c-format msgid "" @@ -8280,7 +8280,7 @@ msgstr "Dostęp do CRL niemożliwy z powodu wyłączonego %s\n" #, c-format msgid "error retrieving '%s': %s\n" -msgstr "błąd odtwarzania ,,%s'': %s\n" +msgstr "błąd odtwarzania „%s”: %s\n" #, c-format msgid "error initializing reader object: %s\n" @@ -8345,7 +8345,7 @@ msgstr "błąd odczytu certyfikatu ze standardowego wejścia: %s\n" #, c-format msgid "error reading certificate from '%s': %s\n" -msgstr "błąd odczytu certyfikatu z ,,%s'': %s\n" +msgstr "błąd odczytu certyfikatu z „%s”: %s\n" #, c-format msgid "certificate too large to make any sense\n" @@ -8361,7 +8361,7 @@ msgstr "wyszukanie nie powiodło się: %s\n" #, c-format msgid "loading CRL '%s' failed: %s\n" -msgstr "załadowanie CRL ,,%s'' nie powiodła się: %s\n" +msgstr "załadowanie CRL „%s” nie powiodła się: %s\n" #, c-format msgid "a dirmngr daemon is up and running\n" @@ -8385,7 +8385,7 @@ msgstr "sprawdzenie certyfikatu nie powiodło się: %s\n" #, c-format msgid "got status: '%s'\n" -msgstr "otrzymano status: ,,%s''\n" +msgstr "otrzymano status: „%s”\n" #, c-format msgid "error writing base64 encoding: %s\n" @@ -8393,7 +8393,7 @@ msgstr "błąd zapisu kodowania base64: %s\n" #, c-format msgid "unsupported inquiry '%s'\n" -msgstr "nieobsługiwane zapytanie ,,%s''\n" +msgstr "nieobsługiwane zapytanie „%s”\n" #, c-format msgid "absolute file name expected\n" @@ -8401,7 +8401,7 @@ msgstr "oczekiwano bezwzględnej nazwy pliku\n" #, c-format msgid "looking up '%s'\n" -msgstr "wyszukiwanie ,,%s''\n" +msgstr "wyszukiwanie „%s”\n" msgid "list the contents of the CRL cache" msgstr "lista zawartości pamięci podręcznej CRL" @@ -8511,7 +8511,7 @@ msgid "" "options)\n" msgstr "" "@\n" -"(pełną listę poleceń i opcji można znaleźć w podręczniku ,,info'')\n" +"(pełną listę poleceń i opcji można znaleźć w podręczniku „info”)\n" msgid "Usage: @DIRMNGR@ [options] (-h for help)" msgstr "Składnia: @DIRMNGR@ [opcje] (-h wyświetla pomoc)" @@ -8537,11 +8537,11 @@ msgstr "dwukropki nie są dozwolone w nazwie gniazda\n" #, c-format msgid "fetching CRL from '%s' failed: %s\n" -msgstr "pobranie CRL z ,,%s'' nie powiodło się: %s\n" +msgstr "pobranie CRL z „%s” nie powiodło się: %s\n" #, c-format msgid "processing CRL from '%s' failed: %s\n" -msgstr "przetworzenie CRL z ,,%s'' nie powiodło się: %s\n" +msgstr "przetworzenie CRL z „%s” nie powiodło się: %s\n" #, c-format msgid "%s:%u: line too long - skipped\n" @@ -8590,11 +8590,11 @@ msgstr "otrzymano sygnał %d - nie zdefiniowano akcji\n" #, c-format msgid "error accessing '%s': http status %u\n" -msgstr "błąd dostępu do ,,%s'': status http %u\n" +msgstr "błąd dostępu do „%s”: status http %u\n" #, c-format msgid "URL '%s' redirected to '%s' (%u)\n" -msgstr "URL ,,%s'' przekierowany na ,,%s'' (%u)\n" +msgstr "URL „%s” przekierowany na „%s” (%u)\n" #, c-format msgid "too many redirections\n" @@ -8602,7 +8602,7 @@ msgstr "za dużo przekierowań\n" #, c-format msgid "redirection changed to '%s'\n" -msgstr "przekierowanie zmienione na ,,%s''\n" +msgstr "przekierowanie zmienione na „%s”\n" #, c-format msgid "error printing log line: %s\n" @@ -8638,7 +8638,7 @@ msgstr "błędny znak 0x%02x w nazwie hosta - nie dodano\n" #, c-format msgid "adding '%s:%d' to the ldap server list\n" -msgstr "dodano ,,%s:%d'' do listy serwerów LDAP\n" +msgstr "dodano „%s:%d” do listy serwerów LDAP\n" #, c-format msgid "malloc failed: %s\n" @@ -8646,11 +8646,11 @@ msgstr "malloc nie powiodło się: %s\n" #, c-format msgid "'%s' is not an LDAP URL\n" -msgstr ",,%s'' nie jest URL-em LDAP\n" +msgstr "„%s” nie jest URL-em LDAP\n" #, c-format msgid "'%s' is an invalid LDAP URL\n" -msgstr ",,%s'' jest nieprawidłowym URL-em LDAP\n" +msgstr "„%s” jest nieprawidłowym URL-em LDAP\n" #, c-format msgid "ldap_search hit the size limit of the server\n" @@ -8711,19 +8711,19 @@ msgstr "błąd budowania żądania OCSP: %s\n" #, c-format msgid "error connecting to '%s': %s\n" -msgstr "błąd połączenia z ,,%s'': %s\n" +msgstr "błąd połączenia z „%s”: %s\n" #, c-format msgid "error reading HTTP response for '%s': %s\n" -msgstr "błąd odczytu odpowiedzi HTTP dla ,,%s'': %s\n" +msgstr "błąd odczytu odpowiedzi HTTP dla „%s”: %s\n" #, c-format msgid "error parsing OCSP response for '%s': %s\n" -msgstr "błąd przetwarzania odpowiedzi OCSP dla ,,%s'': %s\n" +msgstr "błąd przetwarzania odpowiedzi OCSP dla „%s”: %s\n" #, c-format msgid "OCSP responder at '%s' status: %s\n" -msgstr "status respondera OCSP pod ,,%s'': %s\n" +msgstr "status respondera OCSP pod „%s”: %s\n" #, c-format msgid "failed to establish a hashing context for OCSP: %s\n" @@ -8731,7 +8731,7 @@ msgstr "nie udało się ustanowić kontekstu haszowania dla OCSP: %s\n" #, c-format msgid "hashing the OCSP response for '%s' failed: %s\n" -msgstr "liczenie skrótu odpowiedzi OCSP dla ,,%s'' nie powiodło się: %s\n" +msgstr "liczenie skrótu odpowiedzi OCSP dla „%s” nie powiodło się: %s\n" #, c-format msgid "not signed by a default OCSP signer's certificate" @@ -8776,11 +8776,11 @@ msgstr "nie zdefiniowano domyślnego podpisującego OCSP\n" #, c-format msgid "using default OCSP responder '%s'\n" -msgstr "użycie domyślnego respondera OCSP ,,%s''\n" +msgstr "użycie domyślnego respondera OCSP „%s”\n" #, c-format msgid "using OCSP responder '%s'\n" -msgstr "użycie respondera OCSP ,,%s''\n" +msgstr "użycie respondera OCSP „%s”\n" #, c-format msgid "error getting OCSP status for target certificate: %s\n" @@ -8937,11 +8937,11 @@ msgstr "" #, c-format msgid "option \"%s\" requires a program and optional arguments\n" -msgstr "opcja ,,%s'' wymaga programu i opcjonalnych argumentów\n" +msgstr "opcja „%s” wymaga programu i opcjonalnych argumentów\n" #, c-format msgid "option \"%s\" ignored due to \"%s\"\n" -msgstr "opcja ,,%s'' zignorowana z powodu ,,%s''\n" +msgstr "opcja „%s” zignorowana z powodu „%s”\n" #, c-format msgid "receiving line failed: %s\n" @@ -8957,7 +8957,7 @@ msgstr "linia skrócona z powodu osadzonego znaku Nul\n" #, c-format msgid "unknown command '%s'\n" -msgstr "nieznane polecenie ,,%s''\n" +msgstr "nieznane polecenie „%s”\n" #, c-format msgid "sending line failed: %s\n" @@ -9007,7 +9007,7 @@ msgstr "Plik konfiguracyjny komponentu %s jest uszkodzony\n" #, c-format msgid "Note: Use the command \"%s%s\" to get details.\n" -msgstr "Podpowiedź: można użyć polecenia ,,%s%s'', aby uzyskać szczegóły.\n" +msgstr "Podpowiedź: można użyć polecenia „%s%s”, aby uzyskać szczegóły.\n" #, c-format msgid "External verification of component %s failed" @@ -9018,11 +9018,11 @@ msgstr "Uwaga, określenia grup są ignorowane\n" #, c-format msgid "error closing '%s'\n" -msgstr "błąd zamykania ,,%s''\n" +msgstr "błąd zamykania „%s”\n" #, c-format msgid "error parsing '%s'\n" -msgstr "błąd analizy ,,%s''\n" +msgstr "błąd analizy „%s”\n" msgid "list all components" msgstr "lista wszystkich komponentów" @@ -9182,7 +9182,7 @@ msgstr "" #, fuzzy #~| msgid "cipher algorithm '%s' may not be used in %s mode\n" #~ msgid "AEAD algorithm '%s' may not be used in %s mode\n" -#~ msgstr "szyfr ,,%s'' nie może być używany w trybie %s\n" +#~ msgstr "szyfr „%s” nie może być używany w trybie %s\n" #~ msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" #~ msgstr "wymuszone użycie szyfru %s (%d) kłóci się z ustawieniami adresata\n" @@ -9263,74 +9263,74 @@ msgstr "" #~ msgstr "błędny numer portu %d\n" #~ msgid "scanning result for attribute '%s'\n" -#~ msgstr "przeszukiwanie wyniku pod kątem atrybutu ,,%s''\n" +#~ msgstr "przeszukiwanie wyniku pod kątem atrybutu „%s”\n" #~ msgid "error writing to stdout: %s\n" #~ msgstr "błąd zapisu na standardowe wyjście: %s\n" #~ msgid " available attribute '%s'\n" -#~ msgstr " dostępny atrybut ,,%s''\n" +#~ msgstr " dostępny atrybut „%s”\n" #~ msgid "attribute '%s' not found\n" -#~ msgstr "nie znaleziono atrybutu ,,%s''\n" +#~ msgstr "nie znaleziono atrybutu „%s”\n" #~ msgid "found attribute '%s'\n" -#~ msgstr "znaleziono atrybut ,,%s''\n" +#~ msgstr "znaleziono atrybut „%s”\n" #~ msgid "processing url '%s'\n" -#~ msgstr "przetwarzanie URL-a ,,%s''\n" +#~ msgstr "przetwarzanie URL-a „%s”\n" #~ msgid " user '%s'\n" -#~ msgstr " użytkownik ,,%s''\n" +#~ msgstr " użytkownik „%s”\n" #~ msgid " pass '%s'\n" -#~ msgstr " hasło ,,%s''\n" +#~ msgstr " hasło „%s”\n" #~ msgid " host '%s'\n" -#~ msgstr " host ,,%s''\n" +#~ msgstr " host „%s”\n" #~ msgid " port %d\n" #~ msgstr " port %d\n" #~ msgid " DN '%s'\n" -#~ msgstr " DN ,,%s''\n" +#~ msgstr " DN „%s”\n" #~ msgid " filter '%s'\n" -#~ msgstr " filtr ,,%s''\n" +#~ msgstr " filtr „%s”\n" #~ msgid " attr '%s'\n" -#~ msgstr " atrybut ,,%s''\n" +#~ msgstr " atrybut „%s”\n" #~ msgid "no host name in '%s'\n" -#~ msgstr "brak nazwy hosta w ,,%s''\n" +#~ msgstr "brak nazwy hosta w „%s”\n" #~ msgid "no attribute given for query '%s'\n" -#~ msgstr "nie podano atrybutu dla zapytania ,,%s''\n" +#~ msgstr "nie podano atrybutu dla zapytania „%s”\n" #~ msgid "WARNING: using first attribute only\n" #~ msgstr "OSTRZEŻENIE: użyto tylko pierwszego atrybutu\n" #~ msgid "LDAP init to '%s:%d' failed: %s\n" -#~ msgstr "nie udało się zainicjować LDAP na ,,%s:%d'': %s\n" +#~ msgstr "nie udało się zainicjować LDAP na „%s:%d”: %s\n" #, fuzzy #~| msgid "LDAP init to '%s:%d' failed: %s\n" #~ msgid "LDAP init to '%s' failed: %s\n" -#~ msgstr "nie udało się zainicjować LDAP na ,,%s:%d'': %s\n" +#~ msgstr "nie udało się zainicjować LDAP na „%s:%d”: %s\n" #, fuzzy #~| msgid "LDAP init to '%s:%d' failed: %s\n" #~ msgid "LDAP init to '%s' done\n" -#~ msgstr "nie udało się zainicjować LDAP na ,,%s:%d'': %s\n" +#~ msgstr "nie udało się zainicjować LDAP na „%s:%d”: %s\n" #~ msgid "binding to '%s:%d' failed: %s\n" -#~ msgstr "dowiązanie do ,,%s:%d'' nie powiodło się: %s\n" +#~ msgstr "dowiązanie do „%s:%d” nie powiodło się: %s\n" #~ msgid "searching '%s' failed: %s\n" -#~ msgstr "szukanie ,,%s'' nie powiodło się: %s\n" +#~ msgstr "szukanie „%s” nie powiodło się: %s\n" #~ msgid "start_cert_fetch: invalid pattern '%s'\n" -#~ msgstr "start_cert_fetch: błędny wzorzec ,,%s''\n" +#~ msgstr "start_cert_fetch: błędny wzorzec „%s”\n" #~ msgid "ldapserver missing" #~ msgstr "brak pola ldapserver" @@ -9353,7 +9353,7 @@ msgstr "" #~ msgstr "użycie pliku loga dla serwera" #~ msgid "no running gpg-agent - starting '%s'\n" -#~ msgstr "gpg-agent nie działa - uruchamianie ,,%s''\n" +#~ msgstr "gpg-agent nie działa - uruchamianie „%s”\n" #~ msgid "argument not expected" #~ msgstr "nieoczekiwany argument" @@ -9387,7 +9387,7 @@ msgstr "" #, fuzzy #~| msgid "unknown command '%s'\n" #~ msgid "unknown meta command" -#~ msgstr "nieznane polecenie ,,%s''\n" +#~ msgstr "nieznane polecenie „%s”\n" #, fuzzy #~| msgid "unexpected armor: " @@ -9398,31 +9398,31 @@ msgstr "" #~ msgstr "błędna opcja" #~ msgid "missing argument for option \"%.50s\"\n" -#~ msgstr "brak argumentu dla opcji ,,%.50s''\n" +#~ msgstr "brak argumentu dla opcji „%.50s”\n" #~ msgid "option \"%.50s\" does not expect an argument\n" -#~ msgstr "opcja ,,%.50s'' nie może mieć argumentów\n" +#~ msgstr "opcja „%.50s” nie może mieć argumentów\n" #~ msgid "invalid command \"%.50s\"\n" -#~ msgstr "błędne polecenie ,,%.50s''\n" +#~ msgstr "błędne polecenie „%.50s”\n" #~ msgid "option \"%.50s\" is ambiguous\n" -#~ msgstr "opcja ,,%.50s'' jest niejednoznaczna\n" +#~ msgstr "opcja „%.50s” jest niejednoznaczna\n" #~ msgid "command \"%.50s\" is ambiguous\n" -#~ msgstr "polecenie ,,%.50s'' jest niejednoznaczne\n" +#~ msgstr "polecenie „%.50s” jest niejednoznaczne\n" #~ msgid "invalid option \"%.50s\"\n" -#~ msgstr "błędna opcja ,,%.50s''\n" +#~ msgstr "błędna opcja „%.50s”\n" #~ msgid "Note: no default option file '%s'\n" -#~ msgstr "Uwaga: brak domyślnego pliku opcji ,,%s''\n" +#~ msgstr "Uwaga: brak domyślnego pliku opcji „%s”\n" #~ msgid "option file '%s': %s\n" -#~ msgstr "plik opcji ,,%s'': %s\n" +#~ msgstr "plik opcji „%s”: %s\n" #~ msgid "unable to execute program '%s': %s\n" -#~ msgstr "nie można uruchomić programu ,,%s'': %s\n" +#~ msgstr "nie można uruchomić programu „%s”: %s\n" #~ msgid "unable to execute external program\n" #~ msgstr "nie można uruchomić zewnętrznego programu\n" @@ -9443,10 +9443,10 @@ msgstr "" #~ msgstr "honorowanie rekordu PKA ustawionego w kluczu przy pobieraniu kluczy" #~ msgid "Note: Verified signer's address is '%s'\n" -#~ msgstr "Uwaga: Sprawdzony adres pospisującego to ,,%s''\n" +#~ msgstr "Uwaga: Sprawdzony adres pospisującego to „%s”\n" #~ msgid "Note: Signer's address '%s' does not match DNS entry\n" -#~ msgstr "Uwaga: Adres podpisującego ,,%s'' nie pasuje do wpisu DNS\n" +#~ msgstr "Uwaga: Adres podpisującego „%s” nie pasuje do wpisu DNS\n" #~ msgid "trustlevel adjusted to FULL due to valid PKA info\n" #~ msgstr "" @@ -9476,7 +9476,7 @@ msgstr "" #~ msgstr "lista serwerów LDAP" #~ msgid "Note: old default options file '%s' ignored\n" -#~ msgstr "Uwaga: stary domyślny plik opcji ,,%s'' został zignorowany\n" +#~ msgstr "Uwaga: stary domyślny plik opcji „%s” został zignorowany\n" #~ msgid "" #~ "@\n" @@ -9524,7 +9524,7 @@ msgstr "" #~ msgstr "%s na %s nie powiódł się ze stanem %i\n" #~ msgid "can't create temporary directory '%s': %s\n" -#~ msgstr "nie można utworzyć katalogu tymczasowego ,,%s'': %s\n" +#~ msgstr "nie można utworzyć katalogu tymczasowego „%s”: %s\n" #~ msgid "could not open %s for writing: %s\n" #~ msgstr "nie udało się otworzyć %s do zapisu: %s\n" From 6b93b92111cb8ce6d06c6f71bd62cfb314663b8c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 12 Dec 2023 14:23:53 +0900 Subject: [PATCH 268/869] doc: Fix description of scdaemon for --disable-ccid. -- GnuPG-bug-id: 6871 Signed-off-by: NIIBE Yutaka --- doc/scdaemon.texi | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 6f56585e6..d4e663eff 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -241,18 +241,16 @@ Instead of using this option you might also want to install a symbolic link to the default file name (e.g. from @file{libpcsclite.so.1}). A Unicode file name may not be used on Windows. -@item --ctapi-driver @var{library} -@opindex ctapi-driver -Use @var{library} to access the smartcard reader. The current default -is @file{libtowitoko.so}. Note that the use of this interface is -deprecated; it may be removed in future releases. - @item --disable-ccid @opindex disable-ccid -Disable the integrated support for CCID compliant readers. This -allows falling back to one of the other drivers even if the internal -CCID driver can handle the reader. Note, that CCID support is only -available if libusb was available at build time. +The integrated CCID driver for CCID compliant devices can be available +when libusb was detected at build time, and it is used to access the +smartcard reader. If access via PC/SC driver is needed, please +configure this option to disable CCID driver support (if any). In +GnuPG 2.2, there was a fallback mechanism from CCID driver to PC/SC +driver. The fallback mechanism worked, because scdaemon in GnuPG 2.2 +only supported a single token/reader. To support of multiple +tokens/readers at the same time, fallback mechanism was removed. @item --reader-port @var{number_or_string} @opindex reader-port From 37fa36a3291f765f8dd3a5f1ab0cd91f0b49e5f4 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 12 Dec 2023 14:23:53 +0900 Subject: [PATCH 269/869] doc: Fix description of scdaemon for --disable-ccid. -- Cherry-picked from 2.4 branch of the commit: 6b93b92111cb8ce6d06c6f71bd62cfb314663b8c GnuPG-bug-id: 6871 Signed-off-by: NIIBE Yutaka --- doc/scdaemon.texi | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 2c5444e40..264f71301 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -241,18 +241,16 @@ Instead of using this option you might also want to install a symbolic link to the default file name (e.g., from @file{libpcsclite.so.1}). A Unicode file name may not be used on Windows. -@item --ctapi-driver @var{library} -@opindex ctapi-driver -Use @var{library} to access the smartcard reader. The current default -is @file{libtowitoko.so}. Note that the use of this interface is -deprecated; it may be removed in future releases. - @item --disable-ccid @opindex disable-ccid -Disable the integrated support for CCID compliant readers. This -allows falling back to one of the other drivers even if the internal -CCID driver can handle the reader. Note, that CCID support is only -available if libusb was available at build time. +The integrated CCID driver for CCID compliant devices can be available +when libusb was detected at build time, and it is used to access the +smartcard reader. If access via PC/SC driver is needed, please +configure this option to disable CCID driver support (if any). In +GnuPG 2.2, there was a fallback mechanism from CCID driver to PC/SC +driver. The fallback mechanism worked, because scdaemon in GnuPG 2.2 +only supported a single token/reader. To support of multiple +tokens/readers at the same time, fallback mechanism was removed. @item --reader-port @var{number_or_string} @opindex reader-port From f57717bf2314578385e184de5e417b08e22c4c87 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 12 Dec 2023 16:31:30 +0100 Subject: [PATCH 270/869] common: Improve error return for dotlock. * common/dotlock.c (dotlock_take_unix): Return a ETIMEDOUT insteaad of EACCESS on timeout. (dotlock_take_w32): Ditto. --- common/dotlock.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/common/dotlock.c b/common/dotlock.c index 74186b776..d1058845e 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -1061,6 +1061,7 @@ static int dotlock_take_unix (dotlock_t h, long timeout) { int wtime = 0; + int timedout = 0; int sumtime = 0; int pid; int lastpid = -1; @@ -1218,6 +1219,8 @@ dotlock_take_unix (dotlock_t h, long timeout) wtime = 0; /* Reset because owner chnaged. */ wtimereal = next_wait_interval (&wtime, &timeout); + if (!timeout) + timedout = 1; /* remember. */ sumtime += wtimereal; if (sumtime >= 1500) @@ -1233,7 +1236,7 @@ dotlock_take_unix (dotlock_t h, long timeout) goto again; } - my_set_errno (EACCES); + my_set_errno (timedout? ETIMEDOUT : EACCES); return -1; } #endif /*HAVE_POSIX_SYSTEM*/ @@ -1246,6 +1249,7 @@ static int dotlock_take_w32 (dotlock_t h, long timeout) { int wtime = 0; + int timedout = 0; int w32err; OVERLAPPED ovl; @@ -1273,6 +1277,8 @@ dotlock_take_w32 (dotlock_t h, long timeout) int wtimereal; wtimereal = next_wait_interval (&wtime, &timeout); + if (!timeout) + timedout = 1; /* remember. */ if (wtime >= 800) my_info_1 (_("waiting for lock %s...\n"), h->lockname); @@ -1281,7 +1287,7 @@ dotlock_take_w32 (dotlock_t h, long timeout) goto again; } - my_set_errno (EACCES); + my_set_errno (timedout? ETIMEDOUT : EACCES); return -1; } #endif /*HAVE_DOSISH_SYSTEM*/ From 4e94b004a69e63512e4e37858840614b3e062122 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 18 Dec 2023 11:25:01 +0900 Subject: [PATCH 271/869] scd: Debug output is only enabled with an option. * scd/command.c (pin_cb): Check if DBG_IPC for log_debug. (send_client_notifications): Check opt.verbose to output a message. -- Signed-off-by: NIIBE Yutaka --- scd/command.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/scd/command.c b/scd/command.c index 9ce3889d2..a2274f15a 100644 --- a/scd/command.c +++ b/scd/command.c @@ -957,7 +957,8 @@ pin_cb (void *opaque, const char *info, char **retstr) We ignore any value returned. */ if (info) { - log_debug ("prompting for pinpad entry '%s'\n", info); + if (DBG_IPC) + log_debug ("prompting for pinpad entry '%s'\n", info); rc = gpgrt_asprintf (&command, "POPUPPINPADPROMPT %s", info); if (rc < 0) return gpg_error (gpg_err_code_from_errno (errno)); @@ -966,7 +967,8 @@ pin_cb (void *opaque, const char *info, char **retstr) } else { - log_debug ("dismiss pinpad entry prompt\n"); + if (DBG_IPC) + log_debug ("dismiss pinpad entry prompt\n"); rc = assuan_inquire (ctx, "DISMISSPINPADPROMPT", &value, &valuelen, MAXLEN_PIN); } @@ -976,7 +978,8 @@ pin_cb (void *opaque, const char *info, char **retstr) } *retstr = NULL; - log_debug ("asking for PIN '%s'\n", info); + if (DBG_IPC) + log_debug ("asking for PIN '%s'\n", info); rc = gpgrt_asprintf (&command, "NEEDPIN %s", info); if (rc < 0) @@ -2989,12 +2992,16 @@ send_client_notifications (card_t card, int removal) if (killed[kidx].handle == handle) break; if (kidx < killidx) - log_info ("event %p already triggered for client\n", - sl->event_signal); + { + if (opt.verbose) + log_info ("event %p already triggered for client\n", + sl->event_signal); + } else { - log_info ("triggering event %p for client\n", - sl->event_signal); + if (opt.verbose) + log_info ("triggering event %p for client\n", + sl->event_signal); if (!SetEvent (handle)) log_error ("SetEvent(%p) failed: %s\n", sl->event_signal, w32_strerror (-1)); @@ -3015,12 +3022,16 @@ send_client_notifications (card_t card, int removal) && killed[kidx].signo == signo) break; if (kidx < killidx) - log_info ("signal %d already sent to client %d\n", - signo, (int)pid); + { + if (opt.verbose) + log_info ("signal %d already sent to client %d\n", + signo, (int)pid); + } else { - log_info ("sending signal %d to client %d\n", - signo, (int)pid); + if (opt.verbose) + log_info ("sending signal %d to client %d\n", + signo, (int)pid); kill (pid, signo); if (killidx < DIM (killed)) { From 937aeb1904eb5cbe7a8c1c686877c7a9e1196ca6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 13 Dec 2023 10:08:12 +0100 Subject: [PATCH 272/869] common: Add an info callback to dotlock. * common/dotlock.h (enum dotlock_reasons): New. (DOTLOCK_PREPARE_CREATE): New flag. * common/dotlock.c (struct dotlock_handle): Add info_cb and info_cb_value. (dotlock_create): Support the new flag. (dotlock_finish_create): New. (read_lockfile): Silence in case of ENOENT. (dotlock_set_info_cb): New. Use callback after all error and info messages. (dotlock_take_unix, dotlock_take_w32): Allow termination by callback. --- common/dotlock.c | 158 ++++++++++++++++++++++++++++++++++++++++++--- common/dotlock.h | 20 ++++++ common/t-dotlock.c | 36 ++++++++++- 3 files changed, 203 insertions(+), 11 deletions(-) diff --git a/common/dotlock.c b/common/dotlock.c index d1058845e..261e2cce7 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -396,6 +396,13 @@ struct dotlock_handle int extra_fd; /* A place for the caller to store an FD. */ + /* An optional info callback - see dotlock_set_info_cb. */ + int (*info_cb)(dotlock_t, void *, + enum dotlock_reasons reason, + const char *,...); + void *info_cb_value; + + #ifdef HAVE_DOSISH_SYSTEM HANDLE lockhd; /* The W32 handle of the lock file. */ #else /*!HAVE_DOSISH_SYSTEM */ @@ -545,8 +552,15 @@ read_lockfile (dotlock_t h, int *same_node, int *r_fd) if ( (fd = open (h->lockname, O_RDONLY)) == -1 ) { int e = errno; - my_info_2 ("error opening lockfile '%s': %s\n", - h->lockname, strerror(errno) ); + if (errno != ENOENT) + { + my_info_2 ("error opening lockfile '%s': %s\n", + h->lockname, strerror(errno) ); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + "error opening lockfile '%s': %s\n", + h->lockname, strerror (errno) ); + } if (buffer != buffer_space) xfree (buffer); my_set_errno (e); /* Need to return ERRNO here. */ @@ -564,6 +578,10 @@ read_lockfile (dotlock_t h, int *same_node, int *r_fd) { int e = errno; my_info_1 ("error reading lockfile '%s'\n", h->lockname ); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + "error reading lockfile '%s': %s\n", + h->lockname, strerror (errno) ); close (fd); if (buffer != buffer_space) xfree (buffer); @@ -583,6 +601,9 @@ read_lockfile (dotlock_t h, int *same_node, int *r_fd) if (nread < 11) { my_info_1 ("invalid size of lockfile '%s'\n", h->lockname); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_INV_FILE, + "invalid size of lockfile '%s'\n", h->lockname); if (buffer != buffer_space) xfree (buffer); my_set_errno (EINVAL); @@ -594,6 +615,9 @@ read_lockfile (dotlock_t h, int *same_node, int *r_fd) || !pid ) { my_error_2 ("invalid pid %d in lockfile '%s'\n", pid, h->lockname); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_INV_FILE, + "invalid pid %d in lockfile '%s'\n", pid, h->lockname); if (buffer != buffer_space) xfree (buffer); my_set_errno (EINVAL); @@ -722,6 +746,10 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) UNLOCK_all_lockfiles (); my_error_2 (_("failed to create temporary file '%s': %s\n"), h->tname, strerror (errno)); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_WAITING, + _("failed to create temporary file '%s': %s\n"), + h->tname, strerror (errno)); xfree (h->tname); xfree (h); my_set_errno (saveerrno); @@ -755,6 +783,10 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) int saveerrno = errno; my_error_2 ("can't check whether hardlinks are supported for '%s': %s\n" , h->tname, strerror (saveerrno)); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_CONFIG_TEST, + "can't check whether hardlinks are supported for '%s': %s\n" + , h->tname, strerror (saveerrno)); my_set_errno (saveerrno); } goto write_failed; @@ -783,6 +815,11 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) all_lockfiles = h->next; UNLOCK_all_lockfiles (); my_error_2 (_("error writing to '%s': %s\n"), h->tname, strerror (errno)); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + _("error writing to '%s': %s\n"), + h->tname, strerror (errno)); + if ( fd != -1 ) close (fd); unlink (h->tname); @@ -849,6 +886,10 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock) all_lockfiles = h->next; UNLOCK_all_lockfiles (); my_error_2 (_("can't create '%s': %s\n"), h->lockname, w32_strerror (-1)); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + _("can't create '%s': %s\n"), + h->lockname, w32_strerror (-1)); xfree (h->lockname); xfree (h); my_set_errno (saveerrno); @@ -873,7 +914,10 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock) POSIX systems a temporary file ".#lk..pid[.threadid] is used. - FLAGS must be 0. + The only defined FLAG bit is DOTLOCK_PREPARE_CREATE, which only + allocates the handle and requires a further call to + dotlock_finish_create. This can be used to set a callback between + these calls. The function returns an new handle which needs to be released using destroy_dotlock but gets also released at the termination of the @@ -895,7 +939,7 @@ dotlock_create (const char *file_to_lock, unsigned int flags) if ( !file_to_lock ) return NULL; /* Only initialization was requested. */ - if (flags) + if ((flags & ~DOTLOCK_PREPARE_CREATE)) { my_set_errno (EINVAL); return NULL; @@ -916,6 +960,24 @@ dotlock_create (const char *file_to_lock, unsigned int flags) return h; } + if ((flags & DOTLOCK_PREPARE_CREATE)) + return h; + else + return dotlock_finish_create (h, file_to_lock); +} + + +/* This function may be used along with dotlock_create (file_name, + * DOTLOCK_PREPARE_CREATE) to finish the creation call. The given + * filename shall be the same as passed to dotlock_create. On success + * the same handle H is returned, on error NULL is returned and H is + * released. */ +dotlock_t +dotlock_finish_create (dotlock_t h, const char *file_to_lock) +{ + if (!h || !file_to_lock) + return NULL; + #ifdef HAVE_DOSISH_SYSTEM return dotlock_create_w32 (h, file_to_lock); #else /*!HAVE_DOSISH_SYSTEM */ @@ -942,6 +1004,24 @@ dotlock_get_fd (dotlock_t h) } +/* Set a callback function for info diagnostics. The callback + * function CB is called with the handle, the opaque value OPAQUE, a + * reason code, and a format string with its arguments. The callback + * shall return 0 to continue operation or true in which case the + * current function will be terminated with an error. */ +void +dotlock_set_info_cb (dotlock_t h, + int (*cb)(dotlock_t, void *, + enum dotlock_reasons reason, + const char *,...), + void *opaque) +{ + h->info_cb = cb; + h->info_cb_value = opaque; +} + + + #ifdef HAVE_POSIX_SYSTEM /* Unix specific code of destroy_dotlock. */ @@ -1090,6 +1170,10 @@ dotlock_take_unix (dotlock_t h, long timeout) saveerrno = errno; my_error_2 ("lock not made: open(O_EXCL) of '%s' failed: %s\n", h->lockname, strerror (saveerrno)); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + "lock not made: open(O_EXCL) of '%s' failed: %s\n", + h->lockname, strerror (saveerrno)); my_set_errno (saveerrno); return -1; } @@ -1111,6 +1195,10 @@ dotlock_take_unix (dotlock_t h, long timeout) saveerrno = errno; my_error_2 ("lock not made: writing to '%s' failed: %s\n", h->lockname, strerror (errno)); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + "lock not made: writing to '%s' failed: %s\n", + h->lockname, strerror (errno)); close (fd); unlink (h->lockname); my_set_errno (saveerrno); @@ -1129,6 +1217,10 @@ dotlock_take_unix (dotlock_t h, long timeout) saveerrno = errno; my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n", strerror (errno)); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + "lock not made: Oops: stat of tmp file failed: %s\n", + strerror (errno)); /* In theory this might be a severe error: It is possible that link succeeded but stat failed due to changed permissions. We can't do anything about it, though. */ @@ -1150,6 +1242,9 @@ dotlock_take_unix (dotlock_t h, long timeout) { saveerrno = errno; my_info_0 ("cannot read lockfile\n"); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + "cannot read lockfile\n"); my_set_errno (saveerrno); return -1; } @@ -1158,8 +1253,8 @@ dotlock_take_unix (dotlock_t h, long timeout) } else if ( (pid == getpid() && same_node) || (same_node && kill (pid, 0) && errno == ESRCH) ) - /* Stale lockfile is detected. */ { + /* Stale lockfile is detected. */ struct stat sb; /* Check if it's unlocked during examining the lockfile. */ @@ -1202,6 +1297,9 @@ dotlock_take_unix (dotlock_t h, long timeout) unlink (h->lockname); my_info_1 (_("removing stale lockfile (created by %d)\n"), pid); close (fd); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_STALE_REMOVED, + _("removing stale lockfile (created by %d)\n"), pid); goto again; } @@ -1228,6 +1326,15 @@ dotlock_take_unix (dotlock_t h, long timeout) sumtime = 0; my_info_3 (_("waiting for lock (held by %d%s) %s...\n"), pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):""); + if (h->info_cb + && h->info_cb (h, h->info_cb_value, DOTLOCK_WAITING, + _("waiting for lock (held by %d%s) %s...\n"), + pid, maybe_dead, + maybe_deadlock(h)? _("(deadlock?) "):"")) + { + my_set_errno (ECANCELED); + return -1; + } } tv.tv_sec = wtimereal / 1000; @@ -1268,7 +1375,11 @@ dotlock_take_w32 (dotlock_t h, long timeout) { my_error_2 (_("lock '%s' not made: %s\n"), h->lockname, w32_strerror (w32err)); - my_set_errno (map_w32_to_errno (w32err)); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + _("lock '%s' not made: %s\n"), + h->lockname, w32_strerror (w32err)); + _set_errno (map_w32_to_errno (w32err)); return -1; } @@ -1281,7 +1392,16 @@ dotlock_take_w32 (dotlock_t h, long timeout) timedout = 1; /* remember. */ if (wtime >= 800) - my_info_1 (_("waiting for lock %s...\n"), h->lockname); + { + my_info_1 (_("waiting for lock %s...\n"), h->lockname); + if (h->info_cb + && h->info_cb (h, h->info_cb_value, DOTLOCK_WAITING, + _("waiting for lock %s...\n"), h->lockname)) + { + my_set_errno (ECANCELED); + return -1; + } + } Sleep (wtimereal); goto again; @@ -1334,12 +1454,18 @@ dotlock_release_unix (dotlock_t h) { saveerrno = errno; my_error_0 ("release_dotlock: lockfile error\n"); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + "release_dotlock: lockfile error\n"); my_set_errno (saveerrno); return -1; } if ( pid != getpid() || !same_node ) { my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_CONFLICT, + "release_dotlock: not our lock (pid=%d)\n", pid); my_set_errno (EACCES); return -1; } @@ -1349,6 +1475,10 @@ dotlock_release_unix (dotlock_t h) saveerrno = errno; my_error_1 ("release_dotlock: error removing lockfile '%s'\n", h->lockname); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + "release_dotlock: error removing lockfile '%s'\n", + h->lockname); my_set_errno (saveerrno); return -1; } @@ -1369,10 +1499,15 @@ dotlock_release_w32 (dotlock_t h) memset (&ovl, 0, sizeof ovl); if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl)) { - int saveerrno = map_w32_to_errno (GetLastError ()); + int ec = (int)GetLastError (); + my_error_2 ("release_dotlock: error removing lockfile '%s': %s\n", - h->lockname, w32_strerror (-1)); - my_set_errno (saveerrno); + h->lockname, w32_strerror (ec)); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_FILE_ERROR, + "release_dotlock: error removing lockfile '%s': %s\n", + h->lockname, w32_strerror (ec)); + my_set_errno (map_w32_to_errno (ec)); return -1; } @@ -1403,6 +1538,9 @@ dotlock_release (dotlock_t h) if ( !h->locked ) { my_debug_1 ("Oops, '%s' is not locked\n", h->lockname); + if (h->info_cb) + h->info_cb (h, h->info_cb_value, DOTLOCK_NOT_LOCKED, + "Oops, '%s' is not locked\n", h->lockname); return 0; } diff --git a/common/dotlock.h b/common/dotlock.h index 03131bb0c..915279176 100644 --- a/common/dotlock.h +++ b/common/dotlock.h @@ -97,12 +97,32 @@ extern "C" struct dotlock_handle; typedef struct dotlock_handle *dotlock_t; +enum dotlock_reasons + { + DOTLOCK_CONFIG_TEST, /* Can't check system - function terminates. */ + DOTLOCK_FILE_ERROR, /* General file error - function terminates. */ + DOTLOCK_INV_FILE, /* Invalid file - function terminates. */ + DOTLOCK_CONFLICT, /* Something is wrong - function terminates. */ + DOTLOCK_NOT_LOCKED, /* Not locked - No action required. */ + DOTLOCK_STALE_REMOVED, /* Stale lock file was removed - retrying. */ + DOTLOCK_WAITING /* Waiting for the lock - may be terminated. */ + }; + +#define DOTLOCK_PREPARE_CREATE (1<<5) /* Require dotlock_finish_create. */ + void dotlock_disable (void); dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags); +dotlock_t dotlock_finish_create (dotlock_t h, const char *file_to_lock); void dotlock_set_fd (dotlock_t h, int fd); int dotlock_get_fd (dotlock_t h); +void dotlock_set_info_cb (dotlock_t h, + int (*cb)(dotlock_t, void *, + enum dotlock_reasons reason, + const char *,...), + void *opaque); void dotlock_destroy (dotlock_t h); int dotlock_take (dotlock_t h, long timeout); +int dotlock_is_locked (dotlock_t h); int dotlock_release (dotlock_t h); void dotlock_remove_lockfiles (void); diff --git a/common/t-dotlock.c b/common/t-dotlock.c index 994ef1be3..87e62bb33 100644 --- a/common/t-dotlock.c +++ b/common/t-dotlock.c @@ -52,6 +52,7 @@ #ifdef HAVE_W32_SYSTEM #define DIM(v) (sizeof(v)/sizeof((v)[0])) + const char * w32_strerror (int ec) { @@ -174,6 +175,11 @@ strconcat (const char *s1, ...) #define PGM "t-dotlock" +static int opt_silent; + + + + #ifndef HAVE_W32_SYSTEM static volatile int ctrl_c_pending_flag; static void @@ -217,6 +223,9 @@ inf (const char *format, ...) { va_list arg_ptr; + if (opt_silent) + return; + va_start (arg_ptr, format); fprintf (stderr, PGM "[%lu]: ", (unsigned long)getpid ()); vfprintf (stderr, format, arg_ptr); @@ -225,15 +234,35 @@ inf (const char *format, ...) } +static int +lock_info_cb (dotlock_t h, void *opaque, enum dotlock_reasons reason, + const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + fprintf (stderr, PGM "[%lu]: info_cb: reason %d, ", + (unsigned long)getpid (), (int)reason); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + return 0; +} + + static void lock_and_unlock (const char *fname) { dotlock_t h; unsigned long usec; - h = dotlock_create (fname, 0); + h = dotlock_create (fname, DOTLOCK_PREPARE_CREATE); if (!h) die ("error creating lock file for '%s': %s", fname, strerror (errno)); + dotlock_set_info_cb (h, lock_info_cb, NULL); + h = dotlock_finish_create (h, fname); + if (!h) + die ("error finishing lock file creation for '%s': %s", + fname, strerror (errno)); inf ("lock created"); do @@ -270,6 +299,11 @@ main (int argc, char **argv) ctrl_c_pending_flag = 1; argc--; } + if (argc > 1 && !strcmp (argv[1], "--silent")) + { + opt_silent = 1; + argc--; + } if (argc > 1) fname = argv[argc-1]; From c99282fc7838870b70a831924778e50cac34b3e1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 18 Dec 2023 15:25:45 +0100 Subject: [PATCH 273/869] keyboxd: Timeout on failure to get the database lock. * kbx/backend-sqlite.c (dblock_info_cb): New. (create_or_open_database): Add arg ctrl. Add a 10 second timeout. Avoid warning on error if not locked. (be_sqlite_add_resource): Do not open the database here. (be_sqlite_search): ... but do it here. -- Note that we need to delay the initalization to the first use of the database so that we actually have a recipient for the status messages. GnuPG-bug-id: 6838 --- kbx/backend-sqlite.c | 68 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/kbx/backend-sqlite.c b/kbx/backend-sqlite.c index 202897e91..ec891da6d 100644 --- a/kbx/backend-sqlite.c +++ b/kbx/backend-sqlite.c @@ -521,11 +521,45 @@ run_sql_statement (const char *sqlstr) } +static int +dblock_info_cb (dotlock_t h, void *opaque, enum dotlock_reasons reason, + const char *format, ...) +{ + ctrl_t ctrl = opaque; + va_list arg_ptr; + gpg_error_t err; + int rc = 0; + char tmpbuf[200]; + + (void)h; + + if (reason == DOTLOCK_WAITING) + { + if (format) + { + va_start (arg_ptr, format); + gpgrt_vsnprintf (tmpbuf, sizeof tmpbuf, format, arg_ptr); + va_end (arg_ptr); + } + else + *tmpbuf = 0; + err = kbxd_status_printf (ctrl, "NOTE", "database_open %u %s", + gpg_error (GPG_ERR_LOCKED), tmpbuf); + if (err) + { + log_error ("sending status line failed: %s\n", gpg_strerror (err)); + rc = 1; /* snprintf failed. */ + } + + } + return rc; +} + /* Create and initialize a new SQL database file if it does not * exists; else open it and check that all required objects are * available. */ static gpg_error_t -create_or_open_database (const char *filename) +create_or_open_database (ctrl_t ctrl, const char *filename) { gpg_error_t err; int res; @@ -542,7 +576,16 @@ create_or_open_database (const char *filename) /* To avoid races with other temporary instances of keyboxd trying * to create or update the database, we run the database with a lock * file held. */ - database_lock = dotlock_create (filename, 0); + database_lock = dotlock_create (filename, DOTLOCK_PREPARE_CREATE); + if (!database_lock) + { + err = gpg_error_from_syserror (); + if (opt.verbose) + log_info ("can't allocate dotlock handle: %s\n", gpg_strerror (err)); + goto leave; + } + dotlock_set_info_cb (database_lock, dblock_info_cb, ctrl); + database_lock = dotlock_finish_create (database_lock, filename); if (!database_lock) { err = gpg_error_from_syserror (); @@ -556,7 +599,7 @@ create_or_open_database (const char *filename) goto leave; } - if (dotlock_take (database_lock, -1)) + if (dotlock_take (database_lock, 10000)) { err = gpg_error_from_syserror (); /* This is something bad. Probably a stale lockfile. */ @@ -646,7 +689,8 @@ create_or_open_database (const char *filename) { log_error (_("error creating database '%s': %s\n"), filename, gpg_strerror (err)); - dotlock_release (database_lock); + if (dotlock_is_locked (database_lock)) + dotlock_release (database_lock); dotlock_destroy (database_lock); database_lock = NULL; } @@ -660,7 +704,6 @@ gpg_error_t be_sqlite_add_resource (ctrl_t ctrl, backend_handle_t *r_hd, const char *filename, int readonly) { - gpg_error_t err; backend_handle_t hd; (void)ctrl; @@ -672,19 +715,10 @@ be_sqlite_add_resource (ctrl_t ctrl, backend_handle_t *r_hd, return gpg_error_from_syserror (); hd->db_type = DB_TYPE_SQLITE; strcpy (hd->filename, filename); - - err = create_or_open_database (filename); - if (err) - goto leave; - hd->backend_id = be_new_backend_id (); *r_hd = hd; - hd = NULL; - - leave: - xfree (hd); - return err; + return 0; } @@ -1139,6 +1173,10 @@ be_sqlite_search (ctrl_t ctrl, log_assert (backend_hd && backend_hd->db_type == DB_TYPE_SQLITE); log_assert (request); + err = create_or_open_database (ctrl, backend_hd->filename); + if (err) + return err; + acquire_mutex (); /* Find the specific request part or allocate it. */ From bd8346f7abdd6c163d563a2ed5059b514beb7c01 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 18 Dec 2023 16:23:19 +0100 Subject: [PATCH 274/869] keyboxd: Pass lock info back to gpg and gpgsm. * g10/call-keyboxd.c (keydb_default_status_cb): New. (keydb_update_keyblock): Add new status callback. (keydb_insert_keyblock): Ditto. (keydb_delete_keyblock): Ditto. (search_status_cb): Also try the new status callback. * sm/keydb.c (keydb_default_status_cb): New. (keydb_insert_cert): Add new status callback. (keydb_delete): Ditto (search_status_cb): Also try the new status callback. -- GnuPG-bug-id: 6838 --- g10/call-keyboxd.c | 26 +++++++++++++++++++++++--- kbx/kbx-client-util.c | 8 ++++---- sm/keydb.c | 23 +++++++++++++++++++++-- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/g10/call-keyboxd.c b/g10/call-keyboxd.c index 7f4d5f493..121b7aa2a 100644 --- a/g10/call-keyboxd.c +++ b/g10/call-keyboxd.c @@ -385,6 +385,23 @@ keydb_get_keyblock (KEYDB_HANDLE hd, kbnode_t *ret_kb) } +/* Default status callback used to show diagnostics from the keyboxd */ +static gpg_error_t +keydb_default_status_cb (void *opaque, const char *line) +{ + const char *s; + + (void)opaque; + + if ((s = has_leading_keyword (line, "NOTE"))) + log_info (_("Note: %s\n"), s); + else if ((s = has_leading_keyword (line, "WARNING"))) + log_info (_("WARNING: %s\n"), s); + + return 0; +} + + /* Communication object for STORE commands. */ struct store_parm_s @@ -464,7 +481,8 @@ keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb) err = assuan_transact (hd->kbl->ctx, "STORE --update", NULL, NULL, store_inq_cb, &parm, - NULL, NULL); + keydb_default_status_cb, hd); + leave: iobuf_close (iobuf); @@ -515,7 +533,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb) err = assuan_transact (hd->kbl->ctx, "STORE --insert", NULL, NULL, store_inq_cb, &parm, - NULL, NULL); + keydb_default_status_cb, hd); leave: iobuf_close (iobuf); @@ -561,7 +579,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd) err = assuan_transact (hd->kbl->ctx, line, NULL, NULL, NULL, NULL, - NULL, NULL); + keydb_default_status_cb, hd); leave: return err; @@ -648,6 +666,8 @@ search_status_cb (void *opaque, const char *line) } } } + else + err = keydb_default_status_cb (opaque, line); return err; } diff --git a/kbx/kbx-client-util.c b/kbx/kbx-client-util.c index f9d06fab8..f6456a508 100644 --- a/kbx/kbx-client-util.c +++ b/kbx/kbx-client-util.c @@ -399,10 +399,10 @@ kbx_client_data_cmd (kbx_client_data_t kcd, const char *command, status_cb, status_cb_value); if (err) { - if (gpg_err_code (err) != GPG_ERR_NOT_FOUND - && gpg_err_code (err) != GPG_ERR_NOTHING_FOUND) - log_debug ("%s: finished command with error: %s\n", - __func__, gpg_strerror (err)); + /* if (gpg_err_code (err) != GPG_ERR_NOT_FOUND */ + /* && gpg_err_code (err) != GPG_ERR_NOTHING_FOUND) */ + /* log_debug ("%s: finished command with error: %s\n", */ + /* __func__, gpg_strerror (err)); */ xfree (get_membuf (&mb, &len)); kcd->dlineerr = err; goto leave; diff --git a/sm/keydb.c b/sm/keydb.c index 38737c96a..411720513 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -1129,6 +1129,23 @@ keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value) } +/* Default status callback used to show diagnostics from the keyboxd */ +static gpg_error_t +keydb_default_status_cb (void *opaque, const char *line) +{ + const char *s; + + (void)opaque; + + if ((s = has_leading_keyword (line, "NOTE"))) + log_info (_("Note: %s\n"), s); + else if ((s = has_leading_keyword (line, "WARNING"))) + log_info (_("WARNING: %s\n"), s); + + return 0; +} + + /* Communication object for Keyboxd STORE commands. */ struct store_parm_s @@ -1192,7 +1209,7 @@ keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert) err = assuan_transact (hd->kbl->ctx, "STORE --insert", NULL, NULL, store_inq_cb, &parm, - NULL, NULL); + keydb_default_status_cb, hd); goto leave; } @@ -1327,7 +1344,7 @@ keydb_delete (KEYDB_HANDLE hd) err = assuan_transact (hd->kbl->ctx, line, NULL, NULL, NULL, NULL, - NULL, NULL); + keydb_default_status_cb, hd); goto leave; } @@ -1555,6 +1572,8 @@ search_status_cb (void *opaque, const char *line) } } } + else + err = keydb_default_status_cb (opaque, line); return err; } From 1c5584c395d75121046e42a27d60df7b6c6e660e Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 19 Dec 2023 15:56:13 +0900 Subject: [PATCH 275/869] kbx: Create public-keys.d, after creating the homedir. * kbx/keyboxd.c (create_directories): Following the behavior of gpg-agent, call create_public_keys_directory after mkdir. -- Signed-off-by: NIIBE Yutaka --- kbx/keyboxd.c | 1 + tools/dotlock.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 tools/dotlock.c diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index 88a350a08..f875e115d 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -1262,6 +1262,7 @@ create_directories (void) { if (!opt.quiet) log_info (_("directory '%s' created\n"), home); + create_public_keys_directory (home); } } } diff --git a/tools/dotlock.c b/tools/dotlock.c new file mode 100644 index 000000000..27ae5205b --- /dev/null +++ b/tools/dotlock.c @@ -0,0 +1,87 @@ +/* dotlock.c - Command to handle dotlock. + * Copyright (C) 2023 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 . + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_W32_SYSTEM +# include "windows.h" +#else +#include +#endif + +#include "dotlock.h" + +static void +lock (const char *fname) +{ + dotlock_t h; + unsigned int flags = DOTLOCK_FLAG_LOCK_BY_PARENT; + + h = dotlock_create (fname, flags); + if (!h) + die ("error creating lock file for '%s': %s", fname, strerror (errno)); + + if (dotlock_take (h, 0)) + die ("error taking lock"); +} + +static void +unlock (const char *fname, long timeout) +{ + dotlock_t h; + unsigned int flags = (DOTLOCK_FLAG_LOCK_BY_PARENT + | DOTLOCK_FLAG_READONLY); + + h = dotlock_create (fname, flags); + if (!h) + die ("error creating lock file for '%s': %s", fname, strerror (errno)); + + dotlock_destroy (h); +} + + +int +main (int argc, char **argv) +{ + const char *fname; + + fname = argv[argc-1]; + + if () + lock (fname); + else + unlock (fname); + + return 0; +} + + +/* +Local Variables: +compile-command: "cc -Wall -O2 -D_FILE_OFFSET_BITS=64 -o t-dotlock t-dotlock.c" +End: +*/ From 6b4fd3a5da7e018166d154d6514161d939f5c4f1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 19 Dec 2023 15:59:41 +0900 Subject: [PATCH 276/869] common: Enhance dotlock, so that we can have a CLI util. * common/dotlock.h (DOTLOCK_LOCK_BY_PARENT, DOTLOCK_LOCKED): New. * common/dotlock.c [HAVE_POSIX_SYSTEM]: Include . (dotlock_get_process_id, dotlock_detect_tname): New. (dotlock_create_unix): Handle the case when no_write option is specified. Not creating the lock file, but detect the the file of tname. (dotlock_create) [HAVE_POSIX_SYSTEM]: Add support of DOTLOCK_LOCK_BY_PARENT and DOTLOCK_LOCKED for dotlock CLI util. (dotlock_take_unix): Support the case of DOTLOCK_LOCK_BY_PARENT. -- Signed-off-by: NIIBE Yutaka --- common/dotlock.c | 144 +++++++++++++++++++++++++++++++++++++++++++---- common/dotlock.h | 5 +- 2 files changed, 138 insertions(+), 11 deletions(-) diff --git a/common/dotlock.c b/common/dotlock.c index 261e2cce7..f4d7243e0 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -291,6 +291,7 @@ # include # include # include +# include #endif #include #include @@ -393,6 +394,8 @@ struct dotlock_handle unsigned int locked:1; /* Lock status. */ unsigned int disable:1; /* If true, locking is disabled. */ unsigned int use_o_excl:1; /* Use open (O_EXCL) for locking. */ + unsigned int by_parent:1; /* Parent does the locking. */ + unsigned int no_write:1; /* No write to the lockfile. */ int extra_fd; /* A place for the caller to store an FD. */ @@ -679,6 +682,80 @@ use_hardlinks_p (const char *tname) #ifdef HAVE_POSIX_SYSTEM +static int +dotlock_get_process_id (dotlock_t h) +{ + return h->by_parent? (int)getppid(): (int)getpid(); +} + +static int +dotlock_detect_tname (dotlock_t h) +{ + struct stat sb; + DIR *dir; + char *dirname; + char *basename; + struct dirent *d; + int r; + + if (stat (h->lockname, &sb)) + return -1; + + basename = make_basename (h->lockname, NULL); + dirname = make_dirname (h->lockname); + + dir = opendir (dirname); + if (dir == NULL) + { + xfree (basename); + xfree (dirname); + return -1; + } + + while ((d = readdir (dir))) + if (sb.st_ino == d->d_ino && strcmp (d->d_name, basename)) + break; + + if (d) + { + int len = strlen (h->tname); + int dlen = strlen (d->d_name); + const char *tname_path; + + if (dlen > len) + { + xfree (basename); + xfree (dirname); + return -1; + } + + strcpy (stpcpy (stpcpy (h->tname, dirname), DIRSEP_S), d->d_name); + h->use_o_excl = 0; + tname_path = strchr (h->tname + strlen (dirname) + 2, '.'); + if (!tname_path) + { + xfree (basename); + xfree (dirname); + return -1; + } + h->nodename_off = tname_path - h->tname + 1; + } + else + h->use_o_excl = 1; + + r = closedir (dir); + if (r) + { + xfree (basename); + xfree (dirname); + return r; + } + + xfree (basename); + xfree (dirname); + return 0; +} + /* Locking core for Unix. It used a temporary file and the link system call to make locking an atomic operation. */ static dotlock_t @@ -691,8 +768,10 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) int dirpartlen; struct utsname utsbuf; size_t tnamelen; + int pid; - snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() ); + pid = dotlock_get_process_id (h); + snprintf (pidstr, sizeof pidstr, "%10d\n", pid); /* Create a temporary file. */ if ( uname ( &utsbuf ) ) @@ -726,10 +805,17 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) } h->nodename_len = strlen (nodename); + if (h->no_write) + { + memset (h->tname, '_', tnamelen); + h->tname[tnamelen] = 0; + goto skip_write; + } + snprintf (h->tname, tnamelen, "%.*s/.#lk%p.", dirpartlen, dirpart, h ); h->nodename_off = strlen (h->tname); snprintf (h->tname+h->nodename_off, tnamelen - h->nodename_off, - "%s.%d", nodename, (int)getpid ()); + "%s.%d", nodename, pid); do { @@ -792,6 +878,7 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) goto write_failed; } + skip_write: h->lockname = xtrymalloc (strlen (file_to_lock) + 6 ); if (!h->lockname) { @@ -807,6 +894,20 @@ dotlock_create_unix (dotlock_t h, const char *file_to_lock) strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock"); UNLOCK_all_lockfiles (); + if (h->no_write) + { + if (dotlock_detect_tname (h) < 0) + { + xfree (h->lockname); + xfree (h->tname); + xfree (h); + my_set_errno (EACCES); + return NULL; + } + + h->locked = 1; + } + return h; write_failed: @@ -914,10 +1015,15 @@ dotlock_create_w32 (dotlock_t h, const char *file_to_lock) POSIX systems a temporary file ".#lk..pid[.threadid] is used. - The only defined FLAG bit is DOTLOCK_PREPARE_CREATE, which only - allocates the handle and requires a further call to - dotlock_finish_create. This can be used to set a callback between - these calls. + FLAGS may include DOTLOCK_PREPARE_CREATE bit, which only allocates + the handle and requires a further call to dotlock_finish_create. + This can be used to set a callback between these calls. + + FLAGS may include DOTLOCK_LOCK_BY_PARENT bit, when it's the parent + process controlling the lock. This is used by dotlock util. + + FLAGS may include DOTLOCK_LOCKED bit, when it should not create the + lockfile, but to unlock. This is used by dotlock util. The function returns an new handle which needs to be released using destroy_dotlock but gets also released at the termination of the @@ -929,8 +1035,13 @@ dotlock_create (const char *file_to_lock, unsigned int flags) { static int initialized; dotlock_t h; +#ifndef HAVE_DOSISH_SYSTEM + int by_parent = 0; + int no_write = 0; +#endif - if ( !initialized ) + if ( !(flags & DOTLOCK_LOCK_BY_PARENT) + && !initialized ) { atexit (dotlock_remove_lockfiles); initialized = 1; @@ -939,6 +1050,14 @@ dotlock_create (const char *file_to_lock, unsigned int flags) if ( !file_to_lock ) return NULL; /* Only initialization was requested. */ +#ifndef HAVE_DOSISH_SYSTEM + if ((flags & DOTLOCK_LOCK_BY_PARENT) || (flags & DOTLOCK_LOCKED)) + { + by_parent = !!(flags & DOTLOCK_LOCK_BY_PARENT); + no_write = !!(flags & DOTLOCK_LOCKED); + flags &= ~(DOTLOCK_LOCK_BY_PARENT | DOTLOCK_LOCKED); + } +#endif if ((flags & ~DOTLOCK_PREPARE_CREATE)) { my_set_errno (EINVAL); @@ -949,6 +1068,10 @@ dotlock_create (const char *file_to_lock, unsigned int flags) if (!h) return NULL; h->extra_fd = -1; +#ifndef HAVE_DOSISH_SYSTEM + h->by_parent = by_parent; + h->no_write = no_write; +#endif if (never_lock) { @@ -1181,7 +1304,8 @@ dotlock_take_unix (dotlock_t h, long timeout) { char pidstr[16]; - snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid()); + snprintf (pidstr, sizeof pidstr, "%10d\n", + dotlock_get_process_id (h)); if (write (fd, pidstr, 11 ) == 11 && write (fd, h->tname + h->nodename_off,h->nodename_len) == h->nodename_len @@ -1251,7 +1375,7 @@ dotlock_take_unix (dotlock_t h, long timeout) my_info_0 ("lockfile disappeared\n"); goto again; } - else if ( (pid == getpid() && same_node) + else if ( (pid == dotlock_get_process_id (h) && same_node && !h->by_parent) || (same_node && kill (pid, 0) && errno == ESRCH) ) { /* Stale lockfile is detected. */ @@ -1460,7 +1584,7 @@ dotlock_release_unix (dotlock_t h) my_set_errno (saveerrno); return -1; } - if ( pid != getpid() || !same_node ) + if ( pid != dotlock_get_process_id (h) || !same_node ) { my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid); if (h->info_cb) diff --git a/common/dotlock.h b/common/dotlock.h index 915279176..0f52d4037 100644 --- a/common/dotlock.h +++ b/common/dotlock.h @@ -108,7 +108,10 @@ enum dotlock_reasons DOTLOCK_WAITING /* Waiting for the lock - may be terminated. */ }; -#define DOTLOCK_PREPARE_CREATE (1<<5) /* Require dotlock_finish_create. */ +/* Flags for dotlock_create. */ +#define DOTLOCK_PREPARE_CREATE (1U << 5) /* Require dotlock_finish_create. */ +#define DOTLOCK_LOCK_BY_PARENT (1U << 6) /* Used by dotlock util. */ +#define DOTLOCK_LOCKED (1U << 7) /* Used by dotlock util. */ void dotlock_disable (void); dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags); From 8eff1d4c511088ff40d5fac13c00cdd07467eebb Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 19 Dec 2023 10:04:49 +0100 Subject: [PATCH 277/869] common: Improve the parsing of gpgconf.ctl variables. * common/homedir.c (unix_rootdir): Simplify. -- This also relaxes the syntax in that the equal sign may now be surrounded by any number of spaces. --- common/homedir.c | 57 +++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/common/homedir.c b/common/homedir.c index 286685feb..641dba1ae 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -604,43 +604,40 @@ unix_rootdir (int want_sysconfdir) sysconfdir = NULL; while ((length = es_read_line (fp, &line, &linelen, NULL)) > 0) { + static const char *names[] = + { + "rootdir", + "sysconfdir", + ".enable" + }; + int i; + size_t n; + /* Strip NL and CR, if present. */ while (length > 0 && (line[length - 1] == '\n' || line[length - 1] == '\r')) line[--length] = 0; trim_spaces (line); - if (!strncmp (line, "rootdir=", 8)) + /* Find the stamement. */ + name = NULL; + for (i=0; i < DIM (names); i++) { - name = "rootdir"; - p = line + 8; + n = strlen (names[i]); + if (!strncmp (line, names[i], n)) + { + while (line[n] == ' ' || line[n] == '\t') + n++; + if (line[n] == '=') + { + name = names[i]; + p = line + n + 1; + break; + } + } } - else if (!strncmp (line, "rootdir =", 9)) /* (What a kludge) */ - { - name = "rootdir"; - p = line + 9; - } - else if (!strncmp (line, "sysconfdir=", 11)) - { - name = "sysconfdir"; - p = line + 11; - } - else if (!strncmp (line, "sysconfdir =", 12)) /* (What a kludge) */ - { - name = "sysconfdir"; - p = line + 12; - } - else if (!strncmp (line, ".enable=", 8)) - { - name = ".enable"; - p = line + 8; - } - else if (!strncmp (line, ".enable =", 9)) - { - name = ".enable"; - p = line + 9; - } - else - continue; + if (!name) + continue; /* Statement not known. */ + trim_spaces (p); p = substitute_envvars (p); if (!p) From 5488ad0517422b31a7be46a7575f5f5492e9fee1 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 20 Dec 2023 10:28:02 +0900 Subject: [PATCH 278/869] common: Fix a possible resource leak for dotlock. * common/dotlock.c (dotlock_destroy_unix): Don't release ->TNAME here. (dotlock_destroy): Release the memory unconditionally. -- Signed-off-by: NIIBE Yutaka --- common/dotlock.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/common/dotlock.c b/common/dotlock.c index f4d7243e0..06e3910ad 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -1155,7 +1155,6 @@ dotlock_destroy_unix (dotlock_t h) unlink (h->lockname); if (h->tname && !h->use_o_excl) unlink (h->tname); - xfree (h->tname); } #endif /*HAVE_POSIX_SYSTEM*/ @@ -1208,8 +1207,12 @@ dotlock_destroy (dotlock_t h) #else /* !HAVE_DOSISH_SYSTEM */ dotlock_destroy_unix (h); #endif /* HAVE_DOSISH_SYSTEM */ - xfree (h->lockname); } + +#ifdef HAVE_POSIX_SYSTEM + xfree (h->tname); +#endif + xfree (h->lockname); xfree(h); } From 2f6fec3f482d3a6660ce9bf299c0ff7fae21b80b Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 20 Dec 2023 10:38:08 +0900 Subject: [PATCH 279/869] common: Support not-removing the lockfile by dotlock_destroy. * common/dotlock.c (dotlock_destroy): Keep the lock when DOTLOCK_LOCK_BY_PARENT. -- Signed-off-by: NIIBE Yutaka --- common/dotlock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/dotlock.c b/common/dotlock.c index 06e3910ad..84d0b509c 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -1200,8 +1200,11 @@ dotlock_destroy (dotlock_t h) UNLOCK_all_lockfiles (); /* Then destroy the lock. */ - if (!h->disable) + if (!h->disable + && (!h->by_parent || h->no_write)) { + /* NOTE: under the condition of (by_parent && !no_write), + it doesn't come here. So, the lock file remains. */ #ifdef HAVE_DOSISH_SYSTEM dotlock_destroy_w32 (h); #else /* !HAVE_DOSISH_SYSTEM */ From b298322d36d4fc9a8d86515410e1d3f2cddea19f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 20 Dec 2023 10:53:50 +0900 Subject: [PATCH 280/869] common: Clean up the temporary file at dotlock_destroy. * common/dotlock.c (dotlock_destroy): Clean up the temporary file created when it fails. -- Signed-off-by: NIIBE Yutaka --- common/dotlock.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/dotlock.c b/common/dotlock.c index 84d0b509c..fe6d7fe71 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -1213,6 +1213,12 @@ dotlock_destroy (dotlock_t h) } #ifdef HAVE_POSIX_SYSTEM + /* When DOTLOCK_LOCK_BY_PARENT and lock fails, + the temporary file created should be removed. */ + if (h->by_parent && !h->no_write && !h->locked) + if (h->tname && !h->use_o_excl) + unlink (h->tname); + xfree (h->tname); #endif xfree (h->lockname); From 1f04993cd0acaf6fb4982e822f8d8b5722197e03 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 20 Dec 2023 10:55:26 +0900 Subject: [PATCH 281/869] common: Add dotlock util under libexec. * tools/Makefile.am (libexec_PROGRAMS): Add dotlock. * tools/dotlock.c: Finish the first implementation. -- Signed-off-by: NIIBE Yutaka --- tools/Makefile.am | 8 ++++- tools/dotlock.c | 88 +++++++++++++++++++++++++++++++---------------- 2 files changed, 65 insertions(+), 31 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index 769a81a00..b813f55f9 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -69,7 +69,7 @@ else bin_PROGRAMS += gpgconf-w32 endif -libexec_PROGRAMS = gpg-check-pattern gpg-pair-tool +libexec_PROGRAMS = gpg-check-pattern gpg-pair-tool dotlock if !HAVE_W32_SYSTEM libexec_PROGRAMS += gpg-auth endif @@ -203,6 +203,12 @@ gpg_auth_LDADD = $(common_libs) \ $(GPG_ERROR_LIBS) \ $(LIBINTL) $(NETLIBS) $(LIBICONV) +dotlock_SOURCES = dotlock.c +dotlock_LDADD = $(common_libs) \ + $(LIBGCRYPT_LIBS) \ + $(GPG_ERROR_LIBS) \ + $(LIBINTL) $(NETLIBS) $(LIBICONV) + # Instead of a symlink we install a simple wrapper script for the new # gpg-wks-client location. We assume bin is a sibling of libexec. install-exec-local: diff --git a/tools/dotlock.c b/tools/dotlock.c index 27ae5205b..3dfb86c80 100644 --- a/tools/dotlock.c +++ b/tools/dotlock.c @@ -1,4 +1,4 @@ -/* dotlock.c - Command to handle dotlock. +/* dotlock.c - A utility to handle dotlock by command line. * Copyright (C) 2023 g10 Code GmbH * * This file is part of GnuPG. @@ -25,63 +25,91 @@ #include #include #include -#include #include -#ifdef HAVE_W32_SYSTEM -# include "windows.h" -#else -#include -#endif -#include "dotlock.h" +#include +#include "../common/util.h" +#include "../common/stringhelp.h" +#include "../common/dotlock.h" static void -lock (const char *fname) +lock (const char *filename) { dotlock_t h; - unsigned int flags = DOTLOCK_FLAG_LOCK_BY_PARENT; + unsigned int flags = DOTLOCK_LOCK_BY_PARENT; - h = dotlock_create (fname, flags); + h = dotlock_create (filename, flags); if (!h) - die ("error creating lock file for '%s': %s", fname, strerror (errno)); + { + perror ("error creating lock file"); + exit (1); + } if (dotlock_take (h, 0)) - die ("error taking lock"); + { + perror ("error taking lock"); + dotlock_destroy (h); + exit (1); + } + + dotlock_destroy (h); } static void -unlock (const char *fname, long timeout) +unlock (const char *filename) { dotlock_t h; - unsigned int flags = (DOTLOCK_FLAG_LOCK_BY_PARENT - | DOTLOCK_FLAG_READONLY); + unsigned int flags = (DOTLOCK_LOCK_BY_PARENT | DOTLOCK_LOCKED); - h = dotlock_create (fname, flags); + h = dotlock_create (filename, flags); if (!h) - die ("error creating lock file for '%s': %s", fname, strerror (errno)); + { + perror ("no lock file"); + exit (1); + } + dotlock_release (h); dotlock_destroy (h); } int -main (int argc, char **argv) +main (int argc, const char *argv[]) { + const char *name; const char *fname; + char *filename; + int op_unlock = 0; - fname = argv[argc-1]; + if (argc >= 2 && !strcmp (argv[1], "-u")) + { + op_unlock = 1; + argc--; + argv++; + } - if () - lock (fname); + if (argc != 2) + { + printf ("Usage: %s [-u] NAME\n", argv[0]); + exit (1); + } + + name = argv[1]; + + if (!strcmp (name, "pubring.db")) + /* Keybox pubring.db lock */ + fname = "public-keys.d/pubring.db"; else - unlock (fname); + /* Other locks. */ + fname = name; + filename = make_absfilename (gnupg_homedir (), fname, NULL); + + if (op_unlock) + unlock (filename); + else + lock (filename); + + xfree (filename); return 0; } - - -/* -Local Variables: -compile-command: "cc -Wall -O2 -D_FILE_OFFSET_BITS=64 -o t-dotlock t-dotlock.c" -End: -*/ From 93b5ba38dc3acc78fd93af7dcad22332af32f724 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 20 Dec 2023 11:00:22 +0900 Subject: [PATCH 282/869] tools: Integrate the dotlock tool into gpgconf. * tools/gpgconf.c (dotlock_tool): New. (main): Add --lock and --unlock commands. -- Signed-off-by: NIIBE Yutaka --- tools/gpgconf.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index f34248c40..76bdebf1a 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -34,6 +34,7 @@ #include "../common/init.h" #include "../common/status.h" #include "../common/exechelp.h" +#include "../common/dotlock.h" #ifdef HAVE_W32_SYSTEM #include @@ -76,7 +77,9 @@ enum cmd_and_opt_values aCreateSocketDir, aRemoveSocketDir, aApplyProfile, - aShowCodepages + aShowCodepages, + aDotlockLock, + aDotlockUnlock }; @@ -109,7 +112,10 @@ static gpgrt_opt_t opts[] = { aRemoveSocketDir, "remove-socketdir", 256, "@"}, ARGPARSE_c (aShowVersions, "show-versions", ""), ARGPARSE_c (aShowConfigs, "show-configs", ""), + /* hidden commands: for debugging */ ARGPARSE_c (aShowCodepages, "show-codepages", "@"), + ARGPARSE_c (aDotlockLock, "lock", "@"), + ARGPARSE_c (aDotlockUnlock, "unlock", "@"), { 301, NULL, 0, N_("@\nOptions:\n ") }, @@ -604,6 +610,41 @@ query_swdb (estream_t out, const char *name, const char *current_version) } +#if !defined(HAVE_W32_SYSTEM) +/* dotlock tool to handle dotlock by command line + DO_LOCK: 1 for to lock, 0 for unlock + FILENAME: filename for the dotlock */ +static void +dotlock_tool (int do_lock, const char *filename) +{ + dotlock_t h; + unsigned int flags = DOTLOCK_LOCK_BY_PARENT; + + if (!do_lock) + flags |= DOTLOCK_LOCKED; + + h = dotlock_create (filename, flags); + if (!h) + { + if (do_lock) + log_error ("error creating the lock file\n"); + else + log_error ("no lock file found\n"); + return; + } + + if (do_lock) + { + if (dotlock_take (h, 0)) + log_error ("error taking the lock\n"); + } + else + dotlock_release (h); + + dotlock_destroy (h); +} +#endif + /* gpgconf main. */ int main (int argc, char **argv) @@ -669,6 +710,8 @@ main (int argc, char **argv) case aShowVersions: case aShowConfigs: case aShowCodepages: + case aDotlockLock: + case aDotlockUnlock: cmd = pargs.r_opt; break; @@ -1024,7 +1067,32 @@ main (int argc, char **argv) #endif break; + case aDotlockLock: + case aDotlockUnlock: +#if !defined(HAVE_W32_SYSTEM) + if (!fname) + { + es_fprintf (es_stderr, "usage: %s [options] lock|unlock NAME", + GPGCONF_NAME); + es_putc ('\n', es_stderr); + es_fputs (_("Need one NAME argument"), es_stderr); + es_putc ('\n', es_stderr); + gpgconf_failure (GPG_ERR_USER_2); + } + else + { + char *filename; + /* Keybox pubring.db lock is under public-keys.d. */ + if (!strcmp (fname, "pubring.db")) + fname = "public-keys.d/pubring.db"; + + filename = make_absfilename (gnupg_homedir (), fname, NULL); + dotlock_tool (cmd == aDotlockLock, filename); + xfree (filename); + } +#endif + break; } if (outfp != es_stdout) From 4dd4e9d2f1ac0d2a2add41e0e7ad2b328c117d55 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 20 Dec 2023 16:13:49 +0900 Subject: [PATCH 283/869] agent: Fix homedir check wrt --disable-check-own-socket option. * agent/gpg-agent.c (handle_connections): Don't disable use of inotify when it has the --disable-check-own-socket option. -- Before the fix, it checks the homedir using the gnupg_stat function when --disable-check-own-socket is enabled, without trying use of inotify. Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index b7863cbbe..185957a0f 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -345,7 +345,7 @@ static struct debug_flags_s debug_flags [] = * in standard socket mode. If that value is 0 we don't check at all. * Values is in seconds. */ #define CHECK_OWN_SOCKET_INTERVAL (60) -/* CHECK_PROBLEMS_INTERFAL defines how often we check the existence of +/* CHECK_PROBLEMS_INTERVAL defines how often we check the existence of * parent process and homedir. Value is in seconds. */ #define CHECK_PROBLEMS_INTERVAL (4) @@ -3042,10 +3042,8 @@ handle_connections (gnupg_fd_t listen_fd, gpg_strerror (err)); } - if (disable_check_own_socket) - home_inotify_fd = -1; - else if ((err = gnupg_inotify_watch_delete_self (&home_inotify_fd, - gnupg_homedir ()))) + if ((err = gnupg_inotify_watch_delete_self (&home_inotify_fd, + gnupg_homedir ()))) { if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) log_info ("error enabling daemon termination by homedir removal: %s\n", From 5d651fc8fd47d6e9193fb904abd0fb4bb1815911 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 20 Dec 2023 15:30:37 +0100 Subject: [PATCH 284/869] doc: Explain what to put into mailcap for gpg-wks-client. -- --- doc/wks.texi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/doc/wks.texi b/doc/wks.texi index 26d8b96f6..a8d0455e5 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -243,6 +243,21 @@ Display a brief help page and exit. @end table +@noindent +@mansect examples +@chapheading Examples + +To use the services with clients lacking integrated support, the +mailcap mechanism can be used. Simply put: +@example +application/vnd.gnupg.wks; \ + @value{BINDIR}/gpg-wks-client -v --read --send; \ + needsterminal; \ + description=WKS message +@end example +into the @file{/etc/mailcap}. This assumes that a /usr/lib/sendmail +is installed. With this configuration any real mail programs will run +gpg-wks-client for messages received from a Web Key Service. @mansect see also @ifset isman From 812f9880591e54601d0fb32f5832e6c5029358be Mon Sep 17 00:00:00 2001 From: Mario Haustein via Gnupg-devel Date: Tue, 28 Nov 2023 23:09:21 +0100 Subject: [PATCH 285/869] scd:p15: Add support for CardOS 5.4 * scd/app-p15.c (CARD_TYPE_CARDOS_54): New. --- scd/app-p15.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 85c28d9a7..a10053d5a 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -74,6 +74,7 @@ typedef enum CARD_TYPE_MICARDO, CARD_TYPE_CARDOS_50, CARD_TYPE_CARDOS_53, + CARD_TYPE_CARDOS_54, CARD_TYPE_AET, /* A.E.T. Europe JCOP card. */ CARD_TYPE_BELPIC, /* Belgian eID card specs. */ CARD_TYPE_STARCOS_32 @@ -124,6 +125,8 @@ static struct CARD_TYPE_CARDOS_50 }, /* CardOS 5.0 */ { 11, X("\x3b\xd2\x18\x00\x81\x31\xfe\x58\xc9\x03\x16"), CARD_TYPE_CARDOS_53 }, /* CardOS 5.3 */ + { 11, X("\x3b\xd2\x18\x00\x81\x31\xfe\x58\xc9\x04\x11"), + CARD_TYPE_CARDOS_54 }, /* CardOS 5.4 */ { 24, X("\x3b\xfe\x18\x00\x00\x80\x31\xfe\x45\x53\x43\x45" "\x36\x30\x2d\x43\x44\x30\x38\x31\x2d\x6e\x46\xa9"), CARD_TYPE_AET }, @@ -135,9 +138,10 @@ static struct #undef X -/* Macro to test for CardOS 5.0 and 5.3. */ +/* Macro to test for CardOS 5.0, 5.3 and 5.4. */ #define IS_CARDOS_5(a) ((a)->app_local->card_type == CARD_TYPE_CARDOS_50 \ - || (a)->app_local->card_type == CARD_TYPE_CARDOS_53) + || (a)->app_local->card_type == CARD_TYPE_CARDOS_53 \ + || (a)->app_local->card_type == CARD_TYPE_CARDOS_54) /* The default PKCS-15 home DF */ #define DEFAULT_HOME_DF 0x5015 @@ -542,6 +546,7 @@ cardtype2str (card_type_t cardtype) case CARD_TYPE_MICARDO: return "Micardo"; case CARD_TYPE_CARDOS_50: return "CardOS 5.0"; case CARD_TYPE_CARDOS_53: return "CardOS 5.3"; + case CARD_TYPE_CARDOS_54: return "CardOS 5.4"; case CARD_TYPE_BELPIC: return "Belgian eID"; case CARD_TYPE_AET: return "AET"; case CARD_TYPE_STARCOS_32:return "STARCOS 3.2"; @@ -6302,6 +6307,7 @@ app_select_p15 (app_t app) { case CARD_TYPE_CARDOS_50: case CARD_TYPE_CARDOS_53: + case CARD_TYPE_CARDOS_54: direct = 1; break; case CARD_TYPE_AET: From 0b85a9ac09d1593d472ac6f2f51af7608b0dd617 Mon Sep 17 00:00:00 2001 From: Mario Haustein via Gnupg-devel Date: Tue, 28 Nov 2023 23:09:26 +0100 Subject: [PATCH 286/869] scd:p15: Add support for D-Trust Card 4.1/4.4 * scd/app-p15.c (CARD_PRODUCT_DTRUST4) New. (app_select_p15): This cards uses a different AID for PKCS#15 application (do_sign): The card doesn't support MSE SET, but requires MSE RESTORE to a predefined template. (do_decipher): Ditto. --- scd/app-p15.c | 80 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index a10053d5a..1ff4f47c7 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -88,7 +88,8 @@ typedef enum { CARD_PRODUCT_UNKNOWN, CARD_PRODUCT_RSCS, /* Rohde&Schwarz Cybersecurity */ - CARD_PRODUCT_DTRUST, /* D-Trust GmbH (bundesdruckerei.de) */ + CARD_PRODUCT_DTRUST3, /* D-Trust GmbH (bundesdruckerei.de) */ + CARD_PRODUCT_DTRUST4, CARD_PRODUCT_GENUA, /* GeNUA mbH */ CARD_PRODUCT_NEXUS /* Technology Nexus */ } @@ -155,6 +156,11 @@ static char const pkcs15_aid[] = { 0xA0, 0, 0, 0, 0x63, static char const pkcs15be_aid[] = { 0xA0, 0, 0, 0x01, 0x77, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 }; +/* The D-TRUST Card 4.x variant - dito */ +static char const pkcs15dtrust4_aid[] = { 0xE8, 0x28, 0xBD, 0x08, 0x0F, 0xA0, + 0x00, 0x00, 0x01, 0x67, 0x45, 0x53, + 0x49, 0x47, 0x4E }; + /* The PIN types as defined in pkcs#15 v1.1 */ typedef enum @@ -561,7 +567,8 @@ cardproduct2str (card_product_t cardproduct) { case CARD_PRODUCT_UNKNOWN: return ""; case CARD_PRODUCT_RSCS: return "R&S"; - case CARD_PRODUCT_DTRUST: return "D-Trust"; + case CARD_PRODUCT_DTRUST3: return "D-Trust 3"; + case CARD_PRODUCT_DTRUST4: return "D-Trust 4.1/4.4"; case CARD_PRODUCT_GENUA: return "GeNUA"; case CARD_PRODUCT_NEXUS: return "Nexus"; } @@ -3511,7 +3518,7 @@ read_ef_tokeninfo (app_t app) ul |= (*p++) & 0xff; n--; } - if (ul) + if (ul > 1) { log_error ("p15: invalid version %lu in TokenInfo\n", ul); err = gpg_error (GPG_ERR_INV_OBJ); @@ -3845,7 +3852,14 @@ read_p15_info (app_t app) && !strncmp (app->app_local->token_label, "D-TRUST Card V3", 15) && app->app_local->card_type == CARD_TYPE_CARDOS_50) { - app->app_local->card_product = CARD_PRODUCT_DTRUST; + app->app_local->card_product = CARD_PRODUCT_DTRUST3; + } + if (!app->app_local->card_product + && app->app_local->token_label + && !strncmp (app->app_local->token_label, "D-TRUST Card 4.", 15) + && app->app_local->card_type == CARD_TYPE_CARDOS_54) + { + app->app_local->card_product = CARD_PRODUCT_DTRUST4; } @@ -5023,7 +5037,7 @@ prepare_verify_pin (app_t app, const char *keyref, } - if (app->app_local->card_product == CARD_PRODUCT_DTRUST) + if (app->app_local->card_product == CARD_PRODUCT_DTRUST3) { /* According to our protocol analysis we need to select a * special AID here. Before that the master file needs to be @@ -5281,7 +5295,8 @@ verify_pin (app_t app, if (prkdf && prkdf->usageflags.non_repudiation && (app->app_local->card_type == CARD_TYPE_BELPIC - || app->app_local->card_product == CARD_PRODUCT_DTRUST)) + || app->app_local->card_product == CARD_PRODUCT_DTRUST3 + || app->app_local->card_product == CARD_PRODUCT_DTRUST4)) label = _("||Please enter the PIN for the key to create " "qualified signatures."); else if (aodf->pinflags.so_pin) @@ -5645,7 +5660,8 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, goto leave; } if (app->app_local->card_type == CARD_TYPE_BELPIC - || app->app_local->card_product == CARD_PRODUCT_NEXUS) + || app->app_local->card_product == CARD_PRODUCT_NEXUS + || app->app_local->card_product == CARD_PRODUCT_DTRUST4) { /* The default for these cards is to use a plain hash. We * assume that due to the used certificate the correct hash @@ -5731,6 +5747,30 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, else err = micardo_mse (app, prkdf->path[prkdf->pathlen-1]); } + else if (app->app_local->card_product == CARD_PRODUCT_DTRUST4) + { + if (prkdf->is_ecc) + { + /* Not implemented due to lacking test hardware. */ + err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + } + else + { + /* The D-TRUST Card 4.x doesn't support setting a security + * environment, at least as specified in the specs. Insted a + * predefined security environment has to be loaded depending on the + * cipher and message digest used. The spec states SE-ID 0x25 for + * SHA256, 0x26 for SHA384 and 0x27 for SHA512, when using PKCS#1 + * padding. But this matters only if the message digest is computed + * on the card. When providing the digest info and a pre-calculated + * hash, all security environments yield the same result. Thus we + * choose 0x25. + * + * Note: For PSS signatures, different values apply. */ + err = iso7816_manage_security_env (app_get_slot (app), + 0xf3, 0x25, NULL, 0); + } + } else if (prkdf->key_reference_valid) { unsigned char mse[3]; @@ -5886,7 +5926,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, /* The next is guess work for CardOS. */ - if (app->app_local->card_product == CARD_PRODUCT_DTRUST) + if (app->app_local->card_product == CARD_PRODUCT_DTRUST3) { /* From analyzing an USB trace of a Windows signing application * we see that the SE is simply reset to 0x14. It seems to be @@ -5903,6 +5943,21 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, 0xF3, 0x14, NULL, 0); } + else if (app->app_local->card_product == CARD_PRODUCT_DTRUST4) + { + if (prkdf->is_ecc) + { + /* Not implemented due to lacking test hardware. */ + err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + } + else + { + /* SE-ID 0x31 is for PKCS#1 padded cryptograms. For OAEP encryption + * schemes, different values apply. */ + err = iso7816_manage_security_env (app_get_slot (app), + 0xF3, 0x31, NULL, 0); + } + } else if (prkdf->key_reference_valid) { unsigned char mse[9]; @@ -5946,7 +6001,8 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, le_value = prkdf->keynbits / 8; } - if (app->app_local->card_product == CARD_PRODUCT_DTRUST) + if (app->app_local->card_product == CARD_PRODUCT_DTRUST3 + || app->app_local->card_product == CARD_PRODUCT_DTRUST4) padind = 0x81; if (prkdf->is_ecc && IS_CARDOS_5(app)) @@ -6208,6 +6264,12 @@ app_select_p15 (app_t app) rc = iso7816_select_application_ext (slot, pkcs15_aid, sizeof pkcs15_aid, 1, &fci, &fcilen); + if (rc) + { + /* D-TRUST Card 4.x uses a different AID. */ + rc = iso7816_select_application_ext (slot, pkcs15dtrust4_aid, sizeof pkcs15dtrust4_aid, 1, + &fci, &fcilen); + } if (rc) { /* Not found: Try to locate it from 2F00. We use direct path selection here because it seems that the Belgian eID card From f2904737e5594676fdc5f1cadf3cc52621bc901a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 20 Dec 2023 16:52:47 +0100 Subject: [PATCH 287/869] scd:p15: Add a diagnostic for unsupported DTRUST4 features. * scd/app-p15.c (do_sign): Add a diagnostic. --- scd/app-p15.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 1ff4f47c7..8edd737a6 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -5752,6 +5752,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, if (prkdf->is_ecc) { /* Not implemented due to lacking test hardware. */ + log_info ("Note: ECC is not yet implemented for DTRUST 4 cards\n"); err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); } else @@ -5948,6 +5949,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, if (prkdf->is_ecc) { /* Not implemented due to lacking test hardware. */ + log_info ("Note: ECC is not yet implemented for DTRUST 4 cards\n"); err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); } else @@ -6267,7 +6269,8 @@ app_select_p15 (app_t app) if (rc) { /* D-TRUST Card 4.x uses a different AID. */ - rc = iso7816_select_application_ext (slot, pkcs15dtrust4_aid, sizeof pkcs15dtrust4_aid, 1, + rc = iso7816_select_application_ext (slot, pkcs15dtrust4_aid, + sizeof pkcs15dtrust4_aid, 1, &fci, &fcilen); } if (rc) From 91255c3afd3365a092963044881b30e8e6cc7f33 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 21 Dec 2023 12:35:55 +0900 Subject: [PATCH 288/869] tools: Remove the dotlock tool. * tools/Makefile.am (libexec_PROGRAMS): Remove dotlock. * tools/dotlock.c: Remove. -- It's integrated into gpgconf (--lock/--unlock). Signed-off-by: NIIBE Yutaka --- tools/Makefile.am | 8 +--- tools/dotlock.c | 115 ---------------------------------------------- 2 files changed, 1 insertion(+), 122 deletions(-) delete mode 100644 tools/dotlock.c diff --git a/tools/Makefile.am b/tools/Makefile.am index b813f55f9..769a81a00 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -69,7 +69,7 @@ else bin_PROGRAMS += gpgconf-w32 endif -libexec_PROGRAMS = gpg-check-pattern gpg-pair-tool dotlock +libexec_PROGRAMS = gpg-check-pattern gpg-pair-tool if !HAVE_W32_SYSTEM libexec_PROGRAMS += gpg-auth endif @@ -203,12 +203,6 @@ gpg_auth_LDADD = $(common_libs) \ $(GPG_ERROR_LIBS) \ $(LIBINTL) $(NETLIBS) $(LIBICONV) -dotlock_SOURCES = dotlock.c -dotlock_LDADD = $(common_libs) \ - $(LIBGCRYPT_LIBS) \ - $(GPG_ERROR_LIBS) \ - $(LIBINTL) $(NETLIBS) $(LIBICONV) - # Instead of a symlink we install a simple wrapper script for the new # gpg-wks-client location. We assume bin is a sibling of libexec. install-exec-local: diff --git a/tools/dotlock.c b/tools/dotlock.c deleted file mode 100644 index 3dfb86c80..000000000 --- a/tools/dotlock.c +++ /dev/null @@ -1,115 +0,0 @@ -/* dotlock.c - A utility to handle dotlock by command line. - * Copyright (C) 2023 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 . - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include "../common/util.h" -#include "../common/stringhelp.h" -#include "../common/dotlock.h" - -static void -lock (const char *filename) -{ - dotlock_t h; - unsigned int flags = DOTLOCK_LOCK_BY_PARENT; - - h = dotlock_create (filename, flags); - if (!h) - { - perror ("error creating lock file"); - exit (1); - } - - if (dotlock_take (h, 0)) - { - perror ("error taking lock"); - dotlock_destroy (h); - exit (1); - } - - dotlock_destroy (h); -} - -static void -unlock (const char *filename) -{ - dotlock_t h; - unsigned int flags = (DOTLOCK_LOCK_BY_PARENT | DOTLOCK_LOCKED); - - h = dotlock_create (filename, flags); - if (!h) - { - perror ("no lock file"); - exit (1); - } - - dotlock_release (h); - dotlock_destroy (h); -} - - -int -main (int argc, const char *argv[]) -{ - const char *name; - const char *fname; - char *filename; - int op_unlock = 0; - - if (argc >= 2 && !strcmp (argv[1], "-u")) - { - op_unlock = 1; - argc--; - argv++; - } - - if (argc != 2) - { - printf ("Usage: %s [-u] NAME\n", argv[0]); - exit (1); - } - - name = argv[1]; - - if (!strcmp (name, "pubring.db")) - /* Keybox pubring.db lock */ - fname = "public-keys.d/pubring.db"; - else - /* Other locks. */ - fname = name; - - filename = make_absfilename (gnupg_homedir (), fname, NULL); - - if (op_unlock) - unlock (filename); - else - lock (filename); - - xfree (filename); - return 0; -} From 853f36e596316bf540c74f52b25fe5a5eda01d8a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 21 Dec 2023 11:50:16 +0100 Subject: [PATCH 289/869] Register DCO for Mario Haustein -- --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index bd1d528e3..df4e1ec39 100644 --- a/AUTHORS +++ b/AUTHORS @@ -220,6 +220,9 @@ Jussi Kivilinna Kyle Butt 2013-05-29:CAAODAYLbCtqOG6msLLL0UTdASKWT6u2ptxsgUQ1JpusBESBoNQ@mail.gmail.com: +Mario Haustein +2022-09026:8149069.T7Z3S40VBb@localdomain: + Michael Haubenwallner 2018-07-13:c397e637-f1ce-34f0-7e6a-df04a76e1c35@ssi-schaefer.com: From 2376cdff1318688d94c95fd01adc4b2139c4a8c7 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 22 Dec 2023 13:32:40 +0900 Subject: [PATCH 290/869] scd:openpgp: Add the length check for new PIN. * scd/app-openpgp.c (do_change_pin): Make sure new PIN length is longer than MINLEN. -- GnuPG-bug-id: 6843 Signed-off-by: NIIBE Yutaka --- scd/app-openpgp.c | 48 +++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 3e77f8540..3bc709602 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -3499,6 +3499,31 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, log_error (_("error getting new PIN: %s\n"), gpg_strerror (rc)); goto leave; } + + if (set_resetcode) + { + size_t bufferlen = strlen (pinvalue); + + if (bufferlen != 0 && bufferlen < 8) + { + log_error (_("Reset Code is too short; minimum length is %d\n"), 8); + rc = gpg_error (GPG_ERR_BAD_RESET_CODE); + goto leave; + } + } + else + { + if (chvno == 3) + minlen = 8; + + if (strlen (pinvalue) < minlen) + { + log_info (_("PIN for CHV%d is too short;" + " minimum length is %d\n"), chvno, minlen); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; + } + } } @@ -3533,24 +3558,15 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, } else if (set_resetcode) { - size_t bufferlen = strlen (pinvalue); + size_t bufferlen; + char *buffer = NULL; - if (bufferlen != 0 && bufferlen < 8) - { - log_error (_("Reset Code is too short; minimum length is %d\n"), 8); - rc = gpg_error (GPG_ERR_BAD_RESET_CODE); - } - else - { - char *buffer = NULL; + rc = pin2hash_if_kdf (app, 0, pinvalue, &buffer, &bufferlen); + if (!rc) + rc = iso7816_put_data (app_get_slot (app), + 0, 0xD3, buffer, bufferlen); - rc = pin2hash_if_kdf (app, 0, pinvalue, &buffer, &bufferlen); - if (!rc) - rc = iso7816_put_data (app_get_slot (app), - 0, 0xD3, buffer, bufferlen); - - wipe_and_free (buffer, bufferlen); - } + wipe_and_free (buffer, bufferlen); } else if (reset_mode) { From 239c1fdc28dcd0dc7aa5341be7c966da2231642a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 22 Dec 2023 12:47:39 +0100 Subject: [PATCH 291/869] common: Add keyword socketdir to gpgconf.ctl * common/homedir.c (enum wantdir_values): New enums. (unix_rootdir): Change arg to use the enums. Adjust all callers. Add support for the socketdir keyword. (_gnupg_socketdir_internal): Take care of the socketdir keyword in gpgconf.ctl. * doc/tools.texi (Files used by gpgconf): Briefly explain the gpgconf.ctl syntax. --- common/homedir.c | 139 +++++++++++++++++++++++++++++-------------- doc/opt-homedir.texi | 10 ---- doc/tools.texi | 28 ++++++++- 3 files changed, 120 insertions(+), 57 deletions(-) diff --git a/common/homedir.c b/common/homedir.c index 641dba1ae..2b99c9bdc 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -77,6 +77,14 @@ #endif +/* Mode flags for unix_rootdir. */ +enum wantdir_values { + WANTDIR_ROOT = 0, + WANTDIR_SYSCONF, + WANTDIR_SOCKET +}; + + /* The GnuPG homedir. This is only accessed by the functions * gnupg_homedir and gnupg_set_homedir. Malloced. */ static char *the_gnupg_homedir; @@ -491,11 +499,12 @@ w32_rootdir (void) * file system. If WANT_SYSCONFDIR is true the optional sysconfdir * entry is returned. */ static const char * -unix_rootdir (int want_sysconfdir) +unix_rootdir (enum wantdir_values wantdir) { static int checked; static char *dir; /* for the rootdir */ static char *sdir; /* for the sysconfdir */ + static char *s2dir; /* for the socketdir */ if (!checked) { @@ -510,8 +519,10 @@ unix_rootdir (int want_sysconfdir) estream_t fp; char *rootdir; char *sysconfdir; + char *socketdir; const char *name; int ignoreall = 0; + int okay; for (;;) { @@ -602,12 +613,14 @@ unix_rootdir (int want_sysconfdir) linelen = 0; rootdir = NULL; sysconfdir = NULL; + socketdir = NULL; while ((length = es_read_line (fp, &line, &linelen, NULL)) > 0) { static const char *names[] = { "rootdir", "sysconfdir", + "socketdir", ".enable" }; int i; @@ -662,6 +675,11 @@ unix_rootdir (int want_sysconfdir) xfree (sysconfdir); sysconfdir = p; } + else if (!strcmp (name, "socketdir")) + { + xfree (socketdir); + socketdir = p; + } else { xfree (rootdir); @@ -677,6 +695,7 @@ unix_rootdir (int want_sysconfdir) xfree (line); xfree (rootdir); xfree (sysconfdir); + xfree (socketdir); checked = 1; return NULL; } @@ -684,29 +703,26 @@ unix_rootdir (int want_sysconfdir) xfree (buffer); xfree (line); + okay = 0; if (ignoreall) - { - xfree (rootdir); - xfree (sysconfdir); - sdir = dir = NULL; - } + ; else if (!rootdir || !*rootdir || *rootdir != '/') { log_info ("invalid rootdir '%s' specified in gpgconf.ctl\n", rootdir); - xfree (rootdir); - xfree (sysconfdir); - dir = NULL; } else if (sysconfdir && (!*sysconfdir || *sysconfdir != '/')) { log_info ("invalid sysconfdir '%s' specified in gpgconf.ctl\n", sysconfdir); - xfree (rootdir); - xfree (sysconfdir); - dir = NULL; + } + else if (socketdir && (!*socketdir || *socketdir != '/')) + { + log_info ("invalid socketdir '%s' specified in gpgconf.ctl\n", + socketdir); } else { + okay = 1; while (*rootdir && rootdir[strlen (rootdir)-1] == '/') rootdir[strlen (rootdir)-1] = 0; dir = rootdir; @@ -720,11 +736,34 @@ unix_rootdir (int want_sysconfdir) gpgrt_annotate_leaked_object (sdir); /* log_info ("want sysconfdir '%s'\n", sdir); */ } + if (socketdir) + { + while (*socketdir && socketdir[strlen (socketdir)-1] == '/') + socketdir[strlen (socketdir)-1] = 0; + s2dir = socketdir; + gpgrt_annotate_leaked_object (s2dir); + /* log_info ("want socketdir '%s'\n", s2dir); */ + } + } + + if (!okay) + { + xfree (rootdir); + xfree (sysconfdir); + xfree (socketdir); + dir = sdir = s2dir = NULL; } checked = 1; } - return want_sysconfdir? sdir : dir; + switch (wantdir) + { + case WANTDIR_ROOT: return dir; + case WANTDIR_SYSCONF: return sdir; + case WANTDIR_SOCKET: return s2dir; + } + + return NULL; /* Not reached. */ } #endif /* Unix */ @@ -1035,7 +1074,8 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info) }; int i; struct stat sb; - char prefix[19 + 1 + 20 + 6 + 1]; + char prefixbuffer[19 + 1 + 20 + 6 + 1]; + const char *prefix; const char *s; char *name = NULL; @@ -1050,35 +1090,42 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info) * as a background process with no (desktop) user logged in. Thus * we better don't do that. */ - /* Check whether we have a /run/[gnupg/]user dir. */ - for (i=0; bases[i]; i++) + prefix = unix_rootdir (WANTDIR_SOCKET); + if (!prefix) { - snprintf (prefix, sizeof prefix, "%s/user/%u", - bases[i], (unsigned int)getuid ()); - if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode)) - break; - } - if (!bases[i]) - { - *r_info |= 2; /* No /run/user directory. */ - goto leave; + /* gpgconf.ctl does not specify a directory. Check whether we + * have the usual /run/[gnupg/]user dir. */ + for (i=0; bases[i]; i++) + { + snprintf (prefixbuffer, sizeof prefixbuffer, "%s/user/%u", + bases[i], (unsigned int)getuid ()); + prefix = prefixbuffer; + if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode)) + break; + } + if (!bases[i]) + { + *r_info |= 2; /* No /run/user directory. */ + goto leave; + } + + if (sb.st_uid != getuid ()) + { + *r_info |= 4; /* Not owned by the user. */ + if (!skip_checks) + goto leave; + } + + if (strlen (prefix) + 7 >= sizeof prefixbuffer) + { + *r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */ + goto leave; + } + strcat (prefixbuffer, "/gnupg"); } - if (sb.st_uid != getuid ()) - { - *r_info |= 4; /* Not owned by the user. */ - if (!skip_checks) - goto leave; - } - - if (strlen (prefix) + 7 >= sizeof prefix) - { - *r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */ - goto leave; - } - strcat (prefix, "/gnupg"); - - /* Check whether the gnupg sub directory has proper permissions. */ + /* Check whether the gnupg sub directory (or the specified diretory) + * has proper permissions. */ if (stat (prefix, &sb)) { if (errno != ENOENT) @@ -1238,7 +1285,7 @@ gnupg_sysconfdir (void) } return name; #else /*!HAVE_W32_SYSTEM*/ - const char *dir = unix_rootdir (1); + const char *dir = unix_rootdir (WANTDIR_SYSCONF); if (dir) return dir; else @@ -1267,7 +1314,7 @@ gnupg_bindir (void) else return rdir; #else /*!HAVE_W32_SYSTEM*/ - rdir = unix_rootdir (0); + rdir = unix_rootdir (WANTDIR_ROOT); if (rdir) { if (!name) @@ -1294,7 +1341,7 @@ gnupg_libexecdir (void) static char *name; const char *rdir; - rdir = unix_rootdir (0); + rdir = unix_rootdir (WANTDIR_ROOT); if (rdir) { if (!name) @@ -1324,7 +1371,7 @@ gnupg_libdir (void) #else /*!HAVE_W32_SYSTEM*/ const char *rdir; - rdir = unix_rootdir (0); + rdir = unix_rootdir (WANTDIR_ROOT); if (rdir) { if (!name) @@ -1355,7 +1402,7 @@ gnupg_datadir (void) #else /*!HAVE_W32_SYSTEM*/ const char *rdir; - rdir = unix_rootdir (0); + rdir = unix_rootdir (WANTDIR_ROOT); if (rdir) { if (!name) @@ -1387,7 +1434,7 @@ gnupg_localedir (void) #else /*!HAVE_W32_SYSTEM*/ const char *rdir; - rdir = unix_rootdir (0); + rdir = unix_rootdir (WANTDIR_ROOT); if (rdir) { if (!name) diff --git a/doc/opt-homedir.texi b/doc/opt-homedir.texi index 07993d29d..15ae1970d 100644 --- a/doc/opt-homedir.texi +++ b/doc/opt-homedir.texi @@ -13,13 +13,3 @@ directory stated through the environment variable @env{GNUPGHOME} or On Windows systems it is possible to install GnuPG as a portable application. In this case only this command line option is considered, all other ways to set a home directory are ignored. - -@efindex gpgconf.ctl -To install GnuPG as a portable application under Windows, create an -empty file named @file{gpgconf.ctl} in the same directory as the tool -@file{gpgconf.exe}. The root of the installation is then that -directory; or, if @file{gpgconf.exe} has been installed directly below -a directory named @file{bin}, its parent directory. You also need to -make sure that the following directories exist and are writable: -@file{ROOT/home} for the GnuPG home and @file{ROOT@value{LOCALCACHEDIR}} -for internal cache files. diff --git a/doc/tools.texi b/doc/tools.texi index eefa4f9d6..a1c161c3a 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -1122,10 +1122,36 @@ More fields may be added in future to the output. @table @file +@item gpgconf.ctl +@cindex gpgconf.ctl + Under Unix @file{gpgconf.ctl} may be used to change some of the + compiled in directories where the GnuPG components are expected. This + file is expected in the same directory as @file{gpgconf}. The + physical installation directories are evaluated and no symlinks. + Blank lines and lines starting with pound sign are ignored in the + file. The keywords must be followed by optional white space, an equal + sign, optional white space, and the value. Environment variables are + substituted in standard shell manner, the final value must start with + a slash, trailing slashes are stripped. Valid keywords are + @code{rootdir}, @code{sysconfdir}, @code{socketdir}, and + @code{.enable}. No errors are printed for unknown keywords. The + @code{.enable} keyword is special: if the keyword is used and its + value evaluates to true the entire file is ignored. + + Under Windows this file is used to install GnuPG as a portable + application. An empty file named @file{gpgconf.ctl} is expected in + the same directory as the tool @file{gpgconf.exe}. The root of the + installation is then that directory; or, if @file{gpgconf.exe} has + been installed directly below a directory named @file{bin}, its parent + directory. You also need to make sure that the following directories + exist and are writable: @file{ROOT/home} for the GnuPG home and + @file{ROOT@value{LOCALCACHEDIR}} for internal cache files. + + @item /etc/gnupg/gpgconf.conf @cindex gpgconf.conf If this file exists, it is processed as a global configuration file. - This is a legacy mechanism which should not be used tigether with + This is a legacy mechanism which should not be used together with the modern global per component configuration files. A commented example can be found in the @file{examples} directory of the distribution. From 431239b83d98c0d980c53a3fdcd70accc7c3eeac Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 22 Dec 2023 13:19:33 +0100 Subject: [PATCH 292/869] doc: Explain why socket activation is a problem -- --- README | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README b/README index c7887fc0f..8fc906bb5 100644 --- a/README +++ b/README @@ -144,6 +144,13 @@ gpg --import --import-options restore < allkeys.gpg gpgsm --import < allcerts.crt + In case the keyboxd is not able to startup due to a stale lockfile + created by another host, the command + + gpgconf --unlock pubring.db + + can be used to remove the lock file. + ** Socket directory GnuPG uses Unix domain sockets to connect its components (on Windows @@ -166,6 +173,29 @@ fi done ) +** Conflicts with systemd socket activation + + Some Linux distribution use the meanwhile deprecated --supervised + option with gpg-agent, dirmngr, and keyboxd. The idea is that the + systemd process launches the daemons as soon as gpg or gpgsm try to + access them. However, this creates a race condition with GnuPG's + own on-demand launching of these daemon. It also conflicts with the + remote use gpg-agent because the no-autostart feature on the remote + site will not work as expected. + + Thus the recommendation is not to use the --supervised option. All + GnuPG components handle the startup of their daemons on their own. + + The only problem is that for using GnuPG's ssh-agent protocol + support, the gpg-agent must have been started before ssh. This can + either be done with an ssh wrapper running + + gpg-connect-agent updatestartuptty /bye + + for each new tty or by using that command directly after login when + the anyway required SSH_AUTH_SOCK envvar is set (see the example in + the gpg-agent man page). + * DOCUMENTATION From 2be53b214d1c9205f5326ca663115200609d8df4 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 25 Dec 2023 10:07:07 +0900 Subject: [PATCH 293/869] tools: Fix argparse table of gpgconf. * tools/gpgconf.c (opts): Use ARGPARSE macros. -- GnuPG-bug-id: 6902 Signed-off-by: NIIBE Yutaka --- tools/gpgconf.c | 70 +++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 76bdebf1a..9c4ea1193 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -86,30 +86,31 @@ enum cmd_and_opt_values /* The list of commands and options. */ static gpgrt_opt_t opts[] = { - { 300, NULL, 0, N_("@Commands:\n ") }, + ARGPARSE_group (300, N_("@Commands:\n ")), - { aListComponents, "list-components", 256, N_("list all components") }, - { aCheckPrograms, "check-programs", 256, N_("check all programs") }, - { aListOptions, "list-options", 256, N_("|COMPONENT|list options") }, - { aChangeOptions, "change-options", 256, N_("|COMPONENT|change options") }, - { aCheckOptions, "check-options", 256, N_("|COMPONENT|check options") }, - { aApplyDefaults, "apply-defaults", 256, - N_("apply global default values") }, - { aApplyProfile, "apply-profile", 256, - N_("|FILE|update configuration files using FILE") }, - { aListDirs, "list-dirs", 256, - N_("get the configuration directories for @GPGCONF@") }, - { aListConfig, "list-config", 256, - N_("list global configuration file") }, - { aCheckConfig, "check-config", 256, - N_("check global configuration file") }, - { aQuerySWDB, "query-swdb", 256, - N_("query the software version database") }, - { aReload, "reload", 256, N_("reload all or a given component")}, - { aLaunch, "launch", 256, N_("launch a given component")}, - { aKill, "kill", 256, N_("kill a given component")}, - { aCreateSocketDir, "create-socketdir", 256, "@"}, - { aRemoveSocketDir, "remove-socketdir", 256, "@"}, + ARGPARSE_c (aListComponents, "list-components", N_("list all components")), + ARGPARSE_c (aCheckPrograms, "check-programs", N_("check all programs")), + ARGPARSE_c (aListOptions, "list-options", N_("|COMPONENT|list options")), + ARGPARSE_c (aChangeOptions, "change-options", + N_("|COMPONENT|change options")), + ARGPARSE_c (aCheckOptions, "check-options", N_("|COMPONENT|check options")), + ARGPARSE_c (aApplyDefaults, "apply-defaults", + N_("apply global default values")), + ARGPARSE_c (aApplyProfile, "apply-profile", + N_("|FILE|update configuration files using FILE")), + ARGPARSE_c (aListDirs, "list-dirs", + N_("get the configuration directories for @GPGCONF@")), + ARGPARSE_c (aListConfig, "list-config", + N_("list global configuration file")), + ARGPARSE_c (aCheckConfig, "check-config", + N_("check global configuration file")), + ARGPARSE_c (aQuerySWDB, "query-swdb", + N_("query the software version database")), + ARGPARSE_c (aReload, "reload", N_("reload all or a given component")), + ARGPARSE_c (aLaunch, "launch", N_("launch a given component")), + ARGPARSE_c (aKill, "kill", N_("kill a given component")), + ARGPARSE_c (aCreateSocketDir, "create-socketdir", "@"), + ARGPARSE_c (aRemoveSocketDir, "remove-socketdir", "@"), ARGPARSE_c (aShowVersions, "show-versions", ""), ARGPARSE_c (aShowConfigs, "show-configs", ""), /* hidden commands: for debugging */ @@ -117,24 +118,25 @@ static gpgrt_opt_t opts[] = ARGPARSE_c (aDotlockLock, "lock", "@"), ARGPARSE_c (aDotlockUnlock, "unlock", "@"), - { 301, NULL, 0, N_("@\nOptions:\n ") }, + ARGPARSE_header (NULL, N_("@\nOptions:\n ")), - { oOutput, "output", 2, N_("use as output file") }, - { oVerbose, "verbose", 0, N_("verbose") }, - { oQuiet, "quiet", 0, N_("quiet") }, - { oDryRun, "dry-run", 0, N_("do not make any changes") }, - { oRuntime, "runtime", 0, N_("activate changes at runtime, if possible") }, + ARGPARSE_s_s (oOutput, "output", N_("use as output file")), + ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), + ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")), + ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), + ARGPARSE_s_n (oRuntime, "runtime", + N_("activate changes at runtime, if possible")), ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), /* hidden options */ - { oHomedir, "homedir", 2, "@" }, - { oBuilddir, "build-prefix", 2, "@" }, - { oNull, "null", 0, "@" }, - { oNoVerbose, "no-verbose", 0, "@"}, + ARGPARSE_s_s (oHomedir, "homedir", "@"), + ARGPARSE_s_s (oBuilddir, "build-prefix", "@"), + ARGPARSE_s_n (oNull, "null", "@"), + ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"), ARGPARSE_s_n (oShowSocket, "show-socket", "@"), ARGPARSE_s_s (oChUid, "chuid", "@"), - ARGPARSE_end(), + ARGPARSE_end () }; From c44f0bc91e7c16ab46a6fba4626ef906d87b04b8 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 26 Dec 2023 11:47:09 +0900 Subject: [PATCH 294/869] agent,kbx: Fix reliable_homedir_inotify (1/2). * agent/gpg-agent.c (reliable_homedir_inotify): Remove the global. (handle_connections): Add reliable_homedir_inotify as an arg. Don't call gnupg_inotify_watch_delete_self when it's not reliable. (check_others_thread): No check of reliable_homedir_inotify repeatedly in the loop. * kbx/keyboxd.c (reliable_homedir_inotify): Remove the global. (handle_connections): Add reliable_homedir_inotify as an arg. (handle_tick): No check of reliable_homedir_inotify in the loop. -- Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 27 ++++++++++++++------------- kbx/keyboxd.c | 18 ++++++++---------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 185957a0f..7182e1f1a 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -479,11 +479,6 @@ static pid_t parent_pid = (pid_t)(-1); * alternative but portable stat based check. */ static int have_homedir_inotify; -/* Depending on how gpg-agent was started, the homedir inotify watch - * may not be reliable. This flag is set if we assume that inotify - * works reliable. */ -static int reliable_homedir_inotify; - /* Number of active connections. */ static int active_connections; @@ -533,7 +528,8 @@ static void agent_deinit_default_ctrl (ctrl_t ctrl); static void handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_extra, gnupg_fd_t listen_fd_browser, - gnupg_fd_t listen_fd_ssh); + gnupg_fd_t listen_fd_ssh, + int reliable_homedir_inotify); static int check_for_running_agent (int silent); #if CHECK_OWN_SOCKET_INTERVAL > 0 static void *check_own_socket_thread (void *arg); @@ -1097,6 +1093,7 @@ main (int argc, char **argv) int gpgconf_list = 0; gpg_error_t err; struct assuan_malloc_hooks malloc_hooks; + int reliable_homedir_inotify = 0; early_system_init (); @@ -1594,7 +1591,7 @@ main (int argc, char **argv) log_info ("listening on: std=%d extra=%d browser=%d ssh=%d\n", fd, fd_extra, fd_browser, fd_ssh); - handle_connections (fd, fd_extra, fd_browser, fd_ssh); + handle_connections (fd, fd_extra, fd_browser, fd_ssh, 1); #endif /*!HAVE_W32_SYSTEM*/ } else if (!is_daemon) @@ -1848,7 +1845,8 @@ main (int argc, char **argv) } log_info ("%s %s started\n", gpgrt_strusage(11), gpgrt_strusage(13) ); - handle_connections (fd, fd_extra, fd_browser, fd_ssh); + handle_connections (fd, fd_extra, fd_browser, fd_ssh, + reliable_homedir_inotify); assuan_sock_close (fd); } @@ -2966,7 +2964,8 @@ static void handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_extra, gnupg_fd_t listen_fd_browser, - gnupg_fd_t listen_fd_ssh) + gnupg_fd_t listen_fd_ssh, + int reliable_homedir_inotify) { gpg_error_t err; npth_attr_t tattr; @@ -3042,8 +3041,10 @@ handle_connections (gnupg_fd_t listen_fd, gpg_strerror (err)); } - if ((err = gnupg_inotify_watch_delete_self (&home_inotify_fd, - gnupg_homedir ()))) + if (!reliable_homedir_inotify) + home_inotify_fd = -1; + else if ((err = gnupg_inotify_watch_delete_self (&home_inotify_fd, + gnupg_homedir ()))) { if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) log_info ("error enabling daemon termination by homedir removal: %s\n", @@ -3064,7 +3065,7 @@ handle_connections (gnupg_fd_t listen_fd, #endif if ((HAVE_PARENT_PID_SUPPORT && parent_pid != (pid_t)(-1)) - || (!have_homedir_inotify || !reliable_homedir_inotify)) + || !have_homedir_inotify) { npth_t thread; @@ -3462,7 +3463,7 @@ check_others_thread (void *arg) #endif /*HAVE_W32_SYSTEM*/ /* Check whether the homedir is still available. */ - if ((!have_homedir_inotify || !reliable_homedir_inotify) + if (!have_homedir_inotify && gnupg_stat (homedir, &statbuf) && errno == ENOENT) problem_detected |= AGENT_PROBLEM_HOMEDIR_REMOVED; } diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index f9792789d..1ba2fd0b5 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -204,11 +204,6 @@ static char *current_logfile; * alternative but portable stat based check. */ static int have_homedir_inotify; -/* Depending on how keyboxd was started, the homedir inotify watch may - * not be reliable. This flag is set if we assume that inotify works - * reliable. */ -static int reliable_homedir_inotify; - /* Number of active connections. */ static int active_connections; @@ -254,7 +249,8 @@ static void kbxd_libgcrypt_progress_cb (void *data, const char *what, static void kbxd_init_default_ctrl (ctrl_t ctrl); static void kbxd_deinit_default_ctrl (ctrl_t ctrl); -static void handle_connections (gnupg_fd_t listen_fd); +static void handle_connections (gnupg_fd_t listen_fd, + int reliable_homedir_inotify); static void check_own_socket (void); static int check_for_running_kbxd (int silent); @@ -464,6 +460,8 @@ main (int argc, char **argv ) int gpgconf_list = 0; int debug_wait = 0; struct assuan_malloc_hooks malloc_hooks; + int reliable_homedir_inotify = 0; + early_system_init (); @@ -846,7 +844,7 @@ main (int argc, char **argv ) } log_info ("%s %s started\n", gpgrt_strusage(11), gpgrt_strusage(13)); - handle_connections (fd); + handle_connections (fd, reliable_homedir_inotify); assuan_sock_close (fd); } @@ -1300,7 +1298,7 @@ handle_tick (void) /* Check whether the homedir is still available. */ if (!shutdown_pending - && (!have_homedir_inotify || !reliable_homedir_inotify) + && !have_homedir_inotify && gnupg_stat (gnupg_homedir (), &statbuf) && errno == ENOENT) { shutdown_pending = 1; @@ -1448,7 +1446,7 @@ start_connection_thread (void *arg) /* Connection handler loop. Wait for connection requests and spawn a * thread after accepting a connection. */ static void -handle_connections (gnupg_fd_t listen_fd) +handle_connections (gnupg_fd_t listen_fd, int reliable_homedir_inotify) { gpg_error_t err; npth_attr_t tattr; @@ -1503,7 +1501,7 @@ handle_connections (gnupg_fd_t listen_fd) gpg_strerror (err)); } - if (disable_check_own_socket) + if (!reliable_homedir_inotify) home_inotify_fd = -1; else if ((err = gnupg_inotify_watch_delete_self (&home_inotify_fd, gnupg_homedir ()))) From 7cde533ce8eaf1713ca1b6aab4470ce1a68c45d9 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 26 Dec 2023 11:58:43 +0900 Subject: [PATCH 295/869] agent,kbx: Fix reliable_homedir_inotify (2/2). * agent/gpg-agent.c (main): The value of reliable_homedir_inotify doesn't not related to nodetach, and it's only zero in the specific condition. * kbx/keyboxd.c (handle_connections): Remove the last argument. (main): Remove reliable_homedir_inotify, as it's always one. -- Signed-off-by: NIIBE Yutaka --- agent/gpg-agent.c | 14 +++++++------- kbx/keyboxd.c | 20 +++++--------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 7182e1f1a..6ffff6eb3 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1093,7 +1093,7 @@ main (int argc, char **argv) int gpgconf_list = 0; gpg_error_t err; struct assuan_malloc_hooks malloc_hooks; - int reliable_homedir_inotify = 0; + int reliable_homedir_inotify = 1; early_system_init (); @@ -1819,14 +1819,14 @@ main (int argc, char **argv) log_get_prefix (&oldflags); log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED); opt.running_detached = 1; - - /* Unless we are running with a program given on the command - * line we can assume that the inotify things works and thus - * we can avoid the regular stat calls. */ - if (!argc) - reliable_homedir_inotify = 1; } + /* When we are running with a program given on the command + * line, the inotify things may not work well and thus + * we cannot avoid the regular stat calls. */ + if (argc) + reliable_homedir_inotify = 0; + { struct sigaction sa; diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index 1ba2fd0b5..66ffbcb3e 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -249,8 +249,7 @@ static void kbxd_libgcrypt_progress_cb (void *data, const char *what, static void kbxd_init_default_ctrl (ctrl_t ctrl); static void kbxd_deinit_default_ctrl (ctrl_t ctrl); -static void handle_connections (gnupg_fd_t listen_fd, - int reliable_homedir_inotify); +static void handle_connections (gnupg_fd_t listen_fd); static void check_own_socket (void); static int check_for_running_kbxd (int silent); @@ -460,8 +459,6 @@ main (int argc, char **argv ) int gpgconf_list = 0; int debug_wait = 0; struct assuan_malloc_hooks malloc_hooks; - int reliable_homedir_inotify = 0; - early_system_init (); @@ -802,11 +799,6 @@ main (int argc, char **argv ) log_get_prefix (&oldflags); log_set_prefix (NULL, oldflags | GPGRT_LOG_RUN_DETACHED); opt.running_detached = 1; - - /* Because we don't support running a program on the command - * line we can assume that the inotify things works and thus - * we can avoid the regular stat calls. */ - reliable_homedir_inotify = 1; } { @@ -844,7 +836,7 @@ main (int argc, char **argv ) } log_info ("%s %s started\n", gpgrt_strusage(11), gpgrt_strusage(13)); - handle_connections (fd, reliable_homedir_inotify); + handle_connections (fd); assuan_sock_close (fd); } @@ -1446,7 +1438,7 @@ start_connection_thread (void *arg) /* Connection handler loop. Wait for connection requests and spawn a * thread after accepting a connection. */ static void -handle_connections (gnupg_fd_t listen_fd, int reliable_homedir_inotify) +handle_connections (gnupg_fd_t listen_fd) { gpg_error_t err; npth_attr_t tattr; @@ -1501,10 +1493,8 @@ handle_connections (gnupg_fd_t listen_fd, int reliable_homedir_inotify) gpg_strerror (err)); } - if (!reliable_homedir_inotify) - home_inotify_fd = -1; - else if ((err = gnupg_inotify_watch_delete_self (&home_inotify_fd, - gnupg_homedir ()))) + if ((err = gnupg_inotify_watch_delete_self (&home_inotify_fd, + gnupg_homedir ()))) { if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) log_info ("error enabling daemon termination by homedir removal: %s\n", From 6ddaf2be9f484eb7a38f2bda0bb70f2d7b4c4511 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 26 Dec 2023 15:07:44 +0900 Subject: [PATCH 296/869] common: Remove t-b64.c. * common/Makefile.am (module_tests): Remove t-b64. (t_b64_LDADD): Remove. * common/t-b64.c: Remove. -- GnuPG-bug-id: 6734 Signed-off-by: NIIBE Yutaka --- common/Makefile.am | 3 +- common/t-b64.c | 154 --------------------------------------------- 2 files changed, 1 insertion(+), 156 deletions(-) delete mode 100644 common/t-b64.c diff --git a/common/Makefile.am b/common/Makefile.am index 0829f5113..d27603f96 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -160,7 +160,7 @@ endif module_tests = t-stringhelp t-timestuff \ t-convert t-percent t-gettime t-sysutils t-sexputil \ t-session-env t-openpgp-oid t-ssh-utils \ - t-mapstrings t-zb32 t-mbox-util t-iobuf t-strlist t-b64 \ + t-mapstrings t-zb32 t-mbox-util t-iobuf t-strlist \ t-name-value t-ccparray t-recsel t-w32-cmdline t-exechelp if HAVE_W32_SYSTEM @@ -210,7 +210,6 @@ t_zb32_LDADD = $(t_common_ldadd) t_mbox_util_LDADD = $(t_common_ldadd) t_iobuf_LDADD = $(t_common_ldadd) t_strlist_LDADD = $(t_common_ldadd) -t_b64_LDADD = $(t_common_ldadd) t_name_value_LDADD = $(t_common_ldadd) t_ccparray_LDADD = $(t_common_ldadd) t_recsel_LDADD = $(t_common_ldadd) diff --git a/common/t-b64.c b/common/t-b64.c deleted file mode 100644 index 783dea5cc..000000000 --- a/common/t-b64.c +++ /dev/null @@ -1,154 +0,0 @@ -/* t-b64.c - Module tests for b64decodec - * Copyright (C) 2023 g10 Code GmbH - * - * 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 . - * SPDX-License-Identifier: LGPL-2.1-or-later - */ - -#include -#include -#include - -#include "util.h" - -#define pass() do { ; } while(0) -#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ - __FILE__,__LINE__, (a)); \ - errcount++; \ - } while(0) -#define oops() do { fprintf (stderr, "%s:%d: ooops\n", \ - __FILE__,__LINE__); \ - exit (2); \ - } while(0) - -static int verbose; -static int errcount; - - -/* Convert STRING consisting of hex characters into its binary - * representation and return it as an allocated buffer. The valid - * length of the buffer is returned at R_LENGTH. The string is - * delimited by end of string. The function returns NULL on - * error. */ -static void * -hex2buffer (const char *string, size_t *r_length) -{ - const char *s; - unsigned char *buffer; - size_t length; - - buffer = xmalloc (strlen(string)/2+1); - length = 0; - for (s=string; *s; s +=2 ) - { - if (!hexdigitp (s) || !hexdigitp (s+1)) - return NULL; /* Invalid hex digits. */ - ((unsigned char*)buffer)[length++] = xtoi_2 (s); - } - *r_length = length; - return buffer; -} - - -static void -test_b64decode (void) -{ - static struct { - const char *string; /* String to test. */ - const char *title; /* title parameter. */ - gpg_error_t err; /* expected error. */ - const char *datastr; /* Expected data (hex encoded) */ - } tests[] = { - { "YQ==", NULL, 0, - "61" }, - { "YWE==", NULL, 0, - "6161" }, - { "YWFh", NULL, 0, - "616161" }, - { "YWFhYQ==", NULL, 0, - "61616161" }, - { "YWJjZA==", NULL, 0, - "61626364" }, - { "AA=", NULL, 0, - "00" }, - { "AAEA=", NULL, 0, - "000100" }, - { "/w==", NULL, 0, - "ff" }, - { "oRQwEqADCgEDoQsGCSqGSIL3EgECAg==", NULL, 0, - "a1143012a0030a0103a10b06092a864882f712010202" }, - { "oRQwEqADCgEDoQsGCSqGSIL3EgECA-==", NULL, GPG_ERR_BAD_DATA, - "a1143012a0030a0103a10b06092a864882f712010202" }, - { "oRQwEqADCgEDoQsGCSqGSIL3EgECAg==", "", 0, - "" }, - { "-----BEGIN PGP\n\n" - "oRQwEqADCgEDoQsGCSqGSIL3EgECAg==\n" - "-----END PGP\n", "", 0, - "a1143012a0030a0103a10b06092a864882f712010202" }, - - { "", NULL, 0, - "" } - }; - int tidx; - gpg_error_t err; - void *data = NULL; - size_t datalen; - char *wantdata = NULL; - size_t wantdatalen; - - for (tidx = 0; tidx < DIM(tests); tidx++) - { - xfree (wantdata); - if (!(wantdata = hex2buffer (tests[tidx].datastr, &wantdatalen))) - oops (); - xfree (data); - err = b64decode (tests[tidx].string, tests[tidx].title, &data, &datalen); - if (verbose) - fprintf (stderr, "%s:%d: test %d, err=%d, datalen=%zu\n", - __FILE__, __LINE__, tidx, err, datalen); - if (gpg_err_code (err) != tests[tidx].err) - fail (tidx); - else if (err) - pass (); - else if (wantdatalen != datalen) - fail (tidx); - else if (memcmp (wantdata, data, datalen)) - fail (tidx); - else - pass (); - } - xfree (wantdata); - xfree (data); -} - - - - -int -main (int argc, char **argv) -{ - if (argc) - { argc--; argv++; } - if (argc && !strcmp (argv[0], "--verbose")) - { - verbose = 1; - argc--; argv++; - } - - test_b64decode (); - - return !!errcount; -} From 591a53d716aab90e0b9573ce4a993e4577486e3f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 29 Dec 2023 10:57:26 +0900 Subject: [PATCH 297/869] gpg: Don't call keybox_compress when KEYDB_RESOURCE_FLAG_READONLY. * g10/keydb.c (keydb_add_resource): Check the FLAGS to call keybox_compress. -- GnuPG-bug-id: 6811 Signed-off-by: NIIBE Yutaka --- g10/keydb.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/g10/keydb.c b/g10/keydb.c index d2d085291..ba61f8290 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -746,28 +746,30 @@ keydb_add_resource (const char *url, unsigned int flags) err = gpg_error (GPG_ERR_RESOURCE_LIMIT); else { - KEYBOX_HANDLE kbxhd; - if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) primary_keydb = token; all_resources[used_resources].type = rt; all_resources[used_resources].u.kb = NULL; /* Not used here */ all_resources[used_resources].token = token; - /* Do a compress run if needed and no other user is - * currently using the keybox. */ - kbxhd = keybox_new_openpgp (token, 0); - if (kbxhd) + if (!(flags & KEYDB_RESOURCE_FLAG_READONLY)) { - if (!keybox_lock (kbxhd, 1, 0)) + KEYBOX_HANDLE kbxhd; + + /* Do a compress run if needed and no other user is + * currently using the keybox. */ + kbxhd = keybox_new_openpgp (token, 0); + if (kbxhd) { - keybox_compress (kbxhd); - keybox_lock (kbxhd, 0, 0); + if (!keybox_lock (kbxhd, 1, 0)) + { + keybox_compress (kbxhd); + keybox_lock (kbxhd, 0, 0); + } + + keybox_release (kbxhd); } - - keybox_release (kbxhd); } - used_resources++; } } From 4c04143d81370d1a1e6006fada1057461b3d3184 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 2 Jan 2024 10:13:16 +0100 Subject: [PATCH 298/869] gpg: Choose key from inserted card over a non-inserted card * g10/call-agent.c (agent_probe_secret_key): Do not return an error but 0. * g10/getkey.c (finish_lookup): Improve the selection of secret keys. -- GnuPG-bug-id: 6831 --- g10/call-agent.c | 13 ++++++++++--- g10/getkey.c | 7 +++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index c90cdfda5..744c0fcb8 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -2226,7 +2226,14 @@ keyinfo_status_cb (void *opaque, const char *line) /* Ask the agent whether a secret key for the given public key is - available. Returns 0 if not available. Bigger value is preferred. */ + * available. Returns 0 if not available. Bigger value is preferred. + * Will never return a value less than 0. Defined return values are: + * 0 := No key or error + * 1 := Key available + * 2 := Key available on a smartcard + * 3 := Key available and passphrase cached + * 4 := Key available on current smartcard + */ int agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk) { @@ -2240,11 +2247,11 @@ agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk) err = start_agent (ctrl, 0); if (err) - return err; + return 0; err = hexkeygrip_from_pk (pk, &hexgrip); if (err) - return err; + return 0; snprintf (line, sizeof line, "KEYINFO %s", hexgrip); xfree (hexgrip); diff --git a/g10/getkey.c b/g10/getkey.c index 21ffd5cfa..d54edcd7f 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3772,6 +3772,13 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, continue; } + if (secret_key_avail < last_secret_key_avail) + { + if (DBG_LOOKUP) + log_debug ("\tskipping secret key with lower avail\n"); + continue; + } + if (secret_key_avail > last_secret_key_avail) { /* Use this key. */ From 3f8cb9b33949494202fefaa8901ab252467cc1f1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 4 Jan 2024 16:29:33 +0100 Subject: [PATCH 299/869] scd: Add support for SCE 7.0 * scd/app-common.h (CARDTYPE_SCE7): New. * scd/app.c (strcardtype): Support it. (atr_to_cardtype): New. (app_new_register): Try to get the cardtype from atr_to_cardtype. * scd/app-piv.c (app_select_piv): Tweak for SCE7. Add general method to construct a S/N from the Card UUID. -- The test cards I have are rsa2048 with X.509 certificates. I don't have the entire chain but loading the certificates work. For testing I created an OpenPGP key from the keys and tested signing and decryption. GnuPG-bug-id: 6919 --- common/util.h | 2 +- scd/app-common.h | 4 ++-- scd/app-piv.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-- scd/app.c | 53 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 109 insertions(+), 6 deletions(-) diff --git a/common/util.h b/common/util.h index fff2e6e83..803ab3d5c 100644 --- a/common/util.h +++ b/common/util.h @@ -392,7 +392,7 @@ int parse_compatibility_flags (const char *string, unsigned int *flagvar, /*-- Simple replacement functions. */ /* We use the gnupg_ttyname macro to be safe not to run into conflicts - which an extisting but broken ttyname. */ + with an existing but broken ttyname. */ #if !defined(HAVE_TTYNAME) || defined(HAVE_BROKEN_TTYNAME) # define gnupg_ttyname(n) _gnupg_ttyname ((n)) /* Systems without ttyname (W32) will merely return NULL. */ diff --git a/scd/app-common.h b/scd/app-common.h index 988cddf3f..f4035f766 100644 --- a/scd/app-common.h +++ b/scd/app-common.h @@ -56,8 +56,8 @@ typedef enum CARDTYPE_GENERIC = 0, CARDTYPE_GNUK, CARDTYPE_YUBIKEY, - CARDTYPE_ZEITCONTROL - + CARDTYPE_ZEITCONTROL, + CARDTYPE_SCE7 /* G+D SmartCafe Expert 7.0 */ } cardtype_t; /* List of supported card applications. The source code for each diff --git a/scd/app-piv.c b/scd/app-piv.c index c8ef7b43a..dc92bd2e2 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -1,5 +1,5 @@ /* app-piv.c - The OpenPGP card application. - * Copyright (C) 2019, 2020 g10 Code GmbH + * Copyright (C) 2019, 2020, 2024 g10 Code GmbH * * This file is part of GnuPG. * @@ -3642,6 +3642,7 @@ app_select_piv (app_t app) size_t aptlen; const unsigned char *s; size_t n; + void *relptr1 = NULL; /* Note that we select using the AID without the 2 octet version * number. This allows for better reporting of future specs. We @@ -3667,7 +3668,21 @@ app_select_piv (app_t app) s = find_tlv (apt, aptlen, 0x4F, &n); /* Some cards (new Yubikey) return only the PIX, while others - * (old Yubikey, PivApplet) return the RID+PIX. */ + * (old Yubikey, PivApplet) return the RID+PIX. + * Sample APTs: + * Yubikey 5.4.3: 6111 4f06 000010000100 7907 4f05 a000000308 + * SCE7.0-G-F-P : 610f 4f06 001000010000 7905 a000000308 + */ + if (app->card->cardtype == CARDTYPE_SCE7 + && s && apt && aptlen == 17 + && !memcmp (apt, ("\x61\x0f\x4f\x06\x00\x10\x00\x01" + "\x00\x00\x79\x05\xa0\x00\x00\x03\x08"), aptlen)) + { + if (opt.verbose) + log_info ("piv: assuming G&D SCE7.0-G-F-P\n"); + app->appversion = 0x0100; /* Let's assume this. */ + goto apt_checked; + } if (!s || !((n == 6 && !memcmp (s, piv_aid+5, 4)) || (n == 11 && !memcmp (s, piv_aid, 9)))) { @@ -3702,6 +3717,7 @@ app_select_piv (app_t app) goto leave; } + apt_checked: app->app_local = xtrycalloc (1, sizeof *app->app_local); if (!app->app_local) { @@ -3712,6 +3728,41 @@ app_select_piv (app_t app) if (app->card->cardtype == CARDTYPE_YUBIKEY) app->app_local->flags.yubikey = 1; + /* If we don't have a s/n construct it from the CHUID. */ + if (!APP_CARD(app)->serialno) + { + unsigned char *chuid; + size_t chuidlen; + + relptr1 = get_one_do (app, 0x5FC102, &chuid, &chuidlen, NULL); + if (!relptr1) + log_error ("piv: CHUID not found\n"); + else + { + s = find_tlv (chuid, chuidlen, 0x34, &n); + if (!s || n != 16) + { + log_error ("piv: Card UUID %s in CHUID\n", + s? "invalid":"missing"); + if (opt.debug && s) + log_printhex (s, n, "got"); + } + else + { + APP_CARD(app)->serialno = xtrymalloc (n); + if (!APP_CARD(app)->serialno) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (APP_CARD(app)->serialno, s, n); + APP_CARD(app)->serialnolen = n; + err = app_munge_serialno (APP_CARD(app)); + if (err) + goto leave; + } + } + } /* FIXME: Parse the optional and conditional DOs in the APT. */ @@ -3739,6 +3790,7 @@ app_select_piv (app_t app) leave: + xfree (relptr1); xfree (apt); if (err) do_deinit (app); diff --git a/scd/app.c b/scd/app.c index 3686c0f6c..2c92201cf 100644 --- a/scd/app.c +++ b/scd/app.c @@ -112,6 +112,7 @@ strcardtype (cardtype_t t) case CARDTYPE_GNUK: return "gnuk"; case CARDTYPE_YUBIKEY: return "yubikey"; case CARDTYPE_ZEITCONTROL: return "zeitcontrol"; + case CARDTYPE_SCE7: return "smartcafe"; } return "?"; } @@ -549,6 +550,51 @@ card_reset (card_t card) return err; } + +/* Return the card type from (ATR,ATRLEN) or CARDTYPE_GENERIC in case + * of error or if the ATR was not found. If ATR is NULL, SLOT is used + * to retrieve the ATR from the reader. */ +static cardtype_t +atr_to_cardtype (int slot, const unsigned char *atr, size_t atrlen) +{ +#define X(a) ((unsigned char const *)(a)) + static struct + { + size_t atrlen; + unsigned char const *atr; + cardtype_t type; + } atrlist[] = { + { 19, X("\x3b\xf9\x96\x00\x00\x80\x31\xfe" + "\x45\x53\x43\x45\x37\x20\x0f\x00\x20\x46\x4e"), + CARDTYPE_SCE7 }, + { 0 } + }; +#undef X + unsigned char *atrbuf = NULL; + cardtype_t cardtype = 0; + int i; + + if (atr) + { + atrbuf = apdu_get_atr (slot, &atrlen); + if (!atrbuf) + return 0; + atr = atrbuf; + } + + for (i=0; atrlist[i].atrlen; i++) + if (atrlist[i].atrlen == atrlen + && !memcmp (atrlist[i].atr, atr, atrlen)) + { + cardtype = atrlist[i].type; + break; + } + xfree (atrbuf); + return cardtype; +} + + + static gpg_error_t app_new_register (int slot, ctrl_t ctrl, const char *name, int periodical_check_needed) @@ -666,13 +712,16 @@ app_new_register (int slot, ctrl_t ctrl, const char *name, } xfree (buf); } + else + card->cardtype = atr_to_cardtype (slot, NULL, 0); } - else + else /* Got 3F00 */ { unsigned char *atr; size_t atrlen; /* This is heuristics to identify different implementations. */ + /* FIXME: The first two checks are pretty OpenPGP card specific. */ atr = apdu_get_atr (slot, &atrlen); if (atr) { @@ -680,6 +729,8 @@ app_new_register (int slot, ctrl_t ctrl, const char *name, card->cardtype = CARDTYPE_GNUK; else if (atrlen == 21 && atr[7] == 0x75) card->cardtype = CARDTYPE_ZEITCONTROL; + else + card->cardtype = atr_to_cardtype (slot, atr, atrlen); xfree (atr); } } From 2cb97713e9b6590db05894e8015c6cb3d04f4a6f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Jan 2024 11:33:51 +0100 Subject: [PATCH 300/869] gpg: Improve error return for --quick-add-subkey and -add-adsk. * g10/keyedit.c (keyedit_quick_addkey): Emit a ERROR status line. (keyedit_quick_addadsk): Ditto. -- GnuPG-bug-id: 6880 --- g10/keyedit.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/g10/keyedit.c b/g10/keyedit.c index 1f614fb7e..a12546f71 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3212,7 +3212,7 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr, /* We require a fingerprint because only this uniquely identifies a * key and may thus be used to select a key for unattended subkey * creation. */ - if (find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd)) + if ((err=find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd))) goto leave; if (fix_keyblock (ctrl, &keyblock)) @@ -3224,6 +3224,7 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr, if (!opt.verbose) show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1); log_error ("%s%s", _("Key is revoked."), "\n"); + err = gpg_error (GPG_ERR_CERT_REVOKED); goto leave; } @@ -3247,6 +3248,8 @@ keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr, log_info (_("Key not changed so no update needed.\n")); leave: + if (err) + write_status_error ("keyedit.addkey", err); release_kbnode (keyblock); keydb_release (kdbhd); } @@ -3274,7 +3277,7 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr) /* We require a fingerprint because only this uniquely identifies a * key and may thus be used to select a key for unattended adsk * adding. */ - if (find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd)) + if ((err = find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd))) goto leave; if (fix_keyblock (ctrl, &keyblock)) @@ -3286,6 +3289,7 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr) if (!opt.verbose) show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1); log_error ("%s%s", _("Key is revoked."), "\n"); + err = gpg_error (GPG_ERR_CERT_REVOKED); goto leave; } @@ -3310,6 +3314,8 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr) } leave: + if (err) + write_status_error ("keyedit.addadsk", err); release_kbnode (keyblock); keydb_release (kdbhd); } From 45f6357881459dcb6b2b78e475d1c136bcb6f606 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 10:09:36 +0100 Subject: [PATCH 301/869] common,w32: Remove duplicated backslashes when setting the homedir. * common/homedir.c (copy_dir_with_fixup) [W32]: Fold double backslashes. -- This is in general no problem but when we hash or compare the directory to test whether tit is the standard home directory, we may use a different socket file and thus a second instance of a daemon. GnuPG-bug-id: 6833 --- NEWS | 3 +++ common/homedir.c | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/NEWS b/NEWS index 889aff8e1..7b99deeab 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,9 @@ Noteworthy changes in version 2.4.4 (unreleased) * gpgsm: Support ECDSA in de-vs compliance mode. [T6802] + * dirmngr: Avoid starting a second instance on Windows via GPGME + based launching. [T6833] + * Fix garbled time output in non-English Windows. [T6741] Release-info: https://dev.gnupg.org/T6578 diff --git a/common/homedir.c b/common/homedir.c index 2b99c9bdc..6f99f3eab 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -222,6 +222,10 @@ copy_dir_with_fixup (const char *newdir) { char *result = NULL; char *p; +#ifdef HAVE_W32_SYSTEM + char *p0; + const char *s; +#endif if (!*newdir) return NULL; @@ -253,6 +257,29 @@ copy_dir_with_fixup (const char *newdir) *p-- = 0; } + /* Hack to mitigate badly doubled backslashes. */ + s = result? result : newdir; + if (s[0] == '\\' && s[1] == '\\' && s[2] != '\\') + { + /* UNC (\\Servername\file) or Long UNC (\\?\Servername\file) + * Does not seem to be double quoted. */ + } + else if (strstr (s, "\\\\")) + { + /* Double quotes detected. Fold them into one because that is + * what what Windows does. This way we get a unique hash + * regardless of the number of doubled backslashes. */ + if (!result) + result = xstrdup (newdir); + for (p0=p=result; *p; p++) + { + *p0++ = *p; + while (*p == '\\' && p[1] == '\\') + p++; + } + *p0 = 0; + } + #else /*!HAVE_W32_SYSTEM*/ if (newdir[strlen (newdir)-1] == '/') From 35fd89b168b622966019c07aa619b99c2912534c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 12:51:34 +0100 Subject: [PATCH 302/869] gpgconf: Adjust -X command for the new VERSION file format * tools/gpgconf.c (show_version_gnupg): Read and parse the entire VERSION file. -- GnuPG-bug-id: 6918 --- tools/gpgconf.c | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 9c4ea1193..b528e329c 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -1153,10 +1153,12 @@ get_revision_from_blurb (const char *blurb, int *r_len) static void show_version_gnupg (estream_t fp, const char *prefix) { - char *fname, *p; + char *fname, *p, *p0; size_t n; estream_t verfp; - char line[100]; + char *line = NULL; + size_t line_len = 0; + ssize_t length; es_fprintf (fp, "%s%sGnuPG %s (%s)\n%s%s\n", prefix, *prefix?"":"* ", gpgrt_strusage (13), BUILD_REVISION, prefix, gpgrt_strusage (17)); @@ -1175,20 +1177,46 @@ show_version_gnupg (estream_t fp, const char *prefix) verfp = es_fopen (fname, "r"); if (!verfp) es_fprintf (fp, "%s[VERSION file not found]\n", prefix); - else if (!es_fgets (line, sizeof line, verfp)) - es_fprintf (fp, "%s[VERSION file is empty]\n", prefix); else { - trim_spaces (line); - for (p=line; *p; p++) - if (*p < ' ' || *p > '~' || *p == '[') - *p = '?'; - es_fprintf (fp, "%s%s\n", prefix, line); + int lnr = 0; + + p0 = NULL; + while ((length = es_read_line (verfp, &line, &line_len, NULL))>0) + { + lnr++; + trim_spaces (line); + if (lnr == 1 && *line != '[') + { + /* Old file format where we look only at the + * first line. */ + p0 = line; + break; + } + else if (!strncmp (line, "version=", 8)) + { + p0 = line + 8; + break; + } + } + if (length < 0 || es_ferror (verfp)) + es_fprintf (fp, "%s[VERSION file read error]\n", prefix); + else if (p0) + { + for (p=p0; *p; p++) + if (*p < ' ' || *p > '~' || *p == '[') + *p = '?'; + es_fprintf (fp, "%s%s\n", prefix, p0); + } + else + es_fprintf (fp, "%s[VERSION file is empty]\n", prefix); + + es_fclose (verfp); } - es_fclose (verfp); } xfree (fname); } + xfree (line); #ifdef HAVE_W32_SYSTEM { From 880dde8e5bafb1efc6b3b1b64ccc8fd43a46f775 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 15:26:47 +0100 Subject: [PATCH 303/869] scd:p15: Allow PIN verification and decryption for CVISION cards. * scd/app-p15.c (CARD_PRODUCT_CVISION): New. (IS_STARCOS_3): New. (read_p15_info): Detect this product. (prepare_verify_pin): Add special handling for this product. (do_decipher): Use dedicated MSE for Starcos 3 cards. -- To check the verification run gpg-card verify User_PIN For our test cards the "Benutzer-PIN" must be given. For decryption tests gpgsm can be used; --always-trust helps to avoid chain issues. --- scd/app-p15.c | 70 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 8edd737a6..e5edc5308 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -91,7 +91,8 @@ typedef enum CARD_PRODUCT_DTRUST3, /* D-Trust GmbH (bundesdruckerei.de) */ CARD_PRODUCT_DTRUST4, CARD_PRODUCT_GENUA, /* GeNUA mbH */ - CARD_PRODUCT_NEXUS /* Technology Nexus */ + CARD_PRODUCT_NEXUS, /* Technology Nexus */ + CARD_PRODUCT_CVISION /* Cryptovision GmbH */ } card_product_t; @@ -143,6 +144,8 @@ static struct #define IS_CARDOS_5(a) ((a)->app_local->card_type == CARD_TYPE_CARDOS_50 \ || (a)->app_local->card_type == CARD_TYPE_CARDOS_53 \ || (a)->app_local->card_type == CARD_TYPE_CARDOS_54) +#define IS_STARCOS_3(a) ((a)->app_local->card_type == CARD_TYPE_STARCOS_32) + /* The default PKCS-15 home DF */ #define DEFAULT_HOME_DF 0x5015 @@ -532,8 +535,6 @@ struct app_local_s /*** Local prototypes. ***/ static gpg_error_t select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen); -static gpg_error_t select_df_by_path (app_t app, const unsigned short *path, - size_t pathlen); static gpg_error_t keygrip_from_prkdf (app_t app, prkdf_object_t prkdf); static gpg_error_t readcert_by_cdf (app_t app, cdf_object_t cdf, unsigned char **r_cert, size_t *r_certlen); @@ -571,6 +572,7 @@ cardproduct2str (card_product_t cardproduct) case CARD_PRODUCT_DTRUST4: return "D-Trust 4.1/4.4"; case CARD_PRODUCT_GENUA: return "GeNUA"; case CARD_PRODUCT_NEXUS: return "Nexus"; + case CARD_PRODUCT_CVISION: return "Cryptovison"; } return ""; } @@ -803,7 +805,7 @@ select_by_path (app_t app, const unsigned short *path, size_t pathlen, log_debug ("%s: path=", __func__); for (j=0; j < pathlen; j++) log_printf ("%s%04hX", j? "/":"", path[j]); - log_printf ("%s\n",expect_df?" (DF requested)":""); + log_printf ("%s", expect_df?" (DF requested)":""); log_printf ("%s\n",app->app_local->direct_path_selection?" (direct)":""); } @@ -867,11 +869,13 @@ select_ef_by_path (app_t app, const unsigned short *path, size_t pathlen) } +#if 0 /* Currently not used. */ static gpg_error_t select_df_by_path (app_t app, const unsigned short *path, size_t pathlen) { return select_by_path (app, path, pathlen, 1); } +#endif /* Parse a cert Id string (or a key Id string) and return the binary @@ -3611,6 +3615,7 @@ read_p15_info (app_t app) gpg_error_t err; prkdf_object_t prkdf; unsigned int flag; + const char *manu; err = read_ef_tokeninfo (app); if (err) @@ -3631,18 +3636,22 @@ read_p15_info (app_t app) release_lists (app); /* Set a product type from the manufacturer_id. */ - if (IS_CARDOS_5 (app) && app->app_local->manufacturer_id) + if (!(manu = app->app_local->manufacturer_id) || !*manu) + ; /* No manufacturer_id. */ + else if (app->app_local->card_product) + ; /* Already set. */ + else if (IS_CARDOS_5 (app)) { - const char *manu = app->app_local->manufacturer_id; - - if (app->app_local->card_product) - ; /* Already set. */ - else if (!ascii_strcasecmp (manu, "GeNUA mbH")) + if (!ascii_strcasecmp (manu, "GeNUA mbH")) app->app_local->card_product = CARD_PRODUCT_GENUA; else if (!ascii_strcasecmp (manu, "Technology Nexus")) app->app_local->card_product = CARD_PRODUCT_NEXUS; } - + else if (app->app_local->card_type == CARD_TYPE_STARCOS_32) + { + if (strstr (manu, "cryptovision")) + app->app_local->card_product = CARD_PRODUCT_CVISION; + } /* Read the ODF so that we know the location of all directory files. */ @@ -5053,11 +5062,18 @@ prepare_verify_pin (app_t app, const char *keyref, log_error ("p15: error selecting D-TRUST's AID for key %s: %s\n", keyref, gpg_strerror (err)); } - else if (prkdf && app->app_local->card_type == CARD_TYPE_STARCOS_32) + else if (app->app_local->card_product == CARD_PRODUCT_CVISION) { - err = select_df_by_path (app, prkdf->path, prkdf->pathlen); + /* According to our protocol analysis we need to select the + * PKCS#15 AID here. The traces actually show that this is done + * two times but that looks more like a bug. Before that the + * master file needs to be selected. */ + err = iso7816_select_mf (app_get_slot (app)); + if (!err) + err = iso7816_select_application (app_get_slot (app), + pkcs15_aid, sizeof pkcs15_aid, 0); if (err) - log_error ("p15: error selecting file for key %s: %s\n", + log_error ("p15: error selecting PKCS#15 AID for key %s: %s\n", keyref, gpg_strerror (err)); } else if (prkdf) @@ -5862,6 +5878,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, prkdf_object_t prkdf; /* The private key object. */ aodf_object_t aodf; /* The associated authentication object. */ int exmode, le_value, padind; + int i; (void)ctrl; (void)r_info; @@ -5960,10 +5977,33 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, 0xF3, 0x31, NULL, 0); } } + else if (prkdf->key_reference_valid && IS_STARCOS_3 (app)) + { + unsigned char mse[9]; + + i = 0; + if (prkdf->is_ecc) + { + log_info ("Note: ECC is not yet implemented for Starcos 3 cards\n"); + err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + } + else + { + mse[i++] = 0x84; /* Key reference. */ + mse[i++] = 1; + mse[i++] = prkdf->key_reference; + mse[i++] = 0x89; /* Algorithm reference (BCD encoded). */ + mse[i++] = 2; + mse[i++] = 0x11; /* RSA no padding (1 1 3 0). */ + mse[i++] = 0x30; + log_assert (i <= DIM(mse)); + err = iso7816_manage_security_env (app_get_slot (app), 0x41, 0xB8, + mse, i); + } + } else if (prkdf->key_reference_valid) { unsigned char mse[9]; - int i; /* Note: This works with CardOS but the D-Trust card has the * problem that the next created signature would be broken. */ From 4ca017e43bb296b937c792c28cd500baa1f8dc14 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 17:25:34 +0100 Subject: [PATCH 304/869] gpg: Print a useful error id SKI algo 253 is found. * g10/parse-packet.c (parse_key): Detect the SKI algo 253. -- As long as we have not yet implemented this we should at least be able to detect this case. --- g10/parse-packet.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/g10/parse-packet.c b/g10/parse-packet.c index a033732ec..aa6bac9da 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -2684,7 +2684,16 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, { ski->is_protected = 1; ski->s2k.count = 0; - if (ski->algo == 254 || ski->algo == 255) + if (ski->algo == 253) + { + if (list_mode) + es_fprintf (listfp, + "\tS2K pseudo algo %d is not yet supported\n", + ski->algo); + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + goto leave; + } + else if (ski->algo == 254 || ski->algo == 255) { if (pktlen < 3) { From 6233a17ac99deb8d246458380813b621df2609bf Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Jan 2024 19:52:04 +0100 Subject: [PATCH 305/869] g13: New option --no-mount. * g13/g13.c (oNoMount): New. (opts): Add --no-mount. (main): Implement this. * g13/g13-common.h (opt): Add field no_mount. * common/status.h (STATUS_PLAINDEV): New. * g13/sh-cmd.c (has_option): Uncomment. (cmd_mount): Add option --no-mount and pass down. * g13/sh-dmcrypt.c (sh_dmcrypt_mount_container): Add arg nomount and emit PLAINDEV status line. (sh_dmcrypt_umount_container): Rund findmnt before umount. -- This option can be used to decrypt a device but not to mount it. For example to run fsck first. A command or option to run fsck before a mount will eventually be added. The use of findmnt is needed so that we can easily remove a device which has not been mounted. --- common/status.h | 1 + g13/call-syshelp.c | 14 +++++++--- g13/g13-common.h | 2 ++ g13/g13-syshelp.c | 2 +- g13/g13-syshelp.h | 2 +- g13/g13.c | 4 +++ g13/sh-cmd.c | 30 ++++++++++++---------- g13/sh-dmcrypt.c | 64 ++++++++++++++++++++++++++++------------------ 8 files changed, 76 insertions(+), 43 deletions(-) diff --git a/common/status.h b/common/status.h index e4cf23ee1..d249174d1 100644 --- a/common/status.h +++ b/common/status.h @@ -152,6 +152,7 @@ enum STATUS_TRUNCATED, STATUS_MOUNTPOINT, STATUS_BLOCKDEV, + STATUS_PLAINDEV, /* The decrypted virtual device. */ STATUS_PINENTRY_LAUNCHED, diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c index 54dca04ec..c4bc48172 100644 --- a/g13/call-syshelp.c +++ b/g13/call-syshelp.c @@ -433,10 +433,15 @@ static gpg_error_t mount_status_cb (void *opaque, const char *line) { struct mount_parm_s *parm = opaque; + const char *s; - /* Nothing right now. */ (void)parm; - (void)line; + + if ((s=has_leading_keyword (line, "PLAINDEV"))) + { + if (opt.verbose || opt.no_mount) + log_info ("Device: %s\n", s); + } return 0; } @@ -497,7 +502,10 @@ call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint, { ref_tupledesc (tuples); parm.keyblob = get_tupledesc_data (tuples, &parm.keybloblen); - err = assuan_transact (ctx, "MOUNT dm-crypt", + err = assuan_transact (ctx, + (opt.no_mount + ? "MOUNT --no-mount dm-crypt" + : "MOUNT dm-crypt"), NULL, NULL, mount_inq_cb, &parm, mount_status_cb, &parm); diff --git a/g13/g13-common.h b/g13/g13-common.h index 42b8deebd..539c091aa 100644 --- a/g13/g13-common.h +++ b/g13/g13-common.h @@ -81,6 +81,8 @@ struct /* Name of the output file - FIXME: what is this? */ const char *outfile; + int no_mount; /* Stop right before mounting a device. */ + } opt; diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c index 6a4d3a446..0de1cf15d 100644 --- a/g13/g13-syshelp.c +++ b/g13/g13-syshelp.c @@ -584,7 +584,7 @@ g13_syshelp_i_know_what_i_am_doing (void) if (gnupg_access (fname, F_OK)) { log_info ("*******************************************************\n"); - log_info ("* The G13 support for DM-Crypt is new and not matured.\n"); + log_info ("* The G13 support for DM-Crypt is not yet widely used.\n"); log_info ("* Bugs or improper use may delete all your disks!\n"); log_info ("* To confirm that you are ware of this risk, create\n"); log_info ("* the file '%s'.\n", fname); diff --git a/g13/g13-syshelp.h b/g13/g13-syshelp.h index 0243166ba..10b529fb1 100644 --- a/g13/g13-syshelp.h +++ b/g13/g13-syshelp.h @@ -85,7 +85,7 @@ gpg_error_t sh_is_empty_partition (const char *name); gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp); gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, - tupledesc_t keyblob); + tupledesc_t keyblob, int nomount); gpg_error_t sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname); gpg_error_t sh_dmcrypt_suspend_container (ctrl_t ctrl, const char *devname); gpg_error_t sh_dmcrypt_resume_container (ctrl_t ctrl, const char *devname, diff --git a/g13/g13.c b/g13/g13.c index 2bbb453eb..cb1880f80 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -103,6 +103,7 @@ enum cmd_and_opt_values { oWithColons, oDryRun, oNoDetach, + oNoMount, oNoRandomSeedFile, oFakedSystemTime @@ -137,6 +138,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write log output to FILE")), ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"), ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"), + ARGPARSE_s_n (oNoMount, "no-mount", N_("stop right before running mount")), ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), @@ -518,6 +520,8 @@ main (int argc, char **argv) case oNoDetach: /*nodetach = 1; */break; + case oNoMount: opt.no_mount = 1; break; + case oDebug: if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags)) { diff --git a/g13/sh-cmd.c b/g13/sh-cmd.c index 791e3b7f4..1d21f6cc4 100644 --- a/g13/sh-cmd.c +++ b/g13/sh-cmd.c @@ -83,17 +83,17 @@ skip_options (const char *line) /* Check whether the option NAME appears in LINE. */ -/* static int */ -/* has_option (const char *line, const char *name) */ -/* { */ -/* const char *s; */ -/* int n = strlen (name); */ +static int +has_option (const char *line, const char *name) +{ + const char *s; + int n = strlen (name); -/* s = strstr (line, name); */ -/* if (s && s >= skip_options (line)) */ -/* return 0; */ -/* return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); */ -/* } */ + s = strstr (line, name); + if (s && s >= skip_options (line)) + return 0; + return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); +} /* Helper to print a message while leaving a command. */ @@ -431,10 +431,11 @@ cmd_getkeyblob (assuan_context_t ctx, char *line) static const char hlp_mount[] = - "MOUNT \n" + "MOUNT [--no-mount] \n" "\n" "Mount an encrypted partition on the current device.\n" - " must be \"dm-crypt\" for now."; + " must be \"dm-crypt\" for now. Option --no-mount\n" + "stops right before calling the mount command.\n"; static gpg_error_t cmd_mount (assuan_context_t ctx, char *line) { @@ -443,6 +444,9 @@ cmd_mount (assuan_context_t ctx, char *line) unsigned char *keyblob = NULL; size_t keybloblen; tupledesc_t tuples = NULL; + int nomount; + + nomount = has_option (line, "--no-mount"); line = skip_options (line); @@ -493,7 +497,7 @@ cmd_mount (assuan_context_t ctx, char *line) err = sh_dmcrypt_mount_container (ctrl, ctrl->server_local->devicename, - tuples); + tuples, nomount); leave: destroy_tupledesc (tuples); diff --git a/g13/sh-dmcrypt.c b/g13/sh-dmcrypt.c index 6f7173ec5..c3b5a6d77 100644 --- a/g13/sh-dmcrypt.c +++ b/g13/sh-dmcrypt.c @@ -220,7 +220,7 @@ mk_setup_area_prefix (size_t *r_length) } -/* Create a new g13 styloe DM-Crypt container on devoce DEVNAME. */ +/* Create a new g13 style DM-Crypt container on device DEVNAME. */ gpg_error_t sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp) { @@ -538,10 +538,11 @@ sh_dmcrypt_create_container (ctrl_t ctrl, const char *devname, estream_t devfp) /* Mount a DM-Crypt container on device DEVNAME taking keys and other - * meta data from KEYBLOB. */ + * meta data from KEYBLOB. If NOMOUNT is set the actual mount command + * is not run. */ gpg_error_t sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, - tupledesc_t keyblob) + tupledesc_t keyblob, int nomount) { gpg_error_t err; char *targetname_abs = NULL; @@ -696,8 +697,10 @@ sh_dmcrypt_mount_container (ctrl_t ctrl, const char *devname, xfree (result); result = NULL; + g13_status (ctrl, STATUS_PLAINDEV, targetname_abs, NULL); + /* Mount if a mountpoint has been given. */ - if (ctrl->devti->mountpoint) + if (!nomount && ctrl->devti->mountpoint) { const char *argv[3]; @@ -766,32 +769,43 @@ sh_dmcrypt_umount_container (ctrl_t ctrl, const char *devname) goto leave; } - /* Run the regular umount command. */ + /* Run the regular umount command but first test with findmnt. */ { - const char *argv[2]; + const char *argv[3]; argv[0] = targetname_abs; argv[1] = NULL; - log_debug ("now running \"umount %s\"\n", targetname_abs); - err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL); - } - if (err) - { - log_error ("error running umount: %s\n", gpg_strerror (err)); - if (1) - { - /* Try to show some info about processes using the partition. */ - const char *argv[3]; + log_debug ("now running \"findmnt %s\"\n", targetname_abs); + err = gnupg_exec_tool ("/bin/findmnt", argv, NULL, &result, NULL); - argv[0] = "-mv"; - argv[1] = targetname_abs; - argv[2] = NULL; - gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL); - } - goto leave; - } - if (result && *result) /* (We should not see output to stdout). */ - log_info ("WARNING: umount returned data on stdout! (%s)\n", result); + if (err) + log_info ("Note: device was not mounted\n"); + else + { + xfree (result); + result = NULL; + + argv[0] = targetname_abs; + argv[1] = NULL; + log_debug ("now running \"umount %s\"\n", targetname_abs); + err = gnupg_exec_tool ("/bin/umount", argv, NULL, &result, NULL); + if (err) + { + log_error ("error running umount: %s\n", gpg_strerror (err)); + if (1) + { + /* Try to show some info about processes using the partition. */ + argv[0] = "-mv"; + argv[1] = targetname_abs; + argv[2] = NULL; + gnupg_exec_tool ("/bin/fuser", argv, NULL, &result, NULL); + } + goto leave; + } + if (result && *result) /* (We should not see output to stdout). */ + log_info ("WARNING: umount returned data on stdout! (%s)\n", result); + } + } xfree (result); result = NULL; From 275ced5067dabba3028192e50896f2a0e4a4d13c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 10 Jan 2024 14:35:26 +0100 Subject: [PATCH 306/869] scd:p15: Allow signing for CVISION cards * scd/app-p15.c (do_sign): Add code for Starcos 3.2 and the CVISION product. -- The code for the Starcos cards has been implemented according to the 3.52 manual However, this does not work with my test cards. Protocol analysis shows that decryption can be used for the cryptovision product. Thus we do it the same for now. --- scd/app-p15.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index e5edc5308..2bb90beaa 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -5513,6 +5513,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, unsigned char oidbuf[64]; size_t oidbuflen; size_t n; + int i; unsigned char *indata_buffer = NULL; /* Malloced helper. */ (void)ctrl; @@ -5610,7 +5611,6 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, { unsigned int framelen; unsigned char *frame; - int i; framelen = (prkdf->keynbits+7) / 8; if (!framelen) @@ -5685,6 +5685,23 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, memcpy (frame, indata, indatalen); framelen = indatalen; } + else if (hashalgo && IS_STARCOS_3 (app) + && app->app_local->card_product != CARD_PRODUCT_CVISION) + { + /* For Starcos we need the plain hash w/o the prefix. */ + /* Note: This has never been tested because the cvision + * sample cards seem not to work this way. */ + if (indatalen != oidbuflen + digestlen + || memcmp (indata, oidbuf, oidbuflen)) + { + log_error ("p15: non-matching input data for Starcos:" + " hash=%d len=%zu\n", hashalgo, indatalen); + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + framelen = indatalen - oidbuflen; + memcpy (frame, (const char*)indata + oidbuflen, framelen); + } else { n = 0; @@ -5774,7 +5791,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, else { /* The D-TRUST Card 4.x doesn't support setting a security - * environment, at least as specified in the specs. Insted a + * environment, at least as specified in the specs. Instead a * predefined security environment has to be loaded depending on the * cipher and message digest used. The spec states SE-ID 0x25 for * SHA256, 0x26 for SHA384 and 0x27 for SHA512, when using PKCS#1 @@ -5788,6 +5805,61 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, 0xf3, 0x25, NULL, 0); } } + else if (app->app_local->card_product == CARD_PRODUCT_CVISION) + { + /* I can't make the Starcos 3.2 work the correct way, so let's + * make them work in the same way the cryptovision product seems + * to do it: Use the plain RSA decryption instead. */ + unsigned char mse[9]; + + i = 0; + mse[i++] = 0x84; /* Key reference. */ + mse[i++] = 1; + mse[i++] = prkdf->key_reference; + mse[i++] = 0x89; /* Algorithm reference (BCD encoded). */ + mse[i++] = 2; + mse[i++] = 0x11; /* RSA no padding (1 1 3 0). */ + mse[i++] = 0x30; + log_assert (i <= DIM(mse)); + err = iso7816_manage_security_env (app_get_slot (app), 0x41, 0xB8, + mse, i); + } + else if (prkdf->key_reference_valid && IS_STARCOS_3 (app)) + { + unsigned char mse[9]; + + i = 0; + if (prkdf->is_ecc) + { + log_info ("Note: ECC is not yet implemented for Starcos 3 cards\n"); + err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + } + else + { + err = 0; + mse[i++] = 0x84; /* Key reference. */ + mse[i++] = 1; + mse[i++] = prkdf->key_reference; + mse[i++] = 0x89; /* Algorithm reference (BCD encoded). */ + mse[i++] = 3; + mse[i++] = 0x13; /* RSA PKCS#1 (standard) (1 3 2 3). */ + mse[i++] = 0x23; + switch (hashalgo) + { + case GCRY_MD_SHA1: mse[i++] = 0x10; break; + case GCRY_MD_RMD160: mse[i++] = 0x20; break; + case GCRY_MD_SHA256: mse[i++] = 0x30; break; + case GCRY_MD_SHA384: mse[i++] = 0x40; break; + case GCRY_MD_SHA512: mse[i++] = 0x50; break; + case GCRY_MD_SHA224: mse[i++] = 0x60; break; + default: err = gpg_error (GPG_ERR_DIGEST_ALGO); break; + } + log_assert (i <= DIM(mse)); + if (!err) + err = iso7816_manage_security_env (app_get_slot (app), 0x41, 0xB6, + mse, i); + } + } else if (prkdf->key_reference_valid) { unsigned char mse[3]; @@ -5817,9 +5889,14 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, le_value = 0; } - err = iso7816_compute_ds (app_get_slot (app), + if (app->app_local->card_product == CARD_PRODUCT_CVISION) + err = iso7816_decipher (app_get_slot (app), exmode, indata, indatalen, - le_value, outdata, outdatalen); + le_value, 0, outdata, outdatalen); + else + err = iso7816_compute_ds (app_get_slot (app), + exmode, indata, indatalen, + le_value, outdata, outdatalen); leave: xfree (indata_buffer); From b7f45ee6adbc1a2d22b596aada2e8ca8b1e1c82b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 10 Jan 2024 17:18:34 +0100 Subject: [PATCH 307/869] gpg: Allow to create revocations even with non-compliant algos. * g10/sign.c (do_sign): Skip compliance check for revocation certs. -- It just does not make sense to inhibit the creation of revocations depending on the compliance mode. We do this only for key revocation but not for another kind of revocation because the rationale for uid or subkey revocation is more complicated to explain. --- g10/sign.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/g10/sign.c b/g10/sign.c index d6ab396af..b00bdfefd 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -444,8 +444,9 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig, goto leave; } - /* Check compliance. */ - if (! gnupg_digest_is_allowed (opt.compliance, 1, mdalgo)) + /* Check compliance but always allow for key revocations. */ + if (!IS_KEY_REV (sig) + && ! gnupg_digest_is_allowed (opt.compliance, 1, mdalgo)) { log_error (_("digest algorithm '%s' may not be used in %s mode\n"), gcry_md_algo_name (mdalgo), @@ -454,9 +455,10 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig, goto leave; } - if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, - pksk->pubkey_algo, 0, - pksk->pkey, nbits_from_pk (pksk), NULL)) + if (!IS_KEY_REV (sig) + && ! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, + pksk->pubkey_algo, 0, + pksk->pkey, nbits_from_pk (pksk), NULL)) { log_error (_("key %s may not be used for signing in %s mode\n"), keystr_from_pk (pksk), From 8dfbad0c416ebeaf838d06d50708b8b21f7a8e4a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 Jan 2024 09:08:54 +0100 Subject: [PATCH 308/869] gpg: Fix regression in the Revoker keyword of the parmeter file. * g10/keygen.c (parse_revocation_key): Actually allow for v4 fingerprints. -- Note that the use of the parameter file is deprecated. GnuPG-bug-id: 6923 --- doc/gpg.texi | 7 ++++--- g10/keygen.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index b666a72bc..7e51aff6f 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -4638,9 +4638,10 @@ in the @option{--edit-key} menu. @item Revoker: @var{algo}:@var{fpr} [sensitive] Add a designated revoker to the generated key. Algo is the public key algorithm of the designated revoker (i.e. RSA=1, DSA=17, etc.) -@var{fpr} is the fingerprint of the designated revoker. The optional -@samp{sensitive} flag marks the designated revoker as sensitive -information. Only v4 keys may be designated revokers. +@var{fpr} is the fingerprint of the designated revoker. @var{fpr} may +not contain spaces or colons. The optional @samp{sensitive} flag +marks the designated revoker as sensitive information. Only v4 and v5 +keys may be designated revokers. @item Keyserver: @var{string} This is an optional parameter that specifies the preferred keyserver diff --git a/g10/keygen.c b/g10/keygen.c index 2f8528278..3efdf94a3 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -4079,7 +4079,7 @@ parse_revocation_key (const char *fname, pn++; - for(i=0;i Date: Thu, 11 Jan 2024 15:28:33 +0100 Subject: [PATCH 309/869] doc: Document the gpgconf --unlock command. * tools/gpgconf.c (main): Fix usage message. -- GnuPG-bug-id: 6838 --- doc/tools.texi | 13 ++++++++++++- tools/gpgconf.c | 8 ++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/doc/tools.texi b/doc/tools.texi index a1c161c3a..80ec7c6fe 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -387,12 +387,23 @@ daemons. Note that as of now reload and kill have the same effect for Create a directory for sockets below /run/user or /var/run/user. This is command is only required if a non default home directory is used and the /run based sockets shall be used. For the default home -directory GnUPG creates a directory on the fly. +directory GnuPG creates a directory on the fly. @item --remove-socketdir @opindex remove-socketdir Remove a directory created with command @option{--create-socketdir}. +@item --unlock @var{name} +@itemx --lock @var{name} +Remove a stale lock file hold for @file{file}. The file is +expected in the current GnuPG home directory. This command is usually +not required because GnuPG is able to detect and remove stale lock +files. Before using the command make sure that the file protected by +the lock file is actually not in use. The lock command may be used to +lock an accidently removed lock file. Note that the commands have no +effect on Windows because the mere existence of a lock file does not +mean that the lock is active. + @end table diff --git a/tools/gpgconf.c b/tools/gpgconf.c index b528e329c..6a5add42b 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -1074,12 +1074,12 @@ main (int argc, char **argv) #if !defined(HAVE_W32_SYSTEM) if (!fname) { - es_fprintf (es_stderr, "usage: %s [options] lock|unlock NAME", - GPGCONF_NAME); + es_fprintf (es_stderr, "usage: %s --%slock NAME", + GPGCONF_NAME, cmd==aDotlockUnlock?"un":""); es_putc ('\n', es_stderr); - es_fputs (_("Need one NAME argument"), es_stderr); + es_fputs ("Need name of file protected by the lock", es_stderr); es_putc ('\n', es_stderr); - gpgconf_failure (GPG_ERR_USER_2); + gpgconf_failure (GPG_ERR_SYNTAX); } else { From bbad0a2644d18c2d7867c7862006c0d011fbdea7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 Jan 2024 15:54:27 +0100 Subject: [PATCH 310/869] gpg: Improve error message for expired default keys. * g10/getkey.c (parse_def_secret_key): Track reason for skipping keys. -- GnuPG-bug-id: 4704 --- g10/getkey.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/g10/getkey.c b/g10/getkey.c index d54edcd7f..b959d77c7 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -2009,8 +2009,9 @@ parse_def_secret_key (ctrl_t ctrl) { gpg_error_t err; KEYDB_SEARCH_DESC desc; - KBNODE kb; - KBNODE node; + kbnode_t kb; + kbnode_t node; + int any_revoked, any_expired, any_disabled; err = classify_user_id (t->d, &desc, 1); if (err) @@ -2053,6 +2054,7 @@ parse_def_secret_key (ctrl_t ctrl) merge_selfsigs (ctrl, kb); + any_revoked = any_expired = any_disabled = 0; err = gpg_error (GPG_ERR_NO_SECKEY); node = kb; do @@ -2062,6 +2064,7 @@ parse_def_secret_key (ctrl_t ctrl) /* Check if the key is valid. */ if (pk->flags.revoked) { + any_revoked = 1; if (DBG_LOOKUP) log_debug ("not using %s as default key, %s", keystr_from_pk (pk), "revoked"); @@ -2069,6 +2072,7 @@ parse_def_secret_key (ctrl_t ctrl) } if (pk->has_expired) { + any_expired = 1; if (DBG_LOOKUP) log_debug ("not using %s as default key, %s", keystr_from_pk (pk), "expired"); @@ -2076,6 +2080,7 @@ parse_def_secret_key (ctrl_t ctrl) } if (pk_is_disabled (pk)) { + any_disabled = 1; if (DBG_LOOKUP) log_debug ("not using %s as default key, %s", keystr_from_pk (pk), "disabled"); @@ -2096,9 +2101,22 @@ parse_def_secret_key (ctrl_t ctrl) { if (! warned && ! opt.quiet) { + gpg_err_code_t ec; + + /* Try to get a better error than no secret key if we + * only know that the public key is not usable. */ + if (any_revoked) + ec = GPG_ERR_CERT_REVOKED; + else if (any_expired) + ec = GPG_ERR_KEY_EXPIRED; + else if (any_disabled) + ec = GPG_ERR_KEY_DISABLED; + else + ec = GPG_ERR_NO_SECKEY; + log_info (_("Warning: not using '%s' as default key: %s\n"), - t->d, gpg_strerror (GPG_ERR_NO_SECKEY)); - print_reported_error (err, GPG_ERR_NO_SECKEY); + t->d, gpg_strerror (ec)); + print_reported_error (err, ec); } } else From 5a6df94a9a4b2a2c16c5184c37e215302574b90b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 12 Jan 2024 10:42:05 +0100 Subject: [PATCH 311/869] speedo: Patch ELF binaries to use built libraries * build-aux/speedo.mk: Remove GUI stuff. Add patchelf feature. * Makefile.am (speedo): New target. -- GnuPG-bug-id: 6710 --- AUTHORS | 2 +- Makefile.am | 7 +- README | 17 +-- build-aux/speedo.mk | 251 ++++++++--------------------------------- common/w32info-rc.h.in | 2 +- configure.ac | 2 +- tests/cms/Makefile.am | 1 + 7 files changed, 66 insertions(+), 216 deletions(-) diff --git a/AUTHORS b/AUTHORS index bd1d528e3..44a755333 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,7 +16,7 @@ List of Copyright holders ========================= Copyright (C) 1997-2019 Werner Koch - Copyright (C) 2003-2023 g10 Code GmbH + Copyright (C) 2003-2024 g10 Code GmbH Copyright (C) 1994-2021 Free Software Foundation, Inc. Copyright (C) 2002 Klarälvdalens Datakonsult AB Copyright (C) 1995-1997, 2000-2007 Ulrich Drepper diff --git a/Makefile.am b/Makefile.am index 1cd009811..67ee98e20 100644 --- a/Makefile.am +++ b/Makefile.am @@ -191,7 +191,7 @@ endif gen_start_date = 2011-12-01T06:00:00 -.PHONY: gen-ChangeLog +.PHONY: gen-ChangeLog stowinstall speedo gen-ChangeLog: if test -e $(top_srcdir)/.git; then \ (cd $(top_srcdir) && \ @@ -207,6 +207,11 @@ gen-ChangeLog: stowinstall: $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/gnupg + +speedo: + $(MAKE) -f $(top_srcdir)/build-aux/speedo.mk native SELFCHECK=0 + + TESTS_ENVIRONMENT = \ LC_ALL=C \ EXEEXT=$(EXEEXT) \ diff --git a/README b/README index 8fc906bb5..02e0fedd4 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ Copyright 1997-2019 Werner Koch Copyright 1998-2021 Free Software Foundation, Inc. - Copyright 2003-2023 g10 Code GmbH + Copyright 2003-2024 g10 Code GmbH * INTRODUCTION @@ -40,7 +40,7 @@ Several other standard libraries are also required. The configure script prints diagnostic messages if one of these libraries is not - available and a feature will not be available.. + available and a feature will not be available. You also need the Pinentry package for most functions of GnuPG; however it is not a build requirement. Pinentry is available at @@ -80,15 +80,16 @@ to view the directories used by GnuPG. +** Quick build method on Unix + To quickly build all required software without installing it, the - Speedo method may be used: + Speedo target may be used: - cd build - make -f ../build-aux/speedo.mk native + make speedo - This method downloads all required libraries and does a native build - of GnuPG to PLAY/inst/. GNU make is required and you need to set - LD_LIBRARY_PATH to $(pwd)/PLAY/inst/lib to test the binaries. + This target downloads all required libraries and does a native build + of GnuPG to PLAY/inst/. GNU make and the patchelf tool are + required. Follow the instructions give at the end of the make run. ** Specific build problems on some machines: diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 7777411e2..0cefebed9 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -94,16 +94,15 @@ # We need to know our own name. SPEEDO_MK := $(realpath $(lastword $(MAKEFILE_LIST))) -.PHONY : help native native-gui w32-installer w32-source w32-wixlib -.PHONY : git-native git-native-gui git-w32-installer git-w32-source -.PHONY : this-native this-native-gui this-w32-installer this-w32-source +.PHONY : help native w32-installer w32-source w32-wixlib +.PHONY : git-native git-w32-installer git-w32-source +.PHONY : this-native this-w32-installer this-w32-source help: @echo 'usage: make -f speedo.mk TARGET' @echo ' with TARGET being one of:' @echo ' help This help' @echo ' native Native build of the GnuPG core' - @echo ' native-gui Ditto but with pinentry and GPA' @echo ' w32-installer Build a Windows installer' @echo ' w32-source Pack a source archive' @echo ' w32-release Build a Windows release' @@ -148,66 +147,54 @@ help-wixlib: SPEEDOMAKE := $(MAKE) -f $(SPEEDO_MK) UPD_SWDB=1 native: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=release WITH_GUI=0 all + $(SPEEDOMAKE) TARGETOS=native WHAT=release all git-native: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=git WITH_GUI=0 all + $(SPEEDOMAKE) TARGETOS=native WHAT=git all this-native: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=this WITH_GUI=0 all - -native-gui: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=release WITH_GUI=1 all - -git-native-gui: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=git WITH_GUI=1 all - -this-native-gui: check-tools - $(SPEEDOMAKE) TARGETOS=native WHAT=this WITH_GUI=1 all + $(SPEEDOMAKE) TARGETOS=native WHAT=this all w32-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 installer + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release installer git-w32-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=git WITH_GUI=0 installer + $(SPEEDOMAKE) TARGETOS=w32 WHAT=git installer this-w32-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=this WITH_GUI=0 \ - CUSTOM_SWDB=1 installer + $(SPEEDOMAKE) TARGETOS=w32 WHAT=this CUSTOM_SWDB=1 installer w32-wixlib: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 wixlib + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release wixlib git-w32-wixlib: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=git WITH_GUI=0 wixlib + $(SPEEDOMAKE) TARGETOS=w32 WHAT=git wixlib this-w32-wixlib: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=this WITH_GUI=0 \ - CUSTOM_SWDB=1 wixlib + $(SPEEDOMAKE) TARGETOS=w32 WHAT=this CUSTOM_SWDB=1 wixlib w32-source: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 dist-source + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release dist-source git-w32-source: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=git WITH_GUI=0 dist-source + $(SPEEDOMAKE) TARGETOS=w32 WHAT=git dist-source this-w32-source: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=this WITH_GUI=0 \ - CUSTOM_SWDB=1 dist-source + $(SPEEDOMAKE) TARGETOS=w32 WHAT=this CUSTOM_SWDB=1 dist-source w32-release: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ installer-from-source w32-msi-release: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ WITH_WIXLIB=1 installer-from-source w32-sign-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ sign-installer w32-release-offline: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release WITH_GUI=0 SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ CUSTOM_SWDB=1 pkgrep=${HOME}/b pkg10rep=${HOME}/b \ installer-from-source @@ -220,9 +207,6 @@ WHAT=git # Set target to "native" or "w32" TARGETOS= -# Set to 1 to build the GUI tools -WITH_GUI=0 - # Set to 1 to use a pre-installed swdb.lst instead of the online version. CUSTOM_SWDB=0 @@ -240,7 +224,7 @@ STATIC=0 TARBALLS=$(shell pwd)/../tarballs # Number of parallel make jobs for each package -MAKE_J=3 +MAKE_J=6 # Name to use for the w32 installer and sources INST_NAME=gnupg-w32 @@ -251,6 +235,9 @@ INSTALL_PREFIX=none # Set this to the location of wixtools WIXPREFIX=$(shell readlink -f ~/w32root/wixtools) +# If patchelf(1) is not availale disable the command. +PATCHELF := $(shell patchelf --version 2>/dev/null >/dev/null || echo "echo please run: ")patchelf + # Read signing information from ~/.gnupg-autogen.rc define READ_AUTOGEN_template $(1) = $$(shell grep '^$(1)=' $$$$HOME/.gnupg-autogen.rc|cut -d= -f2) @@ -324,55 +311,16 @@ speedo_spkgs = \ ifeq ($(TARGETOS),w32) speedo_spkgs += \ zlib bzip2 sqlite -ifeq ($(WITH_GUI),1) -speedo_spkgs += gettext libiconv -endif endif -speedo_spkgs += \ - libassuan libksba - -ifeq ($(TARGETOS),w32) -speedo_spkgs += \ - ntbtls -endif - -speedo_spkgs += \ - gnupg - -ifeq ($(TARGETOS),w32) -ifeq ($(WITH_GUI),1) -speedo_spkgs += \ - libffi glib pkg-config -endif -endif +speedo_spkgs += libassuan libksba ntbtls gnupg ifeq ($(STATIC),0) -speedo_spkgs += \ - gpgme +speedo_spkgs += gpgme endif ifeq ($(TARGETOS),w32) -ifeq ($(WITH_GUI),1) -speedo_spkgs += \ - libpng \ - gdk-pixbuf atk pixman cairo pango gtk+ -endif -endif - -ifeq ($(TARGETOS),w32) - speedo_spkgs += pinentry -ifeq ($(WITH_GUI),1) -speedo_spkgs += gpa gpgex -endif - -else - -ifeq ($(WITH_GUI),1) -speedo_spkgs += pinentry gpa -endif - endif @@ -383,15 +331,12 @@ endif # only used for gpgex and thus we need to build them only if we want # a full installer. speedo_w64_spkgs = -ifeq ($(WITH_GUI),1) -speedo_w64_spkgs += libgpg-error libiconv gettext libassuan gpgex -endif # Packages which use the gnupg autogen.sh build style speedo_gnupg_style = \ libgpg-error npth libgcrypt \ libassuan libksba ntbtls gnupg gpgme \ - pinentry gpa gpgex + pinentry # Packages which use only make and no build directory speedo_make_only_style = \ @@ -451,14 +396,6 @@ pinentry_ver := $(shell awk '$$1=="pinentry_ver" {print $$2}' swdb.lst) pinentry_sha1 := $(shell awk '$$1=="pinentry_sha1" {print $$2}' swdb.lst) pinentry_sha2 := $(shell awk '$$1=="pinentry_sha2" {print $$2}' swdb.lst) -gpa_ver := $(shell awk '$$1=="gpa_ver" {print $$2}' swdb.lst) -gpa_sha1 := $(shell awk '$$1=="gpa_sha1" {print $$2}' swdb.lst) -gpa_sha2 := $(shell awk '$$1=="gpa_sha2" {print $$2}' swdb.lst) - -gpgex_ver := $(shell awk '$$1=="gpgex_ver" {print $$2}' swdb.lst) -gpgex_sha1 := $(shell awk '$$1=="gpgex_sha1" {print $$2}' swdb.lst) -gpgex_sha2 := $(shell awk '$$1=="gpgex_sha2" {print $$2}' swdb.lst) - zlib_ver := $(shell awk '$$1=="zlib_ver" {print $$2}' swdb.lst) zlib_sha1 := $(shell awk '$$1=="zlib_sha1_gz" {print $$2}' swdb.lst) zlib_sha2 := $(shell awk '$$1=="zlib_sha2_gz" {print $$2}' swdb.lst) @@ -474,7 +411,7 @@ sqlite_sha2 := $(shell awk '$$1=="sqlite_sha2_gz" {print $$2}' swdb.lst) $(info Information from the version database) $(info GnuPG ..........: $(gnupg_ver) (building $(gnupg_ver_this))) -$(info Libgpg-error ...: $(libgpg_error_ver)) +$(info GpgRT ..........: $(libgpg_error_ver)) $(info Npth ...........: $(npth_ver)) $(info Libgcrypt ......: $(libgcrypt_ver)) $(info Libassuan ......: $(libassuan_ver)) @@ -485,23 +422,13 @@ $(info SQLite .........: $(sqlite_ver)) $(info NtbTLS .. ......: $(ntbtls_ver)) $(info GPGME ..........: $(gpgme_ver)) $(info Pinentry .......: $(pinentry_ver)) -$(info GPA ............: $(gpa_ver)) -$(info GpgEX.... ......: $(gpgex_ver)) endif # Version number for external packages pkg_config_ver = 0.23 libiconv_ver = 1.14 gettext_ver = 0.18.2.1 -libffi_ver = 3.0.13 -glib_ver = 2.34.3 -libpng_ver = 1.4.12 -gdk_pixbuf_ver = 2.26.5 -atk_ver = 1.32.0 -pango_ver = 1.29.4 -pixman_ver = 0.32.4 -cairo_ver = 1.12.16 -gtk__ver = 2.24.17 + # The GIT repository. Using a local repo is much faster. #gitrep = git://git.gnupg.org @@ -552,10 +479,6 @@ else ifeq ($(WHAT),git) speedo_pkg_gpgme_gitref = master speedo_pkg_pinentry_git = $(gitrep)/pinentry speedo_pkg_pinentry_gitref = master - speedo_pkg_gpa_git = $(gitrep)/gpa - speedo_pkg_gpa_gitref = master - speedo_pkg_gpgex_git = $(gitrep)/gpgex - speedo_pkg_gpgex_gitref = master else ifeq ($(WHAT),release) speedo_pkg_libgpg_error_tar = \ $(pkgrep)/libgpg-error/libgpg-error-$(libgpg_error_ver).tar.bz2 @@ -573,10 +496,6 @@ else ifeq ($(WHAT),release) $(pkgrep)/gpgme/gpgme-$(gpgme_ver).tar.bz2 speedo_pkg_pinentry_tar = \ $(pkgrep)/pinentry/pinentry-$(pinentry_ver).tar.bz2 - speedo_pkg_gpa_tar = \ - $(pkgrep)/gpa/gpa-$(gpa_ver).tar.bz2 - speedo_pkg_gpgex_tar = \ - $(pkg10rep)/gpgex/gpgex-$(gpgex_ver).tar.bz2 else $(error invalid value for WHAT (use on of: git release this)) endif @@ -587,15 +506,6 @@ speedo_pkg_bzip2_tar = $(pkgrep)/bzip2/bzip2-$(bzip2_ver).tar.gz speedo_pkg_sqlite_tar = $(pkgrep)/sqlite/sqlite-autoconf-$(sqlite_ver).tar.gz speedo_pkg_libiconv_tar = $(pkg2rep)/libiconv-$(libiconv_ver).tar.gz speedo_pkg_gettext_tar = $(pkg2rep)/gettext-$(gettext_ver).tar.gz -speedo_pkg_libffi_tar = $(pkg2rep)/libffi-$(libffi_ver).tar.gz -speedo_pkg_glib_tar = $(pkg2rep)/glib-$(glib_ver).tar.xz -speedo_pkg_libpng_tar = $(pkg2rep)/libpng-$(libpng_ver).tar.bz2 -speedo_pkg_gdk_pixbuf_tar = $(pkg2rep)/gdk-pixbuf-$(gdk_pixbuf_ver).tar.xz -speedo_pkg_atk_tar = $(pkg2rep)/atk-$(atk_ver).tar.bz2 -speedo_pkg_pango_tar = $(pkg2rep)/pango-$(pango_ver).tar.bz2 -speedo_pkg_pixman_tar = $(pkg2rep)/pixman-$(pixman_ver).tar.gz -speedo_pkg_cairo_tar = $(pkg2rep)/cairo-$(cairo_ver).tar.xz -speedo_pkg_gtk__tar = $(pkg2rep)/gtk+-$(gtk__ver).tar.xz # @@ -651,25 +561,13 @@ define speedo_pkg_gnupg_post_install endef endif -# The LDFLAGS is needed for -lintl for glib. -ifeq ($(WITH_GUI),1) -speedo_pkg_gpgme_configure = \ - --enable-static --enable-w32-glib \ - --with-gpg-error-prefix=$(idir) \ - LDFLAGS=-L$(idir)/lib -else +# The LDFLAGS was needed for -lintl for glib. speedo_pkg_gpgme_configure = \ --disable-static --disable-w32-glib \ --with-gpg-error-prefix=$(idir) \ LDFLAGS=-L$(idir)/lib -endif -ifeq ($(TARGETOS),w32) -speedo_pkg_pinentry_configure = --disable-pinentry-gtk2 -else -speedo_pkg_pinentry_configure = --enable-pinentry-gtk2 -endif speedo_pkg_pinentry_configure += \ --disable-pinentry-qt5 \ --disable-pinentry-qt \ @@ -680,22 +578,6 @@ speedo_pkg_pinentry_configure += \ CXXFLAGS=-static-libstdc++ -speedo_pkg_gpa_configure = \ - --with-libiconv-prefix=$(idir) --with-libintl-prefix=$(idir) \ - --with-gpgme-prefix=$(idir) --with-zlib=$(idir) \ - --with-libassuan-prefix=$(idir) --with-gpg-error-prefix=$(idir) - -speedo_pkg_gpgex_configure = \ - --with-gpg-error-prefix=$(idir) \ - --with-libassuan-prefix=$(idir) \ - --enable-gpa-only - -speedo_pkg_w64_gpgex_configure = \ - --with-gpg-error-prefix=$(idir6) \ - --with-libassuan-prefix=$(idir6) \ - --enable-gpa-only - - # # External packages # @@ -759,60 +641,6 @@ speedo_pkg_gettext_extracflags = -O2 speedo_pkg_gettext_make_dir = gettext-runtime -speedo_pkg_glib_configure = \ - --disable-modular-tests \ - --with-libiconv=gnu \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib \ - CCC=$(host)-g++ \ - LIBFFI_CFLAGS=-I$(idir)/lib/libffi-$(libffi_ver)/include \ - LIBFFI_LIBS=\"-L$(idir)/lib -lffi\" -ifeq ($(TARGETOS),w32) -speedo_pkg_glib_extracflags = -march=i486 -endif - -ifeq ($(TARGETOS),w32) -speedo_pkg_libpng_configure = \ - CPPFLAGS=\"-I$(idir)/include -DPNG_BUILD_DLL\" \ - LDFLAGS=\"-L$(idir)/lib\" LIBPNG_DEFINES=\"-DPNG_BUILD_DLL\" -else -speedo_pkg_libpng_configure = \ - CPPFLAGS=\"-I$(idir)/include\" \ - LDFLAGS=\"-L$(idir)/lib\" -endif - -ifneq ($(TARGETOS),w32) -speedo_pkg_gdk_pixbuf_configure = --without-libtiff --without-libjpeg -endif - -speedo_pkg_pixman_configure = \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib - -ifeq ($(TARGETOS),w32) -speedo_pkg_cairo_configure = \ - --disable-qt --disable-ft --disable-fc \ - --enable-win32 --enable-win32-font \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib -else -speedo_pkg_cairo_configure = \ - --disable-qt \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib -endif - -speedo_pkg_pango_configure = \ - --disable-gtk-doc \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib - -speedo_pkg_gtk__configure = \ - --disable-cups \ - CPPFLAGS=-I$(idir)/include \ - LDFLAGS=-L$(idir)/lib - - # --------- all: all-speedo @@ -1286,6 +1114,24 @@ clean-pkg-versions: @: >$(bdir)/pkg-versions.txt all-speedo: $(stampdir)/stamp-final +ifneq ($(TARGETOS),w32) + @(set -e;\ + cd "$(idir)"; \ + echo "speedo: Making RPATH relative";\ + for d in bin sbin libexec lib; do \ + for f in $$(find $$d -type f); do \ + if file $$f | grep ELF >/dev/null; then \ + $(PATCHELF) --set-rpath '$$ORIGIN/../lib' $$f; \ + fi; \ + done; \ + done; \ + echo "sysconfdir = /etc" >bin/gpgconf.ctl ;\ + echo "rootdir = $(idir)" >>bin/gpgconf.ctl ;\ + echo "speedo: /*" ;\ + echo "speedo: * Now copy $(idir)/ to the final location and" ;\ + echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly." ;\ + echo "speedo: */") +endif report-speedo: $(addprefix report-,$(speedo_build_list)) @@ -1357,9 +1203,6 @@ $(bdir)/inst-options.ini: $(w32src)/inst-options.ini cat $(w32src)/inst-options.ini >$(bdir)/inst-options.ini extra_installer_options = -ifeq ($(WITH_GUI),1) -extra_installer_options += -DWITH_GUI=1 -endif # Note that we sign only when doing the final installer. installer: all w32_insthelpers $(w32src)/inst-options.ini $(bdir)/README.txt diff --git a/common/w32info-rc.h.in b/common/w32info-rc.h.in index 1e76b58a9..bec152eb2 100644 --- a/common/w32info-rc.h.in +++ b/common/w32info-rc.h.in @@ -29,4 +29,4 @@ built on @BUILD_HOSTNAME@ at @BUILD_TIMESTAMP@\0" #define W32INFO_PRODUCTVERSION "@VERSION@\0" #define W32INFO_LEGALCOPYRIGHT "Copyright \xa9 \ -2023 g10 Code GmbH\0" +2024 g10 Code GmbH\0" diff --git a/configure.ac b/configure.ac index fc0590c14..26d7f7b55 100644 --- a/configure.ac +++ b/configure.ac @@ -525,7 +525,7 @@ AH_BOTTOM([ #define GNUPG_OPENPGP_REVOC_DIR "openpgp-revocs.d" #define GNUPG_CACHE_DIR "cache.d" -#define GNUPG_DEF_COPYRIGHT_LINE "Copyright (C) 2023 g10 Code GmbH" +#define GNUPG_DEF_COPYRIGHT_LINE "Copyright (C) 2024 g10 Code GmbH" /* For some systems (DOS currently), we hardcode the path here. For POSIX systems the values are constructed by the Makefiles, so that diff --git a/tests/cms/Makefile.am b/tests/cms/Makefile.am index b43fb1c91..557729770 100644 --- a/tests/cms/Makefile.am +++ b/tests/cms/Makefile.am @@ -99,6 +99,7 @@ EXTRA_DIST = $(XTESTS) $(KEYS) $(CERTS) $(TEST_FILES) \ samplekeys/opensc-test.p12 \ samplekeys/t5793-openssl.pfx \ samplekeys/t5793-test.pfx \ + samplekeys/t6752-ov-user-ff.p12 \ samplekeys/edward.tester@demo.gnupg.com.p12 \ samplekeys/nistp256-openssl-self-signed.p12 \ samplemsgs/pwri-sample.cbc.p7m \ From 3f12e3dacbe65b4847eb2ba3b19ae6ee82c6217d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 12 Jan 2024 13:25:06 +0100 Subject: [PATCH 312/869] speedo: Add install target for Unix. * build-aux/speedo.mk: Default to SELFCHECK=0. (install, install-speedo): New targets. -- GnuPG-bug-id: 6710 --- README | 11 ++++++-- build-aux/speedo.mk | 67 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/README b/README index 02e0fedd4..13205c275 100644 --- a/README +++ b/README @@ -85,11 +85,18 @@ To quickly build all required software without installing it, the Speedo target may be used: - make speedo + make -f build-aux/speedo.mk native This target downloads all required libraries and does a native build of GnuPG to PLAY/inst/. GNU make and the patchelf tool are - required. Follow the instructions give at the end of the make run. + required. After the build the entire software including all + libraries can be installed into an arbitrary location using for + example: + + make -f build-aux/speedo.mk install SYSROOT=/usr/local/gnupg-foo + + and adding the directory to PATH. + ** Specific build problems on some machines: diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 0cefebed9..be400c37a 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -113,7 +113,7 @@ help: @echo 'Prepend TARGET with "git-" to build from GIT repos.' @echo 'Prepend TARGET with "this-" to build from the source tarball.' @echo 'Use STATIC=1 to build with statically linked libraries.' - @echo 'Use SELFCHECK=0 for a non-released version.' + @echo 'Use SELFCHECK=1 for additional check of the gnupg version.' @echo 'Use CUSTOM_SWDB=1 for an already downloaded swdb.lst.' @echo 'Use WIXPREFIX to provide the WIX binaries for the MSI package.' @echo ' Using WIX also requires wine with installed wine mono.' @@ -182,19 +182,17 @@ this-w32-source: check-tools $(SPEEDOMAKE) TARGETOS=w32 WHAT=this CUSTOM_SWDB=1 dist-source w32-release: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ - installer-from-source + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release installer-from-source w32-msi-release: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release \ WITH_WIXLIB=1 installer-from-source w32-sign-installer: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ - sign-installer + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release sign-installer w32-release-offline: check-tools - $(SPEEDOMAKE) TARGETOS=w32 WHAT=release SELFCHECK=0 \ + $(SPEEDOMAKE) TARGETOS=w32 WHAT=release \ CUSTOM_SWDB=1 pkgrep=${HOME}/b pkg10rep=${HOME}/b \ installer-from-source @@ -213,8 +211,8 @@ CUSTOM_SWDB=0 # Set to 1 to really download the swdb. UPD_SWDB=0 -# Set to 0 to skip the GnuPG version self-check -SELFCHECK=1 +# Set to 1 to run an additional GnuPG version check +SELFCHECK=0 # Set to 1 to build with statically linked libraries. STATIC=0 @@ -645,6 +643,8 @@ speedo_pkg_gettext_make_dir = gettext-runtime all: all-speedo +install: install-speedo + report: report-speedo clean: clean-speedo @@ -1129,10 +1129,55 @@ ifneq ($(TARGETOS),w32) echo "rootdir = $(idir)" >>bin/gpgconf.ctl ;\ echo "speedo: /*" ;\ echo "speedo: * Now copy $(idir)/ to the final location and" ;\ - echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly." ;\ + echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly" ;\ + echo "speedo: * Or run:" ;\ + echo "speedo: * make -f build-aux/speedo.mk install SYSROOT=/somewhere" ;\ echo "speedo: */") endif +# No dependencies for the install target; instead we test whether +# some of the to be installed files are available. This avoids +# accidental rebuilds under a wrong account. +install-speedo: +ifneq ($(TARGETOS),w32) + @(set -e; \ + cd "$(idir)"; \ + if [ x"$$SYSROOT" = x ]; then \ + echo "speedo: ERROR: SYSROOT has not been given";\ + echo "speedo: Set SYSROOT to the desired install directory";\ + echo "speedo: Example:";\ + echo "speedo: make -f build-aux/speedo.mk install SYSROOT=/usr/local";\ + exit 1;\ + fi;\ + if [ ! -d "$$SYSROOT"/bin ]; then if ! mkdir "$$SYSROOT"/bin; then \ + echo "speedo: error creating target directory";\ + exit 1;\ + fi; fi;\ + if ! touch "$$SYSROOT"/bin/gpgconf.ctl; then \ + echo "speedo: Error writing $$SYSROOT/bin/gpgconf.ctl";\ + echo "speedo: Please check the permissions";\ + exit 1;\ + fi;\ + if [ ! -f bin/gpgconf.ctl ]; then \ + echo "speedo: ERROR: Nothing to install";\ + echo "speedo: Please run a build first";\ + echo "speedo: Example:";\ + echo "speedo: make -f build-aux/speedo.mk native";\ + exit 1;\ + fi;\ + echo "speedo: Installing files to $$SYSROOT";\ + find . -type f -executable \ + -exec install -Dm 755 "{}" "$$SYSROOT/{}" \; ;\ + find . -type f \! -executable \ + -exec install -Dm 644 "{}" "$$SYSROOT/{}" \; ;\ + echo "sysconfdir = /etc" > "$$SYSROOT"/bin/gpgconf.ctl ;\ + echo "rootdir = $$SYSROOT" >> "$$SYSROOT"/bin/gpgconf.ctl ;\ + echo '/*' ;\ + echo " * Installation to $$SYSROOT done" ;\ + echo ' */' ) +endif + + report-speedo: $(addprefix report-,$(speedo_build_list)) # Just to check if we caught all stamps. @@ -1408,4 +1453,4 @@ check-tools: $(stampdir)/stamp-directories # Mark phony targets # .PHONY: all all-speedo report-speedo clean-stamps clean-speedo installer \ - w32_insthelpers check-tools clean-pkg-versions + w32_insthelpers check-tools clean-pkg-versions install-speedo install From b97a36f52d8045faeb769ea7a52caedf1f460098 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 12 Jan 2024 16:53:53 +0100 Subject: [PATCH 313/869] Prepare the NEWS -- --- NEWS | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 7b99deeab..4e2d84d67 100644 --- a/NEWS +++ b/NEWS @@ -1,12 +1,97 @@ Noteworthy changes in version 2.4.4 (unreleased) ------------------------------------------------ - * gpgsm: Support ECDSA in de-vs compliance mode. [T6802] + * gpg: Allow to specify seconds since Epoch beyond 2038 on 32-bit + platforms. [T6736] + + * gpg: Fix expiration time when Creation-Date is specified. [T5252] + + * gpg: Add support for Subkey-Expire-Date. [rG96b69c1866] + + * gpg: Add option --with-v5-fingerprint. [T6705] + + * gpg: Fix validity of re-imported keys. [T6399] + + * gpg: Add --list-filter properties sig_expires/sig_expires_d. + [rGbf662d0f93af] + + * gpg: Report BEGIN_ status before examining the input. [T6481] + + * gpg: Don't try to compress a read-only keybox. [T6811] + + * gpg: Choose key from inserted card over a non-inserted + card. [T6831] + + * gpg: Allow to create revocations even with non-compliant algos. + [T6929] + + * gpg: Fix regression in the Revoker keyword of the parameter file. + [T6923] + + * gpg: Improve error message for expired default keys. [T4704] + + * gpgsm: Add --always-trust feature. [T6559] + + * gpgsm: Support ECC certificates in de-vs mode. [T6802] + + * gpgsm: Major rewrite of the PKCS#12 parser. [T6536] + + * gpgsm: No not show the pkcs#12 passphrase in debug output. [T6654] + + * keyboxd: Timeout on failure to get the database lock. [T6838] + + * agent: Update the key stubs only if really modified. [T6829] + + * scd: Add support for certain Starcos 3.2 cards. [rG5304c9b080] + + * scd: Add support for CardOS 5.4 cards. [rG812f988059] + + * scd: Add support for D-Trust 4.1/4.4 cards. [rG0b85a9ac09] + + * scd: Add support for Smartcafe Expert 7.0 cards. [T6919] + + * scd: Add a length check for a new PIN. [T6843] + + * tpm: Fix keytotpm handling in the agent. [rG9909f622f6] + + * tpm: Fixes for the TPM test suite. [T6052] * dirmngr: Avoid starting a second instance on Windows via GPGME based launching. [T6833] - * Fix garbled time output in non-English Windows. [T6741] + * dirmngr: New option --ignore-crl-extensions. [T6545] + + * dirmngr: Support config value "none" to disable the default + keyserver. [T6708] + + * dirmngr: Implement automatic proxy detection on Windows. [T5768] + + * dirmngr: Fix handling of the HTTP Content-Length. [rGa5e33618f4] + + * dirmngr: Add code to support proxy authentication using the + Negotiation method on Windows. [T6719] + + * gpgconf: Add commands --lock and --unlock. [rG93b5ba38dc] + + * gpgconf: Add keyword socketdir to gpgconf.ctl. [rG239c1fdc28] + + * gpgconf: Adjust the -X command for the new VERSION file format. + [T6918] + + * wkd: Use export-clean for gpg-wks-client's --mirror and --create + commands. [rG2c7f7a5a278c] + + * wkd: Make --add-revocs the default in gpg-wks-client. New option + --no-add-revocs. [rG10c937ee68] + + * Remove duplicated backslashes when setting the homedir. [T6833] + + * Ignore attempts to remove the /dev/null device. [T6556] + + * Improve advisory file lock retry strategy. [T3380] + + * Improve the speedo build system for Unix. [T6710] + Release-info: https://dev.gnupg.org/T6578 @@ -26,6 +111,8 @@ Noteworthy changes in version 2.4.3 (2023-07-04) * gpg: New option --no-compress as alias for -z0. + * gpg: Show better error messages for blocked PINs. [T6425] + * gpgsm: Print PROGRESS status lines. Add new --input-size-hint. [T6534] @@ -57,6 +144,8 @@ Noteworthy changes in version 2.4.3 (2023-07-04) * scd: Fix authentication with Administration Key for PIV. [rG25b59cf6ce] + * Fix garbled time output in non-English Windows. [T6741] + See-also: gnupg-announce/2023q3/000480.html Release-info: https://dev.gnupg.org/T6509 @@ -1681,6 +1770,8 @@ Noteworthy changes in version 2.3.0 (2021-04-07) Release dates of 2.2 versions ----------------------------- +Version 2.2.42 (2023-11-28) https://dev.gnupg.org/T6307 +Version 2.2.41 (2022-12-09) https://dev.gnupg.org/T6280 Version 2.2.40 (2022-10-10) https://dev.gnupg.org/T6181 Version 2.2.39 (2022-09-02) https://dev.gnupg.org/T6175 Version 2.2.38 (2022-09-01) https://dev.gnupg.org/T6159 From 3d60ad5c8c435890d08ae4afa9efccd5bfd4ea58 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Mon, 15 Jan 2024 08:26:57 +0100 Subject: [PATCH 314/869] po: Fix indentation for key generation options -- --- po/ca.po | 10 +++++----- po/da.po | 10 +++++----- po/de.po | 6 +++--- po/el.po | 12 ++++++------ po/eo.po | 12 ++++++------ po/es.po | 8 ++++---- po/et.po | 12 ++++++------ po/fi.po | 12 ++++++------ po/fr.po | 2 +- po/gl.po | 12 ++++++------ po/hu.po | 12 ++++++------ po/id.po | 36 ++++++++++++++++++------------------ po/it.po | 6 +++--- po/nb.po | 2 +- po/pl.po | 8 ++++---- po/ro.po | 6 +++--- po/sk.po | 12 ++++++------ po/sv.po | 10 +++++----- po/uk.po | 4 ++-- po/zh_TW.po | 10 +++++----- 20 files changed, 101 insertions(+), 101 deletions(-) diff --git a/po/ca.po b/po/ca.po index d6840dbc1..9b7cd8d1c 100644 --- a/po/ca.po +++ b/po/ca.po @@ -4535,24 +4535,24 @@ msgstr " (predeterminat)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (només signar)\n" +msgstr " (%d) DSA (només signar)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) DSA (només signar)\n" +msgstr " (%d) DSA (només signar)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (només xifrar)\n" +msgstr " (%d) RSA (només xifrar)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (només xifrar)\n" +msgstr " (%d) RSA (només xifrar)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (només xifrar)\n" +msgstr " (%d) RSA (només xifrar)\n" #, fuzzy msgid "Enter the keygrip: " diff --git a/po/da.po b/po/da.po index 011ea7d0d..a2b7ef163 100644 --- a/po/da.po +++ b/po/da.po @@ -4553,27 +4553,27 @@ msgstr "" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (kun underskriv)\n" +msgstr " (%d) DSA (kun underskriv)\n" #, fuzzy, c-format #| msgid " (%d) DSA (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) DSA (angiv dine egne evner)\n" +msgstr " (%d) DSA (angiv dine egne evner)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (kun krypter)\n" +msgstr " (%d) RSA (kun krypter)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Eksisterende nøgle\n" +msgstr " (%d) Eksisterende nøgle\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Eksisterende nøgle fra kort\n" +msgstr " (%d) Eksisterende nøgle fra kort\n" # key grip # chiefly ( US ) See also grip the person in charge of moving and setting up camera diff --git a/po/de.po b/po/de.po index 04ed2a697..7afa2d086 100644 --- a/po/de.po +++ b/po/de.po @@ -4245,11 +4245,11 @@ msgstr " (%d) ECC (nur verschlüsseln)%s\n" #, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) Vorhandener Schlüssel%s\n" +msgstr " (%d) Vorhandener Schlüssel%s\n" #, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Vorhandener Schlüssel auf der Karte%s\n" +msgstr " (%d) Vorhandener Schlüssel auf der Karte%s\n" msgid "Enter the keygrip: " msgstr "Geben Sie den \"Keygrip\" ein: " @@ -9406,7 +9406,7 @@ msgstr "Verwaltung der Kommandohistorie" #~ msgstr "Werte das Vertrauen zu Signaturen durch gültige PKA-Daten auf" #~ msgid " (%d) ECC and ECC\n" -#~ msgstr " (%d) ECC und ECC\n" +#~ msgstr " (%d) ECC und ECC\n" #~ msgid "honor the PKA record set on a key when retrieving keys" #~ msgstr "Die im Schlüssel enthaltenen PKA-Daten beim Schlüsselholen beachten" diff --git a/po/el.po b/po/el.po index 7d4e8e738..08f85c82c 100644 --- a/po/el.po +++ b/po/el.po @@ -4431,24 +4431,24 @@ msgstr " (προκαθορισμένο)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (για υπογραφή μόνο)\n" +msgstr " (%d) DSA (για υπογραφή μόνο)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" +msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" +msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" +msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" +msgstr " (%d) RSA (για κρυπτογράφηση μόνο)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11225,7 +11225,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (υπογραφή και κρυπτογράφηση)\n" +#~ msgstr " (%d) RSA (υπογραφή και κρυπτογράφηση)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: αδυναμία πρόσβασης του: %s\n" diff --git a/po/eo.po b/po/eo.po index a142ce1aa..d77143896 100644 --- a/po/eo.po +++ b/po/eo.po @@ -4395,24 +4395,24 @@ msgstr "malĉifri datenojn (implicita elekto)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (nur subskribi)\n" +msgstr " (%d) DSA (nur subskribi)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (nur ĉifri)\n" +msgstr " (%d) RSA (nur ĉifri)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (nur ĉifri)\n" +msgstr " (%d) RSA (nur ĉifri)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (nur ĉifri)\n" +msgstr " (%d) RSA (nur ĉifri)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (nur ĉifri)\n" +msgstr " (%d) RSA (nur ĉifri)\n" #, fuzzy msgid "Enter the keygrip: " @@ -10993,7 +10993,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (subskribi kaj ĉifri)\n" +#~ msgstr " (%d) RSA (subskribi kaj ĉifri)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: ne povas malfermi: %s\n" diff --git a/po/es.po b/po/es.po index 4409ce443..635084915 100644 --- a/po/es.po +++ b/po/es.po @@ -4297,22 +4297,22 @@ msgstr " (%d) ECC (sólo firmar)\n" #, fuzzy, c-format #| msgid " (%d) ECC (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) ECC (permite elegir capacidades)\n" +msgstr " (%d) ECC (permite elegir capacidades)\n" #, fuzzy, c-format #| msgid " (%d) ECC (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) ECC (sólo cifrar)\n" +msgstr " (%d) ECC (sólo cifrar)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Clave existente\n" +msgstr " (%d) Clave existente\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Clave existente de la tarjeta\n" +msgstr " (%d) Clave existente de la tarjeta\n" msgid "Enter the keygrip: " msgstr "Introduzca keygrip: " diff --git a/po/et.po b/po/et.po index 5e106d6f5..1f07b58fc 100644 --- a/po/et.po +++ b/po/et.po @@ -4391,24 +4391,24 @@ msgstr " (vaikimisi)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (ainult allkirjastamiseks)\n" +msgstr " (%d) DSA (ainult allkirjastamiseks)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (ainult krüpteerimiseks)\n" +msgstr " (%d) RSA (ainult krüpteerimiseks)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (ainult krüpteerimiseks)\n" +msgstr " (%d) RSA (ainult krüpteerimiseks)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (ainult krüpteerimiseks)\n" +msgstr " (%d) RSA (ainult krüpteerimiseks)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (ainult krüpteerimiseks)\n" +msgstr " (%d) RSA (ainult krüpteerimiseks)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11089,7 +11089,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (allkirjastamiseks ja krüptimiseks)\n" +#~ msgstr " (%d) RSA (allkirjastamiseks ja krüptimiseks)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: ei õnnestu avada: %s\n" diff --git a/po/fi.po b/po/fi.po index 3af8e811e..4248372d3 100644 --- a/po/fi.po +++ b/po/fi.po @@ -4420,24 +4420,24 @@ msgstr " (oletusarvo)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (vain allekirjoitus)\n" +msgstr " (%d) DSA (vain allekirjoitus)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (vain salaus)\n" +msgstr " (%d) RSA (vain salaus)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (vain salaus)\n" +msgstr " (%d) RSA (vain salaus)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (vain salaus)\n" +msgstr " (%d) RSA (vain salaus)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (vain salaus)\n" +msgstr " (%d) RSA (vain salaus)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11195,7 +11195,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (salaus ja allekirjoitus)\n" +#~ msgstr " (%d) RSA (salaus ja allekirjoitus)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: ei voida avata kohdetta: %s\n" diff --git a/po/fr.po b/po/fr.po index 6530e7768..e7ea9ffc2 100644 --- a/po/fr.po +++ b/po/fr.po @@ -4465,7 +4465,7 @@ msgstr " (%d) Clef existante\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Clef existante sur la carte\n" +msgstr " (%d) Clef existante sur la carte\n" msgid "Enter the keygrip: " msgstr "Entrez le keygrip : " diff --git a/po/gl.po b/po/gl.po index d6972580a..73e3ff463 100644 --- a/po/gl.po +++ b/po/gl.po @@ -4427,24 +4427,24 @@ msgstr " (por defecto)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (só asinar)\n" +msgstr " (%d) DSA (só asinar)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (só cifrar)\n" +msgstr " (%d) RSA (só cifrar)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (só cifrar)\n" +msgstr " (%d) RSA (só cifrar)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (só cifrar)\n" +msgstr " (%d) RSA (só cifrar)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (só cifrar)\n" +msgstr " (%d) RSA (só cifrar)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11216,7 +11216,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (asinar e cifrar)\n" +#~ msgstr " (%d) RSA (asinar e cifrar)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: non se pode abrir: %s\n" diff --git a/po/hu.po b/po/hu.po index e875d074b..a0e96c94d 100644 --- a/po/hu.po +++ b/po/hu.po @@ -4396,24 +4396,24 @@ msgstr " (alapértelmezés)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (csak aláírás)\n" +msgstr " (%d) DSA (csak aláírás)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (csak titkosítás)\n" +msgstr " (%d) RSA (csak titkosítás)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (csak titkosítás)\n" +msgstr " (%d) RSA (csak titkosítás)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (csak titkosítás)\n" +msgstr " (%d) RSA (csak titkosítás)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (csak titkosítás)\n" +msgstr " (%d) RSA (csak titkosítás)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11148,7 +11148,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (aláírás és titkosítás)\n" +#~ msgstr " (%d) RSA (aláírás és titkosítás)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s-t nem tudom megnyitni: %s.\n" diff --git a/po/id.po b/po/id.po index 363bad315..259fe9937 100644 --- a/po/id.po +++ b/po/id.po @@ -1585,11 +1585,11 @@ msgstr "Silakan pilih kunci yang anda inginkan:\n" #, fuzzy, c-format msgid " (%d) RSA\n" -msgstr " (%d) RSA (hanya menandai)\n" +msgstr " (%d) RSA (hanya menandai)\n" #, fuzzy, c-format msgid " (%d) ECC\n" -msgstr " (%d) DSA dan ElGamal (baku)\n" +msgstr " (%d) DSA dan ElGamal (baku)\n" msgid "Invalid selection.\n" msgstr "Pilihan tidak valid.\n" @@ -4360,43 +4360,43 @@ msgstr "" #, fuzzy, c-format msgid " (%d) RSA and RSA%s\n" -msgstr " (%d) DSA dan ElGamal (baku)\n" +msgstr " (%d) DSA dan ElGamal (baku)\n" #, fuzzy, c-format msgid " (%d) DSA and Elgamal%s\n" -msgstr " (%d) DSA dan ElGamal (baku)\n" +msgstr " (%d) DSA dan ElGamal (baku)\n" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) DSA (sign only)%s\n" -msgstr " (%d) DSA (hanya menandai)\n" +msgstr " (%d) DSA (hanya menandai)\n" #, fuzzy, c-format #| msgid " (%d) RSA (sign only)\n" msgid " (%d) RSA (sign only)%s\n" -msgstr " (%d) RSA (hanya menandai)\n" +msgstr " (%d) RSA (hanya menandai)\n" #, fuzzy, c-format msgid " (%d) Elgamal (encrypt only)%s\n" -msgstr " (%d) ElGamal (hanya enkripsi)\n" +msgstr " (%d) ElGamal (hanya enkripsi)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) RSA (encrypt only)%s\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" #, fuzzy, c-format msgid " (%d) DSA (set your own capabilities)%s\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" #, fuzzy, c-format msgid " (%d) RSA (set your own capabilities)%s\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" #, fuzzy, c-format #| msgid " (%d) ElGamal (sign and encrypt)\n" msgid " (%d) ECC (sign and encrypt)%s\n" -msgstr " (%d) ElGamal (tandai dan enkripsi)\n" +msgstr " (%d) ElGamal (tandai dan enkripsi)\n" #, fuzzy #| msgid " (default)" @@ -7461,7 +7461,7 @@ msgstr "" #, fuzzy, c-format msgid " (%d) Existing key\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" #, c-format msgid " (%d) Existing key from card\n" @@ -7477,11 +7477,11 @@ msgstr " (%d) RSA (tandai dan enkripsi)\n" #, fuzzy, c-format msgid " (%d) sign\n" -msgstr " (%d) DSA (hanya menandai)\n" +msgstr " (%d) DSA (hanya menandai)\n" #, fuzzy, c-format msgid " (%d) encrypt\n" -msgstr " (%d) RSA (hanya enkripsi)\n" +msgstr " (%d) RSA (hanya enkripsi)\n" msgid "Enter the X.509 subject name: " msgstr "" @@ -9502,7 +9502,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) ECC and ECC\n" -#~ msgstr " (%d) DSA dan ElGamal (baku)\n" +#~ msgstr " (%d) DSA dan ElGamal (baku)\n" #, fuzzy #~ msgid "run without asking a user" @@ -11140,7 +11140,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (auth only)\n" -#~ msgstr " (%d) RSA (hanya menandai)\n" +#~ msgstr " (%d) RSA (hanya menandai)\n" #, fuzzy #~ msgid " (%d) RSA (sign and auth)\n" @@ -11148,11 +11148,11 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (encrypt and auth)\n" -#~ msgstr " (%d) RSA (hanya enkripsi)\n" +#~ msgstr " (%d) RSA (hanya enkripsi)\n" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (tandai dan enkripsi)\n" +#~ msgstr " (%d) RSA (tandai dan enkripsi)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: tidak dapat membuka: %s\n" diff --git a/po/it.po b/po/it.po index 8f04c7afa..f301780da 100644 --- a/po/it.po +++ b/po/it.po @@ -4228,7 +4228,7 @@ msgstr " *predefinito*" #, c-format msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (firma solo)\n" +msgstr " (%d) DSA (firma solo)\n" #, c-format msgid " (%d) ECC (set your own capabilities)%s\n" @@ -7286,7 +7286,7 @@ msgstr "" #, c-format msgid " (%d) Existing key\n" -msgstr " (%d) Chiave esistente\n" +msgstr " (%d) Chiave esistente\n" #, c-format msgid " (%d) Existing key from card\n" @@ -7298,7 +7298,7 @@ msgstr "Azioni possibili per una chiave %s: \n" #, c-format msgid " (%d) sign, encrypt\n" -msgstr " (%d) segno, cifra\n" +msgstr " (%d) segno, cifra\n" #, c-format msgid " (%d) sign\n" diff --git a/po/nb.po b/po/nb.po index 922cb4957..dcbd64efa 100644 --- a/po/nb.po +++ b/po/nb.po @@ -4282,7 +4282,7 @@ msgstr " (%d) Nøkkel\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Nøkkel fra kort\n" +msgstr " (%d) Nøkkel fra kort\n" msgid "Enter the keygrip: " msgstr "Skriv inn nøkkelgrep: " diff --git a/po/pl.po b/po/pl.po index dcbab2240..459d3160c 100644 --- a/po/pl.po +++ b/po/pl.po @@ -4273,22 +4273,22 @@ msgstr "" #, c-format msgid " (%d) ECC (sign only)\n" -msgstr " (%d) ECC (tylko do podpisywania)\n" +msgstr " (%d) ECC (tylko do podpisywania)\n" #, fuzzy, c-format #| msgid " (%d) ECC (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) ECC (możliwości do ustawienia)\n" +msgstr " (%d) ECC (możliwości do ustawienia)\n" #, fuzzy, c-format #| msgid " (%d) ECC (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) ECC (tylko do szyfrowania)\n" +msgstr " (%d) ECC (tylko do szyfrowania)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Istniejący klucz\n" +msgstr " (%d) Istniejący klucz\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" diff --git a/po/ro.po b/po/ro.po index b32a1dcd5..ab6fe8396 100644 --- a/po/ro.po +++ b/po/ro.po @@ -4464,17 +4464,17 @@ msgstr "(implicit)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (numai semnare)\n" +msgstr " (%d) DSA (numai semnare)\n" #, fuzzy, c-format #| msgid " (%d) DSA (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) DSA (setează singur capabilităţile)\n" +msgstr " (%d) DSA (setează singur capabilităţile)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (numai cifrare)\n" +msgstr " (%d) RSA (numai cifrare)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" diff --git a/po/sk.po b/po/sk.po index 743ce6b0a..e730decf0 100644 --- a/po/sk.po +++ b/po/sk.po @@ -4417,24 +4417,24 @@ msgstr "dešifrovať dáta (implicitne)" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (len na podpis)\n" +msgstr " (%d) DSA (len na podpis)\n" #, fuzzy, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) RSA (len na šifrovanie)\n" +msgstr " (%d) RSA (len na šifrovanie)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (len na šifrovanie)\n" +msgstr " (%d) RSA (len na šifrovanie)\n" #, fuzzy, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) RSA (len na šifrovanie)\n" +msgstr " (%d) RSA (len na šifrovanie)\n" #, fuzzy, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) RSA (len na šifrovanie)\n" +msgstr " (%d) RSA (len na šifrovanie)\n" #, fuzzy msgid "Enter the keygrip: " @@ -11179,7 +11179,7 @@ msgstr "" #, fuzzy #~ msgid " (%d) RSA (sign, encrypt and auth)\n" -#~ msgstr " (%d) RSA (pro šifrování a podpis)\n" +#~ msgstr " (%d) RSA (pro šifrování a podpis)\n" #~ msgid "%s: can't open: %s\n" #~ msgstr "%s: nemôžem otvoriť: %s\n" diff --git a/po/sv.po b/po/sv.po index 2a62fe1d7..5fcf6532c 100644 --- a/po/sv.po +++ b/po/sv.po @@ -4623,27 +4623,27 @@ msgstr "" #, fuzzy, c-format #| msgid " (%d) DSA (sign only)\n" msgid " (%d) ECC (sign only)\n" -msgstr " (%d) DSA (endast signering)\n" +msgstr " (%d) DSA (endast signering)\n" #, fuzzy, c-format #| msgid " (%d) DSA (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) DSA (ställ in dina egna förmågor)\n" +msgstr " (%d) DSA (ställ in dina egna förmågor)\n" #, fuzzy, c-format #| msgid " (%d) RSA (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) RSA (endast kryptering)\n" +msgstr " (%d) RSA (endast kryptering)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Befintlig nyckel\n" +msgstr " (%d) Befintlig nyckel\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Befintlig nyckel från kort\n" +msgstr " (%d) Befintlig nyckel från kort\n" msgid "Enter the keygrip: " msgstr "Ange nyckelhashen: " diff --git a/po/uk.po b/po/uk.po index 730e9e135..c3e927947 100644 --- a/po/uk.po +++ b/po/uk.po @@ -4335,12 +4335,12 @@ msgstr " (%d) ECC (лише шифрування)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) Вже записаний ключ\n" +msgstr " (%d) Вже записаний ключ\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Вже записаний ключ з картки\n" +msgstr " (%d) Вже записаний ключ з картки\n" msgid "Enter the keygrip: " msgstr "Вкажіть keygrip: " diff --git a/po/zh_TW.po b/po/zh_TW.po index f14cce879..4cb6f64bb 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -4293,27 +4293,27 @@ msgstr "" #, c-format msgid " (%d) ECC (sign only)\n" -msgstr " (%d) ECC (僅能用於簽署)\n" +msgstr " (%d) ECC (僅能用於簽署)\n" #, fuzzy, c-format #| msgid " (%d) ECC (set your own capabilities)\n" msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) ECC (你能自己設定性能)\n" +msgstr " (%d) ECC (你能自己設定性能)\n" #, fuzzy, c-format #| msgid " (%d) ECC (encrypt only)\n" msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) ECC (僅能用於加密)\n" +msgstr " (%d) ECC (僅能用於加密)\n" #, fuzzy, c-format #| msgid " (%d) Existing key\n" msgid " (%d) Existing key%s\n" -msgstr " (%d) 現有的金鑰\n" +msgstr " (%d) 現有的金鑰\n" #, fuzzy, c-format #| msgid " (%d) Existing key from card\n" msgid " (%d) Existing key from card%s\n" -msgstr " (%d) 卡片上現存的金鑰\n" +msgstr " (%d) 卡片上現存的金鑰\n" msgid "Enter the keygrip: " msgstr "請輸入金鑰鑰柄: " From 092154e17e885616340d7b1f7ecaf5cab4b2baa8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 15 Jan 2024 09:13:46 +0100 Subject: [PATCH 315/869] gpgsm: Improve the status line for --verify errors. * sm/verify.c (gpgsm_verify): Improve verify.leave status line. -- Suggested-by: Jakob Bohm --- sm/verify.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sm/verify.c b/sm/verify.c index e83a24f44..f5d7341ef 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -756,7 +756,12 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) char numbuf[50]; sprintf (numbuf, "%d", rc ); gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave", - numbuf, NULL); + numbuf, + gpg_err_code (rc) == GPG_ERR_EPIPE? + "-- (Broken pipe on input or output)": + gpg_err_code (rc) == GPG_ERR_EOF? + "-- (End of file)" : NULL, + NULL); } return rc; From 0cb622d632f732c24a5d312baf2c6e453775eb10 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 15 Jan 2024 09:55:55 +0100 Subject: [PATCH 316/869] gpgsm: Allow parsing of PKCS#12 files with two private keys. * sm/minip12.c (struct p12_parse_ctx_s): Add privatekey2. (parse_shrouded_key_bag): Handle a second private key. (p12_parse_free_kparms): New. * sm/import.c (parse_p12): Factor some code out to ... (p12_to_skey): this. (parse_p12): Use p12_parse_free_kparms. -- Take care: We allow parsing of a second private key but we are not yet able to import the second private key. The whole things is required to at least import the certificates of current pkcs#12 files as created by the German Elster tax system. No test data, sorry. --- sm/import.c | 157 +++++++++++++++++++++++++------------------------ sm/minip12.c | 58 +++++++++++++++--- sm/minip12.h | 1 + sm/t-minip12.c | 8 +-- 4 files changed, 133 insertions(+), 91 deletions(-) diff --git a/sm/import.c b/sm/import.c index 5a193ef52..cbf8fa627 100644 --- a/sm/import.c +++ b/sm/import.c @@ -692,6 +692,85 @@ store_cert_cb (void *opaque, } +/* Helper for parse_p12. */ +static gpg_error_t +p12_to_skey (gcry_mpi_t *kparms, const char *curve, gcry_sexp_t *r_skey) +{ + gpg_error_t err = 0; + struct rsa_secret_key_s sk; + gcry_ctx_t ecctx = NULL; + + if (curve) + { + /* log_debug ("curve: %s\n", curve); */ + /* gcry_log_debugmpi ("MPI[0]", kparms[0]); */ + + /* We need to get the public key. */ + err = gcry_mpi_ec_new (&ecctx, NULL, curve); + if (err) + { + log_error ("error creating context for curve '%s': %s\n", + curve, gpg_strerror (err)); + goto leave; + } + err = gcry_mpi_ec_set_mpi ("d", kparms[0], ecctx); + if (err) + { + log_error ("error setting 'd' into context of curve '%s': %s\n", + curve, gpg_strerror (err)); + goto leave; + } + + kparms[1] = gcry_mpi_ec_get_mpi ("q", ecctx, 1); + if (!kparms[1]) + { + log_error ("error computing 'q' from 'd' for curve '%s'\n", curve); + goto leave; + } + + err = gcry_sexp_build (r_skey, NULL, + "(private-key(ecc(curve %s)(q%m)(d%m)))", + curve, kparms[1], kparms[0], NULL); + } + else /* RSA */ + { + /* print_mpi (" n", kparms[0]); */ + /* print_mpi (" e", kparms[1]); */ + /* print_mpi (" d", kparms[2]); */ + /* print_mpi (" p", kparms[3]); */ + /* print_mpi (" q", kparms[4]); */ + /* print_mpi ("dmp1", kparms[5]); */ + /* print_mpi ("dmq1", kparms[6]); */ + /* print_mpi (" u", kparms[7]); */ + + sk.n = kparms[0]; + sk.e = kparms[1]; + sk.d = kparms[2]; + sk.q = kparms[3]; + sk.p = kparms[4]; + sk.u = kparms[7]; + err = rsa_key_check (&sk); + if (err) + goto leave; + /* print_mpi (" n", sk.n); */ + /* print_mpi (" e", sk.e); */ + /* print_mpi (" d", sk.d); */ + /* print_mpi (" p", sk.p); */ + /* print_mpi (" q", sk.q); */ + /* print_mpi (" u", sk.u); */ + + /* Create an S-expression from the parameters. */ + err = gcry_sexp_build (r_skey, NULL, + "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", + sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL); + } + + leave: + gcry_ctx_release (ecctx); + return err; +} + + /* Assume that the reader is at a pkcs#12 message and try to import certificates from that stupid format. We will transfer secret keys to the agent. */ @@ -706,7 +785,6 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats) size_t p12buflen; size_t p12bufoff; gcry_mpi_t *kparms = NULL; - struct rsa_secret_key_s sk; char *passphrase = NULL; unsigned char *key = NULL; size_t keylen; @@ -792,82 +870,9 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats) goto leave; } - if (curve) - { - gcry_ctx_t ecctx = NULL; - /* log_debug ("curve: %s\n", curve); */ - /* gcry_log_debugmpi ("MPI[0]", kparms[0]); */ - - /* We need to get the public key. */ - err = gcry_mpi_ec_new (&ecctx, NULL, curve); - if (err) - { - log_error ("error creating context for curve '%s': %s\n", - curve, gpg_strerror (err)); - goto leave; - } - err = gcry_mpi_ec_set_mpi ("d", kparms[0], ecctx); - if (err) - { - log_error ("error setting 'd' into context of curve '%s': %s\n", - curve, gpg_strerror (err)); - gcry_ctx_release (ecctx); - goto leave; - } - - kparms[1] = gcry_mpi_ec_get_mpi ("q", ecctx, 1); - if (!kparms[1]) - { - log_error ("error computing 'q' from 'd' for curve '%s'\n", curve); - gcry_ctx_release (ecctx); - goto leave; - } - - gcry_ctx_release (ecctx); - - err = gcry_sexp_build (&s_key, NULL, - "(private-key(ecc(curve %s)(q%m)(d%m)))", - curve, kparms[1], kparms[0], NULL); - } - else /* RSA */ - { - /* print_mpi (" n", kparms[0]); */ - /* print_mpi (" e", kparms[1]); */ - /* print_mpi (" d", kparms[2]); */ - /* print_mpi (" p", kparms[3]); */ - /* print_mpi (" q", kparms[4]); */ - /* print_mpi ("dmp1", kparms[5]); */ - /* print_mpi ("dmq1", kparms[6]); */ - /* print_mpi (" u", kparms[7]); */ - - sk.n = kparms[0]; - sk.e = kparms[1]; - sk.d = kparms[2]; - sk.q = kparms[3]; - sk.p = kparms[4]; - sk.u = kparms[7]; - err = rsa_key_check (&sk); - if (err) - goto leave; - /* print_mpi (" n", sk.n); */ - /* print_mpi (" e", sk.e); */ - /* print_mpi (" d", sk.d); */ - /* print_mpi (" p", sk.p); */ - /* print_mpi (" q", sk.q); */ - /* print_mpi (" u", sk.u); */ - - /* Create an S-expression from the parameters. */ - err = gcry_sexp_build (&s_key, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL); - } - - /* The next is very ugly - we really should not rely on our - * knowledge of p12_parse internals. */ - for (i=0; i < 8; i++) - gcry_mpi_release (kparms[i]); - gcry_free (kparms); + err = p12_to_skey (kparms, curve, &s_key); + p12_parse_free_kparms (kparms); kparms = NULL; if (err) { diff --git a/sm/minip12.c b/sm/minip12.c index 1bbe126ae..2e7b50e1c 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -168,6 +168,9 @@ struct p12_parse_ctx_s /* The private key as an MPI array. */ gcry_mpi_t *privatekey; + + /* A second private key as an MPI array. */ + gcry_mpi_t *privatekey2; }; @@ -1248,6 +1251,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) int is_pbes2 = 0; int is_aes256 = 0; int digest_algo = GCRY_MD_SHA1; + gcry_mpi_t *privatekey; where = "shrouded_key_bag"; if (opt_verbose) @@ -1565,19 +1569,26 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) if (tlv_expect_sequence (tlv)) goto bailout; - if (ctx->privatekey) + if (ctx->privatekey2) { err = gpg_error (GPG_ERR_DUP_VALUE); - log_error ("a private key has already been received\n"); + log_error ("two private kesy have already been received\n"); goto bailout; } - ctx->privatekey = gcry_calloc (10, sizeof *ctx->privatekey); - if (!ctx->privatekey) + privatekey = gcry_calloc (10, sizeof *privatekey); + if (!privatekey) { err = gpg_error_from_syserror (); log_error ("error allocating privatekey element array\n"); goto bailout; } + if (ctx->privatekey) + { + log_info ("a private key has already been received - reading second\n"); + ctx->privatekey2 = privatekey; + } + else + ctx->privatekey = privatekey; where = "shrouded_key_bag.reading.key-parameters"; if (ctx->curve) /* ECC case. */ @@ -1600,7 +1611,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) goto bailout; if (opt_verbose > 1) log_printhex (data, datalen, "ecc q="); - err = gcry_mpi_scan (ctx->privatekey, GCRYMPI_FMT_USG, + err = gcry_mpi_scan (privatekey, GCRYMPI_FMT_USG, data, datalen, NULL); if (err) { @@ -1623,7 +1634,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) } err = tlv_expect_mpinteger (tlv, firstparam, - ctx->privatekey+keyelem_count); + privatekey+keyelem_count); if (firstparam && gpg_err_code (err) == GPG_ERR_FALSE) ; /* Ignore the first value iff it is zero. */ else if (err) @@ -1918,6 +1929,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, size_t oidlen; int intval; unsigned int startlevel; + int i; *r_badpass = 0; @@ -2037,6 +2049,15 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, else gcry_free (ctx.curve); + /* We have no way yet to return the second private key. */ + if (ctx.privatekey2) + { + for (i=0; ctx.privatekey2[i]; i++) + gcry_mpi_release (ctx.privatekey2[i]); + gcry_free (ctx.privatekey2); + ctx.privatekey2 = NULL; + } + return ctx.privatekey; bailout: @@ -2050,13 +2071,18 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, gpg_strerror (err)); if (ctx.privatekey) { - int i; - for (i=0; ctx.privatekey[i]; i++) gcry_mpi_release (ctx.privatekey[i]); gcry_free (ctx.privatekey); ctx.privatekey = NULL; } + if (ctx.privatekey2) + { + for (i=0; ctx.privatekey2[i]; i++) + gcry_mpi_release (ctx.privatekey2[i]); + gcry_free (ctx.privatekey2); + ctx.privatekey2 = NULL; + } tlv_parser_release (tlv); gcry_free (ctx.curve); if (r_curve) @@ -2065,6 +2091,22 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, } +/* Free the parameters as returned by p12_parse. */ +void +p12_parse_free_kparms (gcry_mpi_t *kparms) +{ + int i; + + if (kparms) + { + for (i=0; i < 8; i++) + gcry_mpi_release (kparms[i]); + gcry_free (kparms); + } +} + + + static size_t compute_tag_length (size_t n) diff --git a/sm/minip12.h b/sm/minip12.h index 654cab0e6..00569cd86 100644 --- a/sm/minip12.h +++ b/sm/minip12.h @@ -29,6 +29,7 @@ gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length, const char *pw, void (*certcb)(void*, const unsigned char*, size_t), void *certcbarg, int *r_badpass, char **r_curve); +void p12_parse_free_kparms (gcry_mpi_t *kparms); unsigned char *p12_build (gcry_mpi_t *kparms, const void *cert, size_t certlen, diff --git a/sm/t-minip12.c b/sm/t-minip12.c index bf3177ea0..75c1545d6 100644 --- a/sm/t-minip12.c +++ b/sm/t-minip12.c @@ -580,13 +580,7 @@ run_one_test (const char *name, const char *desc, const char *pass, ret = 0; } - if (result) - { - int i; - for (i=0; result[i]; i++) - gcry_mpi_release (result[i]); - gcry_free (result); - } + p12_parse_free_kparms (result); xfree (certstr); xfree (resulthash); xfree (curve); From 4cdfc1d0d903855f28b891485aa3a08a7d0c64d3 Mon Sep 17 00:00:00 2001 From: Jakub Bogusz Date: Mon, 15 Jan 2024 11:28:00 +0100 Subject: [PATCH 317/869] po: Update parts of the Polish translation -- Jakub provided the translation in October but at this time it did cleanly apply anymore due to string changes. Thus only parts of his changes are here. -wk --- po/pl.po | 395 ++++++++++++++++++++----------------------------------- 1 file changed, 139 insertions(+), 256 deletions(-) diff --git a/po/pl.po b/po/pl.po index 459d3160c..d9d98e9d2 100644 --- a/po/pl.po +++ b/po/pl.po @@ -2,13 +2,13 @@ # Copyright (C) 1998, 1999, 2000, 2001, 2002, # 2007 Free Software Foundation, Inc. # Janusz A. Urbanowicz , 1999, 2000, 2001, 2002, 2003-2004 -# Jakub Bogusz , 2003-2020. +# Jakub Bogusz , 2003-2023. # msgid "" msgstr "" -"Project-Id-Version: gnupg-2.2.24\n" +"Project-Id-Version: gnupg-2.4.3\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2020-11-18 17:35+0100\n" +"PO-Revision-Date: 2023-10-20 21:29+0200\n" "Last-Translator: Jakub Bogusz \n" "Language-Team: Polish \n" "Language: pl\n" @@ -56,12 +56,12 @@ msgid "|pinentry-tt|Hide passphrase" msgstr "|pinentry-tt|Ukrycie hasła" msgid "Caps Lock is on" -msgstr "" +msgstr "Caps Lock jest włączony" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for generating a passphrase. msgid "Suggest" -msgstr "" +msgstr "Propozycja" #. TRANSLATORS: This string is a tooltip, shown by pinentry when #. hovering over the generate button. Please use an appropriate @@ -70,26 +70,20 @@ msgstr "" #. translate this entry, a default English text (see source) #. will be used. The strcmp thingy is there to detect a #. non-translated string. -#, fuzzy -#| msgid "pinentry.qualitybar.tooltip" msgid "pinentry.genpin.tooltip" -msgstr "" -"Jakość wpisanego wyżej tekstu.\n" -"Kryteria jakości można uzyskać od administratora." +msgstr "Propozycja losowego hasła." #. TRANSLATORS: This is a text shown by pinentry if the option #. for formatted passphrase is enabled. The length is #. limited to about 900 characters. msgid "Note: The blanks are not part of the passphrase." -msgstr "" +msgstr "Uwaga: odstępy nie są częścią hasła." #. TRANSLATORS: This is a text shown by pinentry as title of a dialog #. telling the user that the entered new passphrase does not satisfy #. the passphrase constraints. Please keep it short. -#, fuzzy -#| msgid "Passphrase too long" msgid "Passphrase Not Allowed" -msgstr "Hasło zbyt długie" +msgstr "Hasło niedozwolone" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for the quality bar. @@ -127,10 +121,8 @@ msgstr "Hasło:" msgid "does not match - try again" msgstr "nie pasują - proszę spróbować jeszcze raz" -#, fuzzy -#| msgid "Passphrase Entry" msgid "Passphrases match." -msgstr "Wpisywanie hasła" +msgstr "Hasła się zgadzają." #. TRANSLATORS: The string is appended to an error message in #. the pinentry. The %s is the actual error message, the @@ -161,10 +153,10 @@ msgid "Bad Passphrase" msgstr "Niepoprawne hasło" msgid "Note: Request from the web browser." -msgstr "" +msgstr "Uwaga: żądanie z przeglądarki WWW." msgid "Note: Request from a remote site." -msgstr "" +msgstr "Uwaga: żądanie z maszyny zdalnej." #, c-format msgid "error getting serial number of card: %s\n" @@ -173,20 +165,19 @@ msgstr "błąd pobierania numeru seryjnego karty: %s\n" msgid "Please re-enter this passphrase" msgstr "Proszę ponownie wprowadzić to hasło" -#, fuzzy, c-format -#| msgid "" -#| "Please enter the passphrase to protect the imported object within the " -#| "GnuPG system." +#, c-format msgid "" "Please enter the passphrase to protect the imported object within the %s " "system." msgstr "" -"Proszę wprowadzić hasło do zabezpieczenia ważnego obiektu w systemie GnuPG." +"Proszę wprowadzić hasło do zabezpieczenia importowanego obiektu w systemie %s." msgid "" "This key (or subkey) is not protected with a passphrase. Please enter a new " "passphrase to export it." msgstr "" +"Ten klucz (lub podklucz) nie jest zabezpieczony hasłem. Proszę wprowadzić nowe " +"hasło, aby go wyeksportować." #, c-format msgid "ssh keys greater than %d bits are not supported\n" @@ -276,10 +267,9 @@ msgstr "PIN nie powtórzony poprawnie; spróbuj jeszcze raz" msgid "Please enter the PIN%s%s%s to unlock the card" msgstr "Proszę wprowadzić PIN%s%s%s aby odblokować kartę" -#, fuzzy, c-format -#| msgid "error writing to %s: %s\n" +#, c-format msgid "error writing to pipe: %s\n" -msgstr "błąd zapisu do %s: %s\n" +msgstr "błąd zapisu do potoku: %s\n" msgid "Enter new passphrase" msgstr "Wprowadź nowe hasło" @@ -334,10 +324,8 @@ msgstr "Proszę wprowadzić hasło do%0Azabezpieczenia swojego nowego klucza" msgid "Please enter the new passphrase" msgstr "Proszę wprowadzić nowe hasło" -#, fuzzy -#| msgid "Options useful for debugging" msgid "Options used for startup" -msgstr "Opcje przydatne do diagnostyki" +msgstr "Opcje używane przy uruchamianiu" msgid "run in daemon mode (background)" msgstr "uruchomienie w trybie demona (w tle)" @@ -378,10 +366,8 @@ msgstr "nieużywanie SCdaemona" msgid "|PGM|use PGM as the SCdaemon program" msgstr "|PGM|użycie PGM jako programu SCdaemon" -#, fuzzy -#| msgid "|PGM|use PGM as the SCdaemon program" msgid "|PGM|use PGM as the tpm2daemon program" -msgstr "|PGM|użycie PGM jako programu SCdaemon" +msgstr "|PGM|użycie PGM jako programu tpm2daemon" msgid "|NAME|accept some commands via NAME" msgstr "|NAZWA|przyjęcie poleceń poprzez NAZWĘ" @@ -401,10 +387,8 @@ msgstr "|ALGO|użycie ALGO do wyświetlania odcisków ssh" msgid "enable putty support" msgstr "włączenie obsługi putty" -#, fuzzy -#| msgid "enable putty support" msgid "enable Win32-OpenSSH support" -msgstr "włączenie obsługi putty" +msgstr "włączenie obsługi Win32-OpenSSH" msgid "Options controlling the security" msgstr "Opcje sterujące bezpieczeństwem" @@ -455,19 +439,17 @@ msgstr "|N|przedawnianie haseł po N dniach" msgid "do not allow the reuse of old passphrases" msgstr "niezezwalanie na ponowne użycie starych haseł" -#, fuzzy -#| msgid "Options controlling the security" msgid "Options controlling the PIN-Entry" -msgstr "Opcje sterujące bezpieczeństwem" +msgstr "Opcje sterujące PIN-Entry" msgid "never use the PIN-entry" -msgstr "" +msgstr "bez używania PIN-entry" msgid "disallow caller to override the pinentry" msgstr "niezezwalanie wywołującym na nadpisywanie pinentry" msgid "let PIN-Entry grab keyboard and mouse" -msgstr "" +msgstr "zezwolenie PIN-Entry na przechwycenie klawiatury i myszy" msgid "|PGM|use PGM as the PIN-Entry program" msgstr "|PGM|użycie PGM jako programu do wprowadzania PIN-u" @@ -524,7 +506,7 @@ msgstr "nazwa gniazda „%s” zbyt długa\n" #, c-format msgid "trying to steal socket from running %s\n" -msgstr "" +msgstr "próba kradzieży gniazda od działającego %s\n" #, c-format msgid "a gpg-agent is already running - not starting a new one\n" @@ -764,13 +746,9 @@ msgstr "Zmienię je później" msgid "Please insert the card with serial number" msgstr "Proszę włożyć kartę z numerem seryjnym" -#, fuzzy, c-format -#| msgid "" -#| "An ssh process requested the use of key%%0A %s%%0A (%s)%%0ADo you want " -#| "to allow this?" +#, c-format msgid "Requested the use of key%%0A %s%%0A %s%%0ADo you want to allow this?" -msgstr "" -"Proces ssh zarządał użycia klucza%%0a %s%%0A (%s)%%0ACzy zezwolić na to?" +msgstr "Zażądano użycia klucza%%0A %s%%0A %s%%0ACzy zezwolić na to?" #, c-format msgid "" @@ -1154,19 +1132,19 @@ msgstr "niewłaściwy znak formatu radix64 %02x został pominięty\n" #, c-format msgid "Sorry, we are in batchmode - can't get input\n" -msgstr "" +msgstr "Niestety pracujemy w trybie wsadowym - nie można uzyskać wejścia\n" #, c-format msgid "Sorry, no terminal at all requested - can't get input\n" -msgstr "" +msgstr "Niestety nie żądano terminala - nie można uzyskać wejścia\n" #, c-format msgid "too many errors; giving up\n" -msgstr "" +msgstr "zbyt dużo błędów; poddaję się\n" #, c-format msgid "Control-D detected\n" -msgstr "" +msgstr "wykryto Control-D\n" #, c-format msgid "conversion from '%s' to '%s' not available\n" @@ -1341,10 +1319,9 @@ msgstr "Hasło: " msgid "%s is not compliant with %s mode\n" msgstr "%s nie jest zgodny z trybem %s\n" -#, fuzzy, c-format -#| msgid "error reading from %s: %s\n" +#, c-format msgid "error from TPM: %s\n" -msgstr "błąd odczytu z %s: %s\n" +msgstr "błąd z TPM: %s\n" #, c-format msgid "problem with the agent: %s\n" @@ -1424,7 +1401,7 @@ msgstr "wymuszono" #, c-format msgid "Please try command \"%s\" if the listing does not look correct\n" -msgstr "" +msgstr "Proszę spróbować polecenia ,,%s'', jeśli lista nie wygląda poprawnie\n" msgid "Error: Only plain ASCII is currently allowed.\n" msgstr "Błąd: aktualnie dopuszczalne jest tylko czyste ASCII.\n" @@ -1500,20 +1477,16 @@ msgstr "błąd podczas odczytu aktualnych informacji o kluczu: %s\n" msgid "Replace existing key? (y/N) " msgstr "Zastąpić istniejący klucz? (t/N) " -#, fuzzy -#| msgid "" -#| "Note: There is no guarantee that the card supports the requested size.\n" -#| " If the key generation does not succeed, please check the\n" -#| " documentation of your card to see what sizes are allowed.\n" msgid "" "Note: There is no guarantee that the card supports the requested\n" " key type or size. If the key generation does not succeed,\n" " please check the documentation of your card to see which\n" " key types and sizes are supported.\n" msgstr "" -"Uwaga: Nie ma gwarancji, że karta obsługuje żądany rozmiar.\n" -" Jeśli tworzenie klucza nie powiedzie się, proszę sprawdzić\n" -" dokumentację karty, aby poznać dozwolone rozmiary.\n" +"Uwaga: Nie ma gwarancji, że karta obsługuje żądany typ lub rozmiar\n" +" klucza. Jeśli tworzenie klucza nie powiedzie się, proszę\n" +" sprawdzić dokumentację karty, aby poznać dozwolone typy\n" +" i rozmiary kluczy.\n" #, c-format msgid "What keysize do you want? (%u) " @@ -1626,10 +1599,9 @@ msgstr "Naprawdę przywrócić stan fabryczny? (proszę wpisać „yes”) " msgid "error for setup KDF: %s\n" msgstr "błąd przy ustawianiu KDF: %s\n" -#, fuzzy, c-format -#| msgid "error for setup KDF: %s\n" +#, c-format msgid "error for setup UIF: %s\n" -msgstr "błąd przy ustawianiu KDF: %s\n" +msgstr "błąd przy ustawianiu UIF: %s\n" msgid "quit this menu" msgstr "wyjście z tego menu" @@ -1682,21 +1654,17 @@ msgstr "odblokowanie PIN-u przy użyciu kodu resetującego" msgid "destroy all keys and data" msgstr "zniszczenie wszystkich kluczy i danych" -#, fuzzy -#| msgid "setup KDF for PIN authentication" msgid "setup KDF for PIN authentication (on/single/off)" -msgstr "ustawienie KDF do uwierzytelniania PIN-em" +msgstr "ustawienie KDF do uwierzytelniania PIN-em (on/single/off)" msgid "change the key attribute" msgstr "zmiana atrybutu klucza" -#, fuzzy -#| msgid "change the ownertrust" msgid "change the User Interaction Flag" -msgstr "zmiana zaufania właściciela" +msgstr "zmiana flagi interakcji użytkownika (UIF)" msgid "switch to the OpenPGP app" -msgstr "" +msgstr "przełączenie na aplikację OpenPGP" msgid "gpg/card> " msgstr "gpg/karta> " @@ -1820,16 +1788,13 @@ msgstr "OSTRZEŻENIE: klucz %s nie nadaje się do szyfrowania w trybie %s\n" msgid "error creating passphrase: %s\n" msgstr "błąd podczas tworzenia hasła: %s\n" -#, fuzzy, c-format -#| msgid "can't use a symmetric ESK packet due to the S2K mode\n" +#, c-format msgid "can't use a SKESK packet due to the S2K mode\n" -msgstr "" -"ustawiony tryb S2K nie pozwala użyć pakietu ESK dla szyfru symetrycznego\n" +msgstr "nie można użyć pakietu SKESK ze względu na tryb S2K\n" -#, fuzzy, c-format -#| msgid "using cipher %s\n" +#, c-format msgid "using cipher %s.%s\n" -msgstr "szyfrem %s\n" +msgstr "szyfrem %s.%s\n" #, c-format msgid "'%s' already compressed\n" @@ -1898,18 +1863,14 @@ msgstr "usunięcie bezużytecznych części z klucza przy eksporcie" msgid "remove as much as possible from key during export" msgstr "usunięcie jak największej części klucza przy eksporcie" -#, fuzzy -#| msgid "generate a revocation certificate" msgid "export only revocation certificates" -msgstr "tworzenie certyfikatu unieważnienia klucza" +msgstr "eksport tylko certyfikatów unieważnienia" msgid "use the GnuPG key backup format" msgstr "użycie formatu kopii zapasowej klucza GnuPG" -#, fuzzy -#| msgid "exporting secret keys not allowed\n" msgid "export secret keys using the GnuPG format" -msgstr "eksport kluczy tajnych nie jest dozwolony\n" +msgstr "eksport kluczy tajnych przy użyciu formatu GnuPG" msgid " - skipped" msgstr " - pominięty" @@ -2127,15 +2088,11 @@ msgstr "pozostawienie bez zmian" msgid "prompt before overwriting" msgstr "pytanie przed nadpisaniem plików" -#, fuzzy -#| msgid "Options controlling the security" msgid "Options controlling the input" -msgstr "Opcje sterujące bezpieczeństwem" +msgstr "Opcje sterujące wejściem" -#, fuzzy -#| msgid "Options controlling the diagnostic output" msgid "Options controlling the output" -msgstr "Opcje sterujące wyjściem diagnostycznym" +msgstr "Opcje sterujące wyjściem" msgid "create ascii armored output" msgstr "opakowanie ASCII pliku wynikowego" @@ -2149,10 +2106,8 @@ msgstr "kanoniczny format tekstowy" msgid "|N|set compress level to N (0 disables)" msgstr "|N|ustawienie poziomu kompresji N (0 - bez)" -#, fuzzy -#| msgid "Options controlling the interactivity and enforcement" msgid "Options controlling key import and export" -msgstr "Opcje sterujące interaktywnością i wymuszaniem" +msgstr "Opcje sterujące importem i eksportem" msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address" msgstr "" @@ -2168,15 +2123,11 @@ msgstr "włączanie klucza publicznego do podpisów" msgid "disable all access to the dirmngr" msgstr "zablokuj dostęp do dirmngr" -#, fuzzy -#| msgid "Options controlling the configuration" msgid "Options controlling key listings" -msgstr "Opcje sterujące konfiguracją" +msgstr "Opcje sterujące listami kluczy" -#, fuzzy -#| msgid "list secret keys" msgid "Options to specify keys" -msgstr "lista kluczy prywatnych" +msgstr "Opcje określające klucze" msgid "|USER-ID|encrypt for USER-ID" msgstr "|UŻYTKOWNIK|szyfrowanie dla odbiorcy o tym identyfikatorze" @@ -2187,10 +2138,10 @@ msgstr "" "odszyfrowania" msgid "Options for unattended use" -msgstr "" +msgstr "Opcje użycia nieinteraktywnego" msgid "Other options" -msgstr "" +msgstr "Pozostałe opcje" msgid "" "@\n" @@ -2364,10 +2315,8 @@ msgstr "" msgid "show revoked and expired subkeys in key listings" msgstr "pokazywanie unieważnionych i wygasłych podkluczy na listach kluczy" -#, fuzzy -#| msgid "show expiration dates during signature listings" msgid "show signatures with invalid algorithms during signature listings" -msgstr "pokazywanie dat wygaśnięcia przy wypisywaniu podpisów" +msgstr "pokazywanie podpisów z niepoprawnymi algorytmami przy wypisywaniu podpisów" msgid "show the keyring name in key listings" msgstr "pokazywanie nazwy zbioru kluczy na listach kluczy" @@ -2375,10 +2324,8 @@ msgstr "pokazywanie nazwy zbioru kluczy na listach kluczy" msgid "show expiration dates during signature listings" msgstr "pokazywanie dat wygaśnięcia przy wypisywaniu podpisów" -#, fuzzy -#| msgid "list preferences (expert)" msgid "show preferences" -msgstr "ustawienia (zaawansowane)" +msgstr "pokazanie ustawień" #, c-format msgid "unknown TOFU policy '%s'\n" @@ -2592,10 +2539,9 @@ msgstr "niewłaściwe ustawienia skrótów\n" msgid "invalid personal compress preferences\n" msgstr "niewłaściwe ustawienia algorytmów kompresji\n" -#, fuzzy, c-format -#| msgid "keysize invalid; using %u bits\n" +#, c-format msgid "chunk size invalid - using %d\n" -msgstr "niewłaściwa długość klucza; wykorzystano %u bitów\n" +msgstr "nieprawidłowy rozmiar porcji - użycie %d\n" #, c-format msgid "%s does not yet work with %s\n" @@ -2739,18 +2685,14 @@ msgstr "nieczyszczenie wartości zaufania podczas importu" msgid "do not update the trustdb after import" msgstr "nieuaktualnianie bazy zaufania po imporcie" -#, fuzzy -#| msgid "enable putty support" msgid "enable bulk import mode" -msgstr "włączenie obsługi putty" +msgstr "włączenie trybu importu masowego" msgid "show key during import" msgstr "okazanie klucza podczas importu" -#, fuzzy -#| msgid "show key during import" msgid "show key but do not actually import" -msgstr "okazanie klucza podczas importu" +msgstr "okazanie klucza bez importowania go" msgid "only accept updates to existing keys" msgstr "przyjmowanie tylko uaktualnień istniejących kluczy" @@ -2992,7 +2934,7 @@ msgstr "klucz %s: błąd wysyłania do agenta: %s\n" #, c-format msgid "key %s: card reference is overridden by key material\n" -msgstr "" +msgstr "klucz %s: odwołanie do karty nadpisane przez materiał klucza\n" #. TRANSLATORS: For a smartcard, each private key on host has a #. * reference (stub) to a smartcard and actual private key data @@ -3140,12 +3082,11 @@ msgstr "klucz %s: pominięto - nieoczekiwana klasa podpisu (0x%02X)\n" #, c-format msgid "key %s: duplicated user ID detected - merged\n" -msgstr "key %s: dołączono powtórzony identyfikator użytkownika\n" +msgstr "klucz %s: dołączono powtórzony identyfikator użytkownika\n" -#, fuzzy, c-format -#| msgid "key %s: duplicated user ID detected - merged\n" +#, c-format msgid "key %s: duplicated subkeys detected - merged\n" -msgstr "key %s: dołączono powtórzony identyfikator użytkownika\n" +msgstr "klucz %s: wykryto powtórzone podklucze - połączono\n" #, c-format msgid "WARNING: key %s may be revoked: fetching revocation key %s\n" @@ -3513,7 +3454,7 @@ msgid "move a key to a smartcard" msgstr "przeniesienie klucza na kartę procesorową" msgid "convert a key to TPM form using the local TPM" -msgstr "" +msgstr "przekształcenie klucza do postaci TPM przy użyciu lokalnego TPM" msgid "move a backup key to a smartcard" msgstr "przeniesienie klucza zapasowego na kartę procesorową" @@ -3524,10 +3465,8 @@ msgstr "usunięcie wybranych podkluczy" msgid "add a revocation key" msgstr "dodanie klucza unieważniającego" -#, fuzzy -#| msgid "Data decryption succeeded" msgid "add an additional decryption subkey" -msgstr "Odszyfrowywanie danych zakończone" +msgstr "dodanie dodatkowego podklucza do odszyfrowywania" msgid "delete signatures from the selected user IDs" msgstr "usunięcie podpisów z wybranych identyfikatorów użytkownika" @@ -3595,11 +3534,9 @@ msgstr "Dostępny jest klucz tajny.\n" msgid "Secret subkeys are available.\n" msgstr "Dostępne są podklucze tajne.\n" -#, fuzzy -#| msgid "Note: Only the secret part of the shown subkey will be deleted.\n" msgid "" "Note: the local copy of the secret key will only be deleted with \"save\".\n" -msgstr "Uwaga: usunięta zostanie tylko tajna część pokazanego podklucza.\n" +msgstr "Uwaga: kopia lokalna klucza tajnego będzie usunięta tylko z \"save\".\n" msgid "Need the secret key to do this.\n" msgstr "Do wykonania tej operacji potrzebny jest klucz tajny.\n" @@ -3715,10 +3652,9 @@ msgstr "Zapisać zmiany? (t/N) " msgid "Quit without saving? (y/N) " msgstr "Wyjść bez zapisania zmian? (t/N) " -#, fuzzy, c-format -#| msgid "deleting secret %s failed: %s\n" +#, c-format msgid "deleting copy of secret key failed: %s\n" -msgstr "usunięcie %s tajnego nie powiodło się: %s\n" +msgstr "usunięcie kopii klucza tajnego nie powiodło się: %s\n" #, c-format msgid "Key not changed so no update needed.\n" @@ -3858,10 +3794,9 @@ msgstr "OSTRZEŻENIE: podklucz do szyfrowania wkrótce wygaśnie.\n" msgid "You may want to change its expiration date too.\n" msgstr "Może warto także zmienić jego datę ważności.\n" -#, fuzzy, c-format -#| msgid "WARNING: Your encryption subkey expires soon.\n" +#, c-format msgid "WARNING: No valid encryption subkey left over.\n" -msgstr "OSTRZEŻENIE: podklucz do szyfrowania wkrótce wygaśnie.\n" +msgstr "OSTRZEŻENIE: nie pozostawiono poprawnego podklucza do szyfrowania.\n" msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " @@ -3877,10 +3812,8 @@ msgstr "Czy dalej chcesz je dodać? (t/N) " msgid "You may not add a photo ID to a PGP2-style key.\n" msgstr "Do klucza dla PGP 2.x nie można dodać zdjęcia.\n" -#, fuzzy -#| msgid "Such a user ID already exists on this key!\n" msgid "Such a user ID already exists on this key!" -msgstr "Taki identyfikator użytkownika już istnieje na tym kluczu!\n" +msgstr "Taki identyfikator użytkownika już istnieje na tym kluczu!" msgid "Delete this good signature? (y/N/q)" msgstr "Usunąć ten poprawny podpis? (t/N/w) " @@ -3962,17 +3895,15 @@ msgid "" msgstr "Czy na pewno chcesz wyznaczyć ten klucz jako unieważniający? (t/N) " msgid "Enter the fingerprint of the additional decryption subkey: " -msgstr "" +msgstr "Wprowadź odcisk klucza dodatkowego podklucza do odszyfrowywania: " -#, fuzzy, c-format -#| msgid "(unless you specify the key by fingerprint)\n" +#, c-format msgid "Did you specify the fingerprint of a subkey?\n" -msgstr "(chyba, że klucz zostaje wybrany przez podanie odcisku)\n" +msgstr "Czy podano odcisk podklucza?\n" -#, fuzzy, c-format -#| msgid "Subkey %s is already revoked.\n" +#, c-format msgid "key \"%s\" is already on this keyblock\n" -msgstr "Podklucz %s jest już unieważniony.\n" +msgstr "klucz ,,%s'' jest już w tym bloku kluczy\n" msgid "" "Are you sure you want to change the expiration time for multiple subkeys? (y/" @@ -4138,10 +4069,9 @@ msgstr "zbyt wiele ustawień funkcji skrótu\n" msgid "too many compression preferences\n" msgstr "zbyt wiele ustawień kompresji\n" -#, fuzzy, c-format -#| msgid "too many cipher preferences\n" +#, c-format msgid "too many AEAD preferences\n" -msgstr "zbyt wiele ustawień szyfru\n" +msgstr "zbyt dużo ustawień AEAD\n" #, c-format msgid "invalid item '%s' in preference string\n" @@ -4199,10 +4129,9 @@ msgstr "Uwierzytelnianie" msgid "SsEeAaQq" msgstr "PpSsUuZz" -#, fuzzy, c-format -#| msgid "Possible actions for a %s key: " +#, c-format msgid "Possible actions for this %s key: " -msgstr "Możliwe akcje dla klucza %s: " +msgstr "Możliwe akcje dla tego klucza %s: " msgid "Current allowed actions: " msgstr "Aktualnie dopuszczalne akcje: " @@ -4521,11 +4450,11 @@ msgstr "" #, c-format msgid "WARNING: v4 is specified, but overridden by v5.\n" -msgstr "" +msgstr "UWAGA: określono wersję 4, ale została nadpisana przez 5.\n" #, c-format msgid "Key generation failed: %s\n" -msgstr "Generacja klucza nie powiodła się: %s\n" +msgstr "Generowanie klucza nie powiodło się: %s\n" #, c-format msgid "" @@ -4559,7 +4488,7 @@ msgstr "" #, c-format msgid "Key generation canceled.\n" -msgstr "Procedura generacji klucza została anulowana.\n" +msgstr "Procedura generowania klucza została anulowana.\n" #, c-format msgid "can't create backup file '%s': %s\n" @@ -4803,20 +4732,17 @@ msgstr "OSTRZEŻENIE: nie można pobrać URI %s: %s\n" msgid "weird size for an encrypted session key (%d)\n" msgstr "dziwny rozmiar jak na zaszyfrowany klucz sesyjny (%d)\n" -#, fuzzy, c-format -#| msgid "%s encrypted session key\n" +#, c-format msgid "%s.%s encrypted session key\n" -msgstr "klucz sesyjny zaszyfrowany %s\n" +msgstr "klucz sesyjny zaszyfrowany %s.%s\n" -#, fuzzy, c-format -#| msgid "%s encrypted data\n" +#, c-format msgid "%s.%s encrypted data\n" -msgstr "dane zaszyfrowano za pomocą %s\n" +msgstr "dane zaszyfrowano za pomocą %s.%s\n" -#, fuzzy, c-format -#| msgid "encrypted with unknown algorithm %d\n" +#, c-format msgid "encrypted with unknown algorithm %d.%s\n" -msgstr "dane zaszyfrowano nieznanym algorytmem numer %d\n" +msgstr "zaszyfrowano nieznanym algorytmem %d.%s\n" #, c-format msgid "passphrase generated with unknown digest algorithm %d\n" @@ -4826,11 +4752,9 @@ msgstr "hasło wygenerowane nieznanym algorytmem skrótu %d\n" msgid "public key is %s\n" msgstr "klucz publiczny to %s\n" -#, fuzzy, c-format -#| msgid "encrypted with %u-bit %s key, ID %s, created %s\n" +#, c-format msgid "encrypted with %s key, ID %s, created %s\n" -msgstr "" -"zaszyfrowano %u-bitowym kluczem %s o identyfikatorze %s, stworzonym %s\n" +msgstr "zaszyfrowano kluczem %s o identyfikatorze %s, stworzonym %s\n" #, c-format msgid " \"%s\"\n" @@ -4903,7 +4827,7 @@ msgstr "błąd odszyfrowywania: %s\n" #, c-format msgid "operation forced to fail due to unfulfilled compliance rules\n" -msgstr "" +msgstr "wymuszono niepowodzenie operacji ze względu na niespełnione zasady zgodności\n" #, c-format msgid "Note: sender requested \"for-your-eyes-only\"\n" @@ -5174,10 +5098,8 @@ msgstr "Nieznane krytyczne adnotacje podpisu: " msgid "subpacket of type %d has critical bit set\n" msgstr "podpakiet typu %d ma ustawiony krytyczny bit\n" -#, fuzzy -#| msgid "Please enter the new passphrase" msgid "Please enter the passphrase for decryption." -msgstr "Proszę wprowadzić nowe hasło" +msgstr "Proszę wprowadzić hasło w celu odszyfrowania." msgid "Enter passphrase\n" msgstr "Hasło\n" @@ -5209,10 +5131,8 @@ msgstr "Czy na pewno trwale usunąć podklucz prywatny OpenPGP:" msgid "Do you really want to permanently delete the OpenPGP secret key:" msgstr "Czy na pewno trwale usunąć klucz prywatny OpenPGP:" -#, fuzzy -#| msgid "Please enter the passphrase to export the OpenPGP secret key:" msgid "Please enter the passphrase to export the secret key with keygrip:" -msgstr "Proszę wprowadzić hasło do wyeksportowania klucza prywatnego OpenPGP:" +msgstr "Proszę wprowadzić hasło do wyeksportowania klucza prywatnego z uchwytem:" #, c-format msgid "" @@ -5459,10 +5379,9 @@ msgstr "Uwaga: Ten klucz został wyłączony z użytku.\n" msgid "Note: This key has expired!\n" msgstr "Uwaga: Data ważności tego klucza upłynęła!\n" -#, fuzzy, c-format -#| msgid "WARNING: This key is not certified with a trusted signature!\n" +#, c-format msgid "WARNING: The key's User ID is not certified with a trusted signature!\n" -msgstr "OSTRZEŻENIE: Ten klucz nie jest poświadczony zaufanym podpisem!\n" +msgstr "OSTRZEŻENIE: Identyfikator użytkownika tego klucza nie jest poświadczony zaufanym podpisem!\n" #, c-format msgid "WARNING: This key is not certified with a trusted signature!\n" @@ -5482,14 +5401,13 @@ msgstr "OSTRZEŻENIE: NIE UFAMY temu kluczowi!\n" msgid " The signature is probably a FORGERY.\n" msgstr " Ten podpis prawdopodobnie jest FAŁSZYWY.\n" -#, fuzzy, c-format -#| msgid "" -#| "WARNING: This key is not certified with sufficiently trusted signatures!\n" +#, c-format msgid "" "WARNING: The key's User ID is not certified with sufficiently trusted " "signatures!\n" msgstr "" -"OSTRZEŻENIE: Tego klucza nie poświadczają wystarczająco zaufane podpisy!\n" +"OSTRZEŻENIE: Identyfikatora użytkownika tego klucza nie poświadczają " +"wystarczająco zaufane podpisy!\n" #, c-format msgid "" @@ -5605,10 +5523,9 @@ msgstr "klucz %s nie nadaje się do odszyfrowywania w trybie %s\n" msgid "anonymous recipient; trying secret key %s ...\n" msgstr "adresat anonimowy; sprawdzanie klucza tajnego %s...\n" -#, fuzzy, c-format -#| msgid "key %s is not suitable for decryption in %s mode\n" +#, c-format msgid "used key is not marked for encryption use.\n" -msgstr "klucz %s nie nadaje się do odszyfrowywania w trybie %s\n" +msgstr "używany klucz nie jest oznaczony jako przeznaczony do szyfrowania.\n" #, c-format msgid "okay, we are the anonymous recipient.\n" @@ -5779,7 +5696,7 @@ msgstr "wygenerowano słaby klucz - operacja zostaje powtórzona\n" #, c-format msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n" msgstr "" -"brak możliwości generacji dobrego klucza dla szyfru symetrycznego;\n" +"brak możliwości wygenerowania dobrego klucza dla szyfru symetrycznego;\n" "operacja była powtarzana %d razy!\n" #, c-format @@ -5920,10 +5837,9 @@ msgstr "" msgid "signing:" msgstr "podpis:" -#, fuzzy, c-format -#| msgid "%s encryption will be used\n" +#, c-format msgid "%s.%s encryption will be used\n" -msgstr "zostanie użyty szyfr %s\n" +msgstr "zostanie użyty szyfr %s.%s\n" #, c-format msgid "key is not flagged as insecure - can't use it with the faked RNG!\n" @@ -6645,53 +6561,39 @@ msgstr "%sNumer: %s%%0AWłaściciel: %s%s" msgid "Remaining attempts: %d" msgstr "Pozostało prób: %d" -#, fuzzy -#| msgid "||Please enter the PIN" msgid "|N|Please enter the new Global-PIN" -msgstr "||Proszę wpisać PIN" +msgstr "|N|Proszę wprowadzić nowy Global-PIN" -#, fuzzy -#| msgid "||Please enter the Reset Code for the card" msgid "||Please enter the Global-PIN of your PIV card" -msgstr "||Proszę wprowadzić kod resetujący dla karty" +msgstr "||Proszę wprowadzić Global-PIN karty PIV" -#, fuzzy -#| msgid "||Please enter the PIN" msgid "|N|Please enter the new PIN" -msgstr "||Proszę wpisać PIN" +msgstr "|N|Proszę wprowadzić nowy PIN" -#, fuzzy -#| msgid "||Please enter the Reset Code for the card" msgid "||Please enter the PIN of your PIV card" -msgstr "||Proszę wprowadzić kod resetujący dla karty" +msgstr "||Proszę wprowadzić PIN karty PIV" -#, fuzzy -#| msgid "|A|Please enter the Admin PIN" msgid "|N|Please enter the new Unblocking Key" -msgstr "|A|Proszę wprowadzić PIN administracyjny" +msgstr "|N|Proszę wprowadzić nowy klucz odblokowujący" -#, fuzzy -#| msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys." msgid "||Please enter the Unblocking Key of your PIV card" -msgstr "|P|Proszę wprowadzić kod odblokowujący PIN (PUK) dla zwykłych kluczy." +msgstr "||Proszę wprowadzić klucz odblokowujący karty PIV" #, c-format msgid "PIN callback returned error: %s\n" msgstr "Zapytanie zwrotne o PIN zwróciło błąd: %s\n" -#, fuzzy, c-format -#| msgid "PIN for CHV%d is too short; minimum length is %d\n" +#, c-format msgid "PIN is too short; minimum length is %d\n" -msgstr "PIN dla CHV%d jest zbyt krótki; minimalna długość to %d\n" +msgstr "PIN zbyt krótki; minimalna długość to %d\n" -#, fuzzy, c-format -#| msgid "PIN for CHV%d is too short; minimum length is %d\n" +#, c-format msgid "PIN is too long; maximum length is %d\n" -msgstr "PIN dla CHV%d jest zbyt krótki; minimalna długość to %d\n" +msgstr "PIN zbyt długi; maksymalna długość to %d\n" #, c-format msgid "PIN has invalid characters; only digits are allowed\n" -msgstr "" +msgstr "PIN ma nieprawidłowe znaki; dozwolone są tylko cyfry\n" #, c-format msgid "key already exists\n" @@ -6767,10 +6669,8 @@ msgstr "reszta RSA brakująca lub o rozmiarze innym niż %d bity\n" msgid "RSA public exponent missing or larger than %d bits\n" msgstr "publiczny wykładnik RSA brakujący lub większy niż %d bity\n" -#, fuzzy -#| msgid "the NullPIN has not yet been changed\n" msgid "Note: PIN has not yet been enabled." -msgstr "NullPIN nie został jeszcze zmieniony\n" +msgstr "Uwaga: PIN nie został jeszcze włączony." #, c-format msgid "the NullPIN has not yet been changed\n" @@ -6984,7 +6884,7 @@ msgid "use variable length input for pinpad" msgstr "użycie wejścia z klawiatury czytnika o zmiennej długości" msgid "|LIST|change the application priority to LIST" -msgstr "" +msgstr "|LISTA|zmiana priorytetów aplikacji na LISTĘ" msgid "deny the use of admin card commands" msgstr "zabronienie używania poleceń karty administratora" @@ -7016,7 +6916,7 @@ msgid "error getting key usage information: %s\n" msgstr "błąd pobierania informacji o zastosowaniu klucza: %s\n" msgid "Tor might be in use - network access is limited" -msgstr "" +msgstr "Tor może być w użyciu - dostep do sieci jest ograniczony" #, c-format msgid "validation model requested by certificate: %s" @@ -7294,10 +7194,9 @@ msgstr "certyfikat nie nadaje się do szyfrowania\n" msgid "certificate is not usable for signing\n" msgstr "certyfikat nie nadaje się do podpisywania\n" -#, fuzzy, c-format -#| msgid "lookup a certificate" +#, c-format msgid "looking for another certificate\n" -msgstr "wyszukanie certyfikatu" +msgstr "wyszukanie innego certyfikatu\n" #, c-format msgid "line %d: invalid algorithm\n" @@ -7477,10 +7376,9 @@ msgstr "(to jest algorytm RC2)\n" msgid "(this does not seem to be an encrypted message)\n" msgstr "(to nie wygląda na zaszyfrowaną wiadomość)\n" -#, fuzzy, c-format -#| msgid "encrypted with %s key, ID %s\n" +#, c-format msgid "encrypted to %s key %s\n" -msgstr "zaszyfrowano kluczem %s o identyfikatorze %s\n" +msgstr "zaszyfrowano do %s kluczem %s\n" #, c-format msgid "certificate '%s' not found: %s\n" @@ -7648,10 +7546,9 @@ msgstr "błąd importu certyfikatu: %s\n" msgid "error reading input: %s\n" msgstr "błąd odczytu wejścia: %s\n" -#, fuzzy, c-format -#| msgid "no dirmngr running in this session\n" +#, c-format msgid "no keyboxd running in this session\n" -msgstr "brak działającego dirmngr w tej sesji\n" +msgstr "brak działającego keyboxd w tej sesji\n" #, c-format msgid "error opening key DB: %s\n" @@ -7740,10 +7637,9 @@ msgstr "algorytm skrótu użyty dla podpisującego %d: %s (%s)\n" msgid "checking for qualified certificate failed: %s\n" msgstr "sprawdzenie certyfikatu kwalifikowanego nie powiodło się: %s\n" -#, fuzzy, c-format -#| msgid "Signature made %s using %s key ID %s\n" +#, c-format msgid "%s/%s signature using %s key %s\n" -msgstr "Podpisano w %s kluczem %s o numerze %s\n" +msgstr "Podpis %s/%s kluczem %s %s\n" #, c-format msgid "Signature made " @@ -8269,10 +8165,8 @@ msgstr "crl_cache_insert po wystawcy nie powiodło się: %s\n" msgid "reader to file mapping table full - waiting\n" msgstr "tabela przypisań czytelników do plików pełna - oczekiwanie\n" -#, fuzzy -#| msgid "CRL access not possible due to Tor mode\n" msgid "CRL access not possible due to Tor mode" -msgstr "dostęp do CRL niemożliwy z powodu trybu Tor\n" +msgstr "dostęp do CRL niemożliwy z powodu trybu Tor" #, c-format msgid "CRL access not possible due to disabled %s\n" @@ -8425,7 +8319,7 @@ msgid "|N|do not return more than N items in one query" msgstr "|N|bez zwracania więcej niż N elementów w jednym zapytaniu" msgid "Network related options" -msgstr "" +msgstr "Opcje związane z siecią" msgid "route all network traffic via Tor" msgstr "trasowanie całego ruchu sieciowego przez Tora" @@ -8445,10 +8339,8 @@ msgstr "|URL|przekierowanie wszystkich żądań HTTP na URL" msgid "use system's HTTP proxy setting" msgstr "użycie systemowego ustawienia proxy HTTP" -#, fuzzy -#| msgid "Configuration for HTTP servers" msgid "Configuration for OpenPGP servers" -msgstr "Konfiguracja dla serwerów HTTP" +msgstr "Konfiguracja dla serwerów OpenPGP" msgid "|URL|use keyserver at URL" msgstr "|URL|używaj serwera kluczy URL" @@ -8456,10 +8348,8 @@ msgstr "|URL|używaj serwera kluczy URL" msgid "|FILE|use the CA certificates in FILE for HKP over TLS" msgstr "|PLIK|użycie certyfikatów CA w PLIKU dla HKP po TLS" -#, fuzzy -#| msgid "Configuration for HTTP servers" msgid "Configuration for X.509 servers" -msgstr "Konfiguracja dla serwerów HTTP" +msgstr "Konfiguracja dla serwerów X.509" msgid "inhibit the use of LDAP" msgstr "powstrzymanie od użycia LDAP" @@ -8662,7 +8552,7 @@ msgstr "%s:%u: podano hasło bez użytkownika\n" #, c-format msgid "%s:%u: ignoring unknown flag '%s'\n" -msgstr "" +msgstr "%s:%u: zignorowano nieznaną flagę ,,%s''\n" #, c-format msgid "%s:%u: skipping this line\n" @@ -8692,10 +8582,8 @@ msgstr "błąd odczytu z respondera: %s\n" msgid "response from server too large; limit is %d bytes\n" msgstr "odpowiedź z serwera zbyt długa; limit to %d bajtów\n" -#, fuzzy -#| msgid "OCSP request not possible due to Tor mode\n" msgid "OCSP request not possible due to Tor mode" -msgstr "żądanie OCSP niemożliwe z powodu trybu Tor\n" +msgstr "żądanie OCSP niemożliwe z powodu trybu Tor" #, c-format msgid "OCSP request not possible due to disabled HTTP\n" @@ -8902,10 +8790,8 @@ msgstr "dekodowanie otrzymanych linii danych" msgid "connect to the dirmngr" msgstr "połączenie z dirmngr" -#, fuzzy -#| msgid "connect to the dirmngr" msgid "connect to the keyboxd" -msgstr "połączenie z dirmngr" +msgstr "połączenie z keyboxd" msgid "|NAME|connect to Assuan socket NAME" msgstr "|NAZWA|połączenie z gniazdem Assuan o tej nazwie" @@ -8963,10 +8849,9 @@ msgstr "nieznane polecenie „%s”\n" msgid "sending line failed: %s\n" msgstr "wysyłanie linii nie powiodło się: %s\n" -#, fuzzy, c-format -#| msgid "no dirmngr running in this session\n" +#, c-format msgid "no keybox daemon running in this session\n" -msgstr "brak działającego dirmngr w tej sesji\n" +msgstr "brak działającego demona keybox w tej sesji\n" #, c-format msgid "error sending standard options: %s\n" @@ -8978,10 +8863,8 @@ msgstr "OpenPGP" msgid "S/MIME" msgstr "S/MIME" -#, fuzzy -#| msgid "public key is %s\n" msgid "Public Keys" -msgstr "klucz publiczny to %s\n" +msgstr "Klucze publiczne" msgid "Private Keys" msgstr "Klucze prywatne" @@ -8990,7 +8873,7 @@ msgid "Smartcards" msgstr "Karty procesorowe" msgid "TPM" -msgstr "" +msgstr "TPM" msgid "Network" msgstr "Sieć" From daedb3c96549427ed84fba5c9ab3f9475a412243 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 15 Jan 2024 17:21:24 +0100 Subject: [PATCH 318/869] doc: Describe the ssh-agent protocol options for Windows. -- Also fix a typo in a macro. --- agent/gpg-agent.c | 4 ++-- doc/gpg-agent.texi | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 1db422737..b0150031d 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -366,7 +366,7 @@ static int putty_support; /* Path to the pipe, which handles requests from Win32-OpenSSH. */ static const char *win32_openssh_support; -#define W32_DEFAILT_AGENT_PIPE_NAME "\\\\.\\pipe\\openssh-ssh-agent" +#define W32_DEFAULT_AGENT_PIPE_NAME "\\\\.\\pipe\\openssh-ssh-agent" #endif /*HAVE_W32_SYSTEM*/ /* The list of open file descriptors at startup. Note that this list @@ -1295,7 +1295,7 @@ main (int argc, char **argv) if (pargs.r_type) win32_openssh_support = pargs.r.ret_str; else - win32_openssh_support = W32_DEFAILT_AGENT_PIPE_NAME; + win32_openssh_support = W32_DEFAULT_AGENT_PIPE_NAME; # endif break; diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 902de56f4..49cf16e39 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -623,19 +623,30 @@ are touched. @anchor{option --enable-ssh-support} @item --enable-ssh-support +@itemx --enable-win32-openssh-support @itemx --enable-putty-support @opindex enable-ssh-support +@opindex enable-win32-openssh-support @opindex enable-putty-support -The OpenSSH Agent protocol is always enabled, but @command{gpg-agent} -will only set the @code{SSH_AUTH_SOCK} variable if this flag is given. +On Unix platforms the OpenSSH Agent protocol is always enabled, but +@command{gpg-agent} will only set the @code{SSH_AUTH_SOCK} variable if +the option @option{enable-ssh-support} is given. Some Linux +distributions use the presence of this option to decide whether the +old ssh-agent shall be started. + +On Windows support for the native ssh implementation must be enabled +using the the option @option{enable-win32-openssh-support}. For using +gpg-agent as a replacement for PuTTY's Pageant, the option +@option{enable-putty-support} must be enabled. In this mode of operation, the agent does not only implement the gpg-agent protocol, but also the agent protocol used by OpenSSH -(through a separate socket). Consequently, it should be possible to use -the gpg-agent as a drop-in replacement for the well known ssh-agent. +(through a separate socket or via Named Pipes) or the protocol used by +PuTTY. Consequently, this allows to use the gpg-agent as a drop-in +replacement for the ssh-agent. -SSH Keys, which are to be used through the agent, need to be added to +SSH keys, which are to be used through the agent, need to be added to the gpg-agent initially through the ssh-add utility. When a key is added, ssh-add will ask for the password of the provided key file and send the unprotected key material to the agent; this causes the From 1a2c8267f54ba0a55fa2f87fdc19068b0088510f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Jan 2024 14:02:42 +0100 Subject: [PATCH 319/869] gpg: When using a parm file w/o usage don't set the RENC usage. * g10/keygen.c (proc_parameter_file): Don't include RENC in the default usage. -- Testplan: $ gpg --gen-key --batch <key = pSUBKEYUSAGE; r->u.usage = (is_default ? PUBKEY_USAGE_ENC - : openpgp_pk_algo_usage (algo)); + : (openpgp_pk_algo_usage (algo) + & ~PUBKEY_USAGE_RENC) ); append_to_parameter (para, r); } else if (err == -1) From 5402e6fb936d25243bf546a560b20b9e5f7b2b24 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Jan 2024 14:32:04 +0100 Subject: [PATCH 320/869] gpg: For v5 key generation for X448 also in parm file mode. * g10/keygen.c (curve_is_448): New. (do_create_from_keygrip): Pass arg keygen_flags byref so that it can be updated. Set v5 flag for X448. (gen_ecc): Ditto. (do_create): Change keygen_flags as above. For robustness change checking for Ed448. (do_generate_keypair): Change keygen_flags as above (generate_subkeypair): Ditto. (gen_card_key): Ditto. Support v5 keys. -- GnuPG-bug-id: 6942 --- g10/keygen.c | 170 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 56 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 10b81d1ee..8e50a795e 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -159,7 +159,7 @@ static void do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, static int write_keyblock (iobuf_t out, kbnode_t node); static gpg_error_t gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, u32 *timestamp, - u32 expireval, int keygen_flags); + u32 expireval, int *keygen_flags); static unsigned int get_keysize_range (int algo, unsigned int *min, unsigned int *max); @@ -1266,6 +1266,39 @@ write_keybinding (ctrl_t ctrl, kbnode_t root, } +/* Returns true if SEXP specified the curve ED448 or X448. */ +static int +curve_is_448 (gcry_sexp_t sexp) +{ + gcry_sexp_t list, l2; + char *curve; + int result; + + list = gcry_sexp_find_token (sexp, "public-key", 0); + if (!list) + return 0; /* Not a public key. */ + l2 = gcry_sexp_cadr (list); + gcry_sexp_release (list); + list = l2; + if (!list) + return 0; /* Bad public key. */ + + l2 = gcry_sexp_find_token (list, "curve", 0); + gcry_sexp_release (list); + if (!l2) + return 0; /* No curve parameter. */ + curve = gcry_sexp_nth_string (l2, 1); + gcry_sexp_release (l2); + if (!curve) + return 0; /* Bad curve parameter. */ + result = (!ascii_strcasecmp (curve, "X448") + || !ascii_strcasecmp (curve, "Ed448") + || !ascii_strcasecmp (curve, "cv448")); + xfree (curve); + return result; +} + + static gpg_error_t ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) { @@ -1404,7 +1437,7 @@ static int do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip, int cardkey, kbnode_t pub_root, u32 timestamp, u32 expireval, - int is_subkey, int keygen_flags) + int is_subkey, int *keygen_flags) { int err; PACKET *pkt; @@ -1448,6 +1481,10 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, return err; } + /* For X448 we force the use of v5 packets. */ + if (curve_is_448 (s_key)) + *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + /* Build a public key packet. */ pk = xtrycalloc (1, sizeof *pk); if (!pk) @@ -1458,7 +1495,7 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, } pk->timestamp = timestamp; - pk->version = (keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; + pk->version = (*keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; if (expireval) pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; @@ -1709,12 +1746,14 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, /* - * Generate an ECC key + * Generate an ECC key. + * Note that KEYGEN_FLAGS might be updated by this function to + * indicate the forced creation of a v5 key. */ static gpg_error_t gen_ecc (int algo, const char *curve, kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, - int keygen_flags, const char *passphrase, + int *keygen_flags, const char *passphrase, char **cache_nonce_addr, char **passwd_nonce_addr) { gpg_error_t err; @@ -1741,40 +1780,52 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root, /* Note that we use the "comp" flag with EdDSA to request the use of a 0x40 compression prefix octet. */ if (algo == PUBKEY_ALGO_EDDSA && !strcmp (curve, "Ed25519")) - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags eddsa comp%s)))", - strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + { + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags eddsa comp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } else if (algo == PUBKEY_ALGO_EDDSA && !strcmp (curve, "Ed448")) - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags comp%s)))", - strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + { + *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags comp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } else if (algo == PUBKEY_ALGO_ECDH && !strcmp (curve, "Curve25519")) - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))", + { + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))", strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } else if (algo == PUBKEY_ALGO_ECDH && !strcmp (curve, "X448")) - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags comp%s)))", - strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + { + *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags comp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } else - keyparms = xtryasprintf - ("(genkey(ecc(curve %zu:%s)(flags nocomp%s)))", - strlen (curve), curve, - (((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? - " transient-key" : "")); + { + keyparms = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags nocomp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } if (!keyparms) err = gpg_error_from_syserror (); @@ -1782,7 +1833,7 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root, { err = common_gen (keyparms, algo, "", pub_root, timestamp, expireval, is_subkey, - keygen_flags, passphrase, + *keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr); xfree (keyparms); } @@ -3200,11 +3251,12 @@ ask_user_id (int mode, int full, KBNODE keyblock) /* Basic key generation. Here we divert to the actual generation - routines based on the requested algorithm. */ + * routines based on the requested algorithm. KEYGEN_FLAGS might be + * updated by this function. */ static int do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, u32 timestamp, u32 expiredate, int is_subkey, - int keygen_flags, const char *passphrase, + int *keygen_flags, const char *passphrase, char **cache_nonce_addr, char **passwd_nonce_addr) { gpg_error_t err; @@ -3220,11 +3272,11 @@ do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, if (algo == PUBKEY_ALGO_ELGAMAL_E) err = gen_elg (algo, nbits, pub_root, timestamp, expiredate, is_subkey, - keygen_flags, passphrase, + *keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr); else if (algo == PUBKEY_ALGO_DSA) err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey, - keygen_flags, passphrase, + *keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr); else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA @@ -3234,7 +3286,7 @@ do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, cache_nonce_addr, passwd_nonce_addr); else if (algo == PUBKEY_ALGO_RSA) err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey, - keygen_flags, passphrase, + *keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr); else BUG(); @@ -5074,7 +5126,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, strcpy (r->u.value, curve); r->next = para; para = r; - if (!strcmp (curve, "Ed448")) + if (!strcmp (curve, "X448") || !strcmp (curve, "Ed448")) { r = xmalloc_clear (sizeof *r + 20); r->key = pVERSION; @@ -5156,7 +5208,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname, strcpy (r->u.value, curve); r->next = para; para = r; - if (!strcmp (curve, "Ed448")) + if (!strcmp (curve, "X448") || !strcmp (curve, "Ed448")) { r = xmalloc_clear (sizeof *r + 20); r->key = pVERSION; @@ -5587,7 +5639,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip, cardkey, pub_root, keytimestamp, - expire, 0, keygen_flags); + expire, 0, &keygen_flags); else if (!card) err = do_create (algo, get_parameter_uint( para, pKEYLENGTH ), @@ -5595,13 +5647,13 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, pub_root, keytimestamp, expire, 0, - keygen_flags, + &keygen_flags, get_parameter_passphrase (para), &cache_nonce, NULL); else err = gen_card_key (1, algo, 1, pub_root, &keytimestamp, - expire, keygen_flags); + expire, &keygen_flags); /* Get the pointer to the generated public key packet. */ if (!err) @@ -5645,7 +5697,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, { err = gen_card_key (3, get_parameter_algo (ctrl, para, pAUTHKEYTYPE, NULL ), - 0, pub_root, &authkeytimestamp, expire, keygen_flags); + 0, pub_root, &authkeytimestamp, expire, + &keygen_flags); if (!err) err = write_keybinding (ctrl, pub_root, pri_psk, NULL, PUBKEY_USAGE_AUTH, signtimestamp, cache_nonce); @@ -5667,16 +5720,18 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, key_from_hexgrip, cardkey, pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), - 1, keygen_flags); + 1, &keygen_flags); else if (!card || (s = get_parameter_value (para, pCARDBACKUPKEY))) { + unsigned int mykeygenflags = KEYGEN_FLAG_NO_PROTECTION; + err = do_create (subkey_algo, get_parameter_uint (para, pSUBKEYLENGTH), get_parameter_value (para, pSUBKEYCURVE), pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, - s? KEYGEN_FLAG_NO_PROTECTION : keygen_flags, + s? &mykeygenflags : &keygen_flags, get_parameter_passphrase (para), &cache_nonce, NULL); /* Get the pointer to the generated public subkey packet. */ @@ -5697,7 +5752,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, else { err = gen_card_key (2, subkey_algo, 0, pub_root, - &subkeytimestamp, expire, keygen_flags); + &subkeytimestamp, expire, &keygen_flags); } if (!err) @@ -6071,7 +6126,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, keyblock, keytime? keytime : cur_time, expire, 1, - keygen_flags); + &keygen_flags); } else { @@ -6087,7 +6142,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, passwd = NULL; err = do_create (algo, nbits, curve, - keyblock, cur_time, expire, 1, keygen_flags, + keyblock, cur_time, expire, 1, &keygen_flags, passwd, &cache_nonce, &passwd_nonce); } if (err) @@ -6211,7 +6266,7 @@ generate_card_subkeypair (ctrl_t ctrl, kbnode_t pub_keyblock, /* Note, that depending on the backend, the card key generation may update CUR_TIME. */ err = gen_card_key (keyno, algo, 0, pub_keyblock, &cur_time, expire, - keygen_flags); + &keygen_flags); /* Get the pointer to the generated public subkey packet. */ if (!err) { @@ -6257,11 +6312,10 @@ write_keyblock( IOBUF out, KBNODE node ) } -/* Note that timestamp is an in/out arg. - * FIXME: Does not yet support v5 keys. */ +/* Note that timestamp is an in/out arg. */ static gpg_error_t gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, - u32 *timestamp, u32 expireval, int keygen_flags) + u32 *timestamp, u32 expireval, int *keygen_flags) { #ifdef ENABLE_CARD_SUPPORT gpg_error_t err; @@ -6325,6 +6379,10 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, return err; } + /* Force creation of v5 keys for X448. */ + if (curve_is_448 (s_key)) + *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + if (algo == PUBKEY_ALGO_RSA) err = key_from_sexp (pk->pkey, s_key, "public-key", "ne"); else if (algo == PUBKEY_ALGO_ECDSA @@ -6343,7 +6401,7 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, } pk->timestamp = *timestamp; - pk->version = (keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; + pk->version = (*keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; if (expireval) pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; From cb8eb366cb009b66af95c7b5a147db4c6a651e40 Mon Sep 17 00:00:00 2001 From: Tobias Fella Date: Thu, 18 Jan 2024 11:23:51 +0100 Subject: [PATCH 321/869] Pass PINENTRY_GEOM_HINT environment variable to pinentry * common/session-env.c: Add PINENTRY_GEOM_HINT to variables. -- GnuPG-Bug-ID: 6930 --- common/session-env.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/session-env.c b/common/session-env.c index f07d9d101..e774c1d9b 100644 --- a/common/session-env.c +++ b/common/session-env.c @@ -84,9 +84,10 @@ static struct modules (eg "xim"). */ { "INSIDE_EMACS" }, /* Set by Emacs before running a process. */ - { "PINENTRY_USER_DATA", "pinentry-user-data"} + { "PINENTRY_USER_DATA", "pinentry-user-data"}, /* Used for communication with non-standard Pinentries. */ + { "PINENTRY_GEOM_HINT" } /* Used to pass window information. */ }; From c8060a8f23a72cab399c4d7212c97529ae83ba34 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 19 Jan 2024 12:40:58 +0100 Subject: [PATCH 322/869] doc: Document Backup-info in keyformat.txt -- This name is used by Kleopatra for quite some time now but was missing a specification. --- agent/keyformat.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/agent/keyformat.txt b/agent/keyformat.txt index fbe999ca1..e0c4df0f0 100644 --- a/agent/keyformat.txt +++ b/agent/keyformat.txt @@ -155,6 +155,16 @@ This field is for card key. If given and the value is "yes" dialog window when card is not available. When the value is "no", a card operation is refused with GPG_ERR_UNUSABLE_SECKEY error. +*** Backup-info +This gives information for a backup of the key. The follwoing fields +are space delimited: + +- Hexified keygrip (uppercase) to make it easy to identify the + filename. When restoring software should make sure that the keygrip + matches the one derived from the "Key" field. +- Backup time in as ISO string. +- Name of the backup software. +- Arbitrary information. * Private Key Format ** Unprotected Private Key Format From adeb17e37588cf88300a2df91a4ec2ec34fccec7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Jan 2024 18:05:46 +0100 Subject: [PATCH 323/869] card: New subcommand "checkkeys". * agent/command.c (cmd_havekey): Add new option --info. * tools/card-call-scd.c (scd_readkey): Allow using without result arg. (struct havekey_status_parm_s): New. (havekey_status_cb): New. (scd_havekey_info): New. (scd_delete_key): New. * tools/gpg-card.c (print_keygrip): Add arg with_lf. (cmd_checkkeys): New. (cmdCHECKKEYS): New. (cmds): Add command "checkkeys". (dispatch_command, interactive_loop): Call cmd_checkkeys. -- GnuPG-bug-id: 6943 --- agent/command.c | 44 ++++++++++++-- tools/card-call-scd.c | 92 +++++++++++++++++++++++++++- tools/gpg-card.c | 138 +++++++++++++++++++++++++++++++++++++++++- tools/gpg-card.h | 2 + 4 files changed, 265 insertions(+), 11 deletions(-) diff --git a/agent/command.c b/agent/command.c index b7a71cbe5..da91053d8 100644 --- a/agent/command.c +++ b/agent/command.c @@ -634,10 +634,12 @@ cmd_marktrusted (assuan_context_t ctx, char *line) static const char hlp_havekey[] = "HAVEKEY \n" "HAVEKEY --list[=]\n" + "HAVEKEY --info \n" "\n" "Return success if at least one of the secret keys with the given\n" "keygrips is available. With --list return all available keygrips\n" - "as binary data; with bail out at this number of keygrips"; + "as binary data; with bail out at this number of keygrips.\n" + "In --info mode check just one keygrip."; static gpg_error_t cmd_havekey (assuan_context_t ctx, char *line) { @@ -645,7 +647,8 @@ cmd_havekey (assuan_context_t ctx, char *line) gpg_error_t err; unsigned char grip[20]; char *p; - int list_mode; /* Less than 0 for no limit. */ + int list_mode = 0; /* Less than 0 for no limit. */ + int info_mode = 0; int counter; char *dirname; gnupg_dir_t dir; @@ -653,15 +656,46 @@ cmd_havekey (assuan_context_t ctx, char *line) char hexgrip[41]; struct card_key_info_s *keyinfo_on_cards, *l; - if (has_option_name (line, "--list")) + if (has_option (line, "--info")) + info_mode = 1; + else if (has_option_name (line, "--list")) { if ((p = option_value (line, "--list"))) list_mode = atoi (p); else list_mode = -1; } - else - list_mode = 0; + + line = skip_options (line); + + + if (info_mode) + { + int keytype; + const char *infostring; + + ctrl = assuan_get_pointer (ctx); + + err = parse_keygrip (ctx, line, grip); + if (err) + goto leave; + + err = agent_key_info_from_file (ctrl, grip, &keytype, NULL, NULL); + if (err) + goto leave; + + switch (keytype) + { + case PRIVATE_KEY_CLEAR: + case PRIVATE_KEY_OPENPGP_NONE: infostring = "clear"; break; + case PRIVATE_KEY_PROTECTED: infostring = "protected"; break; + case PRIVATE_KEY_SHADOWED: infostring = "shadowed"; break; + default: infostring = "unknown"; break; + } + + err = agent_write_status (ctrl, "KEYFILEINFO", infostring, NULL); + goto leave; + } if (!list_mode) diff --git a/tools/card-call-scd.c b/tools/card-call-scd.c index 34b03e694..f6ce565c3 100644 --- a/tools/card-call-scd.c +++ b/tools/card-call-scd.c @@ -1529,14 +1529,16 @@ scd_readkey (const char *keyrefstr, int create_shadow, gcry_sexp_t *r_result) unsigned char *buf; size_t len, buflen; - *r_result = NULL; + if (r_result) + *r_result = NULL; err = start_agent (0); if (err) return err; init_membuf (&data, 1024); if (create_shadow) - snprintf (line, DIM(line), "READKEY --card -- %s", keyrefstr); + snprintf (line, DIM(line), "READKEY %s--card -- %s", + r_result? "" : "--no-data ", keyrefstr); else snprintf (line, DIM(line), "SCD READKEY %s", keyrefstr); err = assuan_transact (agent_ctx, line, @@ -1552,7 +1554,7 @@ scd_readkey (const char *keyrefstr, int create_shadow, gcry_sexp_t *r_result) if (!buf) return gpg_error_from_syserror (); - err = gcry_sexp_new (r_result, buf, buflen, 0); + err = r_result ? gcry_sexp_new (r_result, buf, buflen, 0) : 0; xfree (buf); return err; @@ -1769,6 +1771,90 @@ agent_get_s2k_count (void) } + +struct havekey_status_parm_s +{ + char *string; +}; + +static gpg_error_t +havekey_status_cb (void *opaque, const char *line) +{ + struct havekey_status_parm_s *parm = opaque; + const char *s; + char *p; + + if ((s = has_leading_keyword (line, "KEYFILEINFO"))) + { + xfree (parm->string); + parm->string = xtrystrdup (s); + if (!parm->string) + return gpg_error_from_syserror (); + p = strchr (parm->string, ' '); + if (p) + *p = 0; + } + + return 0; +} + + +/* Run the HAVEKEY --info command and stores the retrieved string at + * R_RESULT. Caller must free that string. If an error is returned + * R_RESULT is set to NULL. */ +gpg_error_t +scd_havekey_info (const unsigned char *grip, char **r_result) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + struct havekey_status_parm_s parm = {NULL}; + + *r_result = NULL; + + err = start_agent (0); + if (err) + return err; + + snprintf (line, sizeof line, "HAVEKEY --info "); + log_assert (ASSUAN_LINELENGTH > strlen(line) + 2*KEYGRIP_LEN + 10); + bin2hex (grip, KEYGRIP_LEN, line+strlen(line)); + + err = assuan_transact (agent_ctx, line, + NULL, NULL, NULL, NULL, + havekey_status_cb, &parm); + if (err) + xfree (parm.string); + else + *r_result = parm.string; + return err; +} + + +/* Run the DELETE_KEY command. If FORCE is given the user will not be + * asked for confirmation. */ +gpg_error_t +scd_delete_key (const unsigned char *grip, int force) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + struct default_inq_parm_s dfltparm = {NULL}; + + err = start_agent (0); + if (err) + return err; + dfltparm.ctx = agent_ctx; + + snprintf (line, sizeof line, "DELETE_KEY%s ", force?" --force":""); + log_assert (ASSUAN_LINELENGTH > strlen(line) + 2*KEYGRIP_LEN + 10); + bin2hex (grip, KEYGRIP_LEN, line+strlen(line)); + + err = assuan_transact (agent_ctx, line, + NULL, NULL, default_inq_cb, &dfltparm, NULL, NULL); + return err; +} + + + /* Return a malloced string describing the statusword SW. On error * NULL is returned. */ char * diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 4b0457ab9..442acdc84 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -582,13 +582,14 @@ print_shax_fpr (estream_t fp, const unsigned char *fpr, unsigned int fprlen) /* Print the keygrip GRP. */ static void -print_keygrip (estream_t fp, const unsigned char *grp) +print_keygrip (estream_t fp, const unsigned char *grp, int with_lf) { int i; for (i=0; i < 20 ; i++, grp++) tty_fprintf (fp, "%02X", *grp); - tty_fprintf (fp, "\n"); + if (with_lf) + tty_fprintf (fp, "\n"); } @@ -700,7 +701,7 @@ list_one_kinfo (card_info_t info, key_info_t kinfo, goto leave; } - print_keygrip (fp, kinfo->grip); + print_keygrip (fp, kinfo->grip, 1); tty_fprintf (fp, " keyref .....: %s", kinfo->keyref); if (kinfo->usage) { @@ -1376,6 +1377,133 @@ cmd_list (card_info_t info, char *argstr) } + +/* The CHECKKEYS command. */ +static gpg_error_t +cmd_checkkeys (card_info_t callerinfo, char *argstr) +{ + gpg_error_t err; + estream_t fp = opt.interactive? NULL : es_stdout; + strlist_t cards = NULL; + strlist_t sl; + int opt_ondisk; + int opt_delete_clear; + int opt_delete_protected; + int delete_count = 0; + struct card_info_s info_buffer = { 0 }; + card_info_t info = &info_buffer; + key_info_t kinfo; + + + if (!callerinfo) + return print_help + ("CHECKKEYS [--ondisk] [--delete-clear-copy]\n\n" + "Print a list of keys on all inserted cards. With --ondisk only\n" + "keys are listed which also have a copy on disk. Missing shadow\n" + "keys are created. With --delete-clear, copies of keys also stored\n" + "on disk without any protection will be deleted.\n" + , 0); + + + opt_ondisk = has_leading_option (argstr, "--ondisk"); + opt_delete_clear = has_leading_option (argstr, "--delete-clear-copy"); + opt_delete_protected = has_leading_option (argstr, "--delete-protected-copy"); + argstr = skip_options (argstr); + + if (*argstr) + { + /* No args expected */ + err = gpg_error (GPG_ERR_INV_ARG); + goto leave; + } + + if (!callerinfo->serialno) + { + /* This is probably the first call We need to send a SERIALNO + * command to scdaemon so that our session knows all cards. */ + err = scd_serialno (NULL, NULL); + if (err) + goto leave; + } + + /* Get the list of all cards. */ + err = scd_cardlist (&cards); + if (err) + goto leave; + + /* Loop over all cards. We use our own info buffer here. */ + for (sl = cards; sl; sl = sl->next) + { + err = scd_switchcard (sl->d); + if (err) + { + log_error ("Error switching to card %s: %s\n", + sl->d, gpg_strerror (err)); + continue; + } + release_card_info (info); + err = scd_learn (info, 0); + if (err) + { + log_error ("Error getting infos from card %s: %s\n", + sl->d, gpg_strerror (err)); + continue; + } + + for (kinfo = info->kinfo; kinfo; kinfo = kinfo->next) + { + char *infostr; + + err = scd_havekey_info (kinfo->grip, &infostr); + if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) + { + /* Create a shadow key and try again. */ + scd_readkey (kinfo->keyref, 1, NULL); + err = scd_havekey_info (kinfo->grip, &infostr); + } + if (err) + log_error ("Error getting infos for a key: %s\n", + gpg_strerror (err)); + + if (opt_ondisk && infostr && !strcmp (infostr, "shadowed")) + ; /* Don't print this one. */ + else + { + tty_fprintf (fp, "%s %s ", + nullnone (info->serialno), + app_type_string (info->apptype)); + print_keygrip (fp, kinfo->grip, 0); + tty_fprintf (fp, " %s %s\n", + kinfo->keyref, infostr? infostr: "error"); + } + if (infostr + && ((opt_delete_clear && !strcmp (infostr, "clear")) + || (opt_delete_protected && !strcmp (infostr, "protected")))) + { + err = scd_delete_key (kinfo->grip, 0); + if (err) + log_error ("Error deleting a key copy: %s\n", + gpg_strerror (err)); + else + delete_count++; + } + xfree (infostr); + } + } + if (delete_count) + log_info ("Number of deleted key copies: %d\n", delete_count); + + err = 0; + + leave: + release_card_info (info); + free_strlist (cards); + /* Better reset to the original card. */ + scd_learn (callerinfo, 0); + return err; +} + + /* The VERIFY command. */ static gpg_error_t @@ -3726,6 +3854,7 @@ enum cmdids cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT, cmdREADCERT, cmdWRITEKEY, cmdUNBLOCK, cmdFACTRST, cmdKDFSETUP, cmdUIF, cmdAUTH, cmdYUBIKEY, cmdAPDU, cmdGPG, cmdGPGSM, cmdHISTORY, + cmdCHECKKEYS, cmdINVCMD }; @@ -3765,6 +3894,7 @@ static struct { "readcert", cmdREADCERT, N_("read a certificate from a data object")}, { "writecert", cmdWRITECERT, N_("store a certificate to a data object")}, { "writekey", cmdWRITEKEY, N_("store a private key to a data object")}, + { "checkkeys", cmdCHECKKEYS, N_("run various checks on the keys")}, { "yubikey", cmdYUBIKEY, N_("Yubikey management commands")}, { "gpg", cmdGPG, NULL}, { "gpgsm", cmdGPGSM, NULL}, @@ -3901,6 +4031,7 @@ dispatch_command (card_info_t info, const char *orig_command) case cmdGPG: err = cmd_gpg (info, argstr, 0); break; case cmdGPGSM: err = cmd_gpg (info, argstr, 1); break; case cmdHISTORY: err = 0; break; /* Only used in interactive mode. */ + case cmdCHECKKEYS: err = cmd_checkkeys (info, argstr); break; case cmdINVCMD: default: @@ -4160,6 +4291,7 @@ interactive_loop (void) case cmdGPG: err = cmd_gpg (info, argstr, 0); break; case cmdGPGSM: err = cmd_gpg (info, argstr, 1); break; case cmdHISTORY: err = cmd_history (info, argstr); break; + case cmdCHECKKEYS: err = cmd_checkkeys (info, argstr); break; case cmdINVCMD: default: diff --git a/tools/gpg-card.h b/tools/gpg-card.h index 86b63cda0..5b49ef31e 100644 --- a/tools/gpg-card.h +++ b/tools/gpg-card.h @@ -246,6 +246,8 @@ gpg_error_t scd_cardlist (strlist_t *result); gpg_error_t scd_applist (strlist_t *result, int all); gpg_error_t scd_change_pin (const char *pinref, int reset_mode, int nullpin); gpg_error_t scd_checkpin (const char *serialno); +gpg_error_t scd_havekey_info (const unsigned char *grip, char **r_result); +gpg_error_t scd_delete_key (const unsigned char *grip, int force); unsigned long agent_get_s2k_count (void); From ee56f71c8a68d909d99062e96c23ffe9f8533b2b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 Jan 2024 18:34:19 +0100 Subject: [PATCH 324/869] gpg: Add a communication object to the key generation code. * g10/keygen.c (struct common_gen_cb_parm_s): New. (common_gen): Add args common_gen_cb and common_gen_cb_parm. Adjust all callers. (do_generate_keypair): Clarify the code by using a better var name. -- We may eventually also replace the long arg list with that object. The immediate reason for this change is the followup commit. --- g10/keygen.c | 94 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 22 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 8e50a795e..886c3b007 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -131,6 +131,18 @@ struct output_control_s }; +/* An object to help communicating with the actual key generation + * code. */ +struct common_gen_cb_parm_s +{ + /* This variable set to the result of agent_genkey. The callback + * may take a copy of this so that the result can be used after we + * are back from the deep key generation call stack. */ + gcry_sexp_t genkey_result; +}; +typedef struct common_gen_cb_parm_s *common_gen_cb_parm_t; + + /* FIXME: These globals vars are ugly. And using MAX_PREFS even for * aeads is useless, given that we don't expects more than a very few * algorithms. */ @@ -1531,12 +1543,17 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, } -/* Common code for the key generation function gen_xxx. */ +/* Common code for the key generation function gen_xxx. The optinal + * (COMMON_GEN_CB,COMMON_GEN_CB_PARM) can be used as communication + * object. + */ static int common_gen (const char *keyparms, int algo, const char *algoelem, kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { int err; PACKET *pkt; @@ -1553,6 +1570,18 @@ common_gen (const char *keyparms, int algo, const char *algoelem, return err; } + if (common_gen_cb && common_gen_cb_parm) + { + common_gen_cb_parm->genkey_result = s_key; + err = common_gen_cb (common_gen_cb_parm); + common_gen_cb_parm->genkey_result = NULL; + if (err) + { + gcry_sexp_release (s_key); + return err; + } + } + pk = xtrycalloc (1, sizeof *pk); if (!pk) { @@ -1605,7 +1634,9 @@ static int gen_elg (int algo, unsigned int nbits, KBNODE pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { int err; char *keyparms; @@ -1647,7 +1678,8 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root, err = common_gen (keyparms, algo, "pgy", pub_root, timestamp, expireval, is_subkey, keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); xfree (keyparms); } @@ -1662,7 +1694,9 @@ static gpg_error_t gen_dsa (unsigned int nbits, KBNODE pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { int err; unsigned int qbits; @@ -1736,7 +1770,8 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy", pub_root, timestamp, expireval, is_subkey, keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); xfree (keyparms); } @@ -1754,7 +1789,9 @@ static gpg_error_t gen_ecc (int algo, const char *curve, kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, int *keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { gpg_error_t err; char *keyparms; @@ -1834,7 +1871,8 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root, err = common_gen (keyparms, algo, "", pub_root, timestamp, expireval, is_subkey, *keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); xfree (keyparms); } @@ -1849,7 +1887,9 @@ static int gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { int err; char *keyparms; @@ -1891,7 +1931,8 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, err = common_gen (keyparms, algo, "ne", pub_root, timestamp, expireval, is_subkey, keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); xfree (keyparms); } @@ -3257,7 +3298,9 @@ static int do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, u32 timestamp, u32 expiredate, int is_subkey, int *keygen_flags, const char *passphrase, - char **cache_nonce_addr, char **passwd_nonce_addr) + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) { gpg_error_t err; @@ -3273,21 +3316,25 @@ do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, if (algo == PUBKEY_ALGO_ELGAMAL_E) err = gen_elg (algo, nbits, pub_root, timestamp, expiredate, is_subkey, *keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); else if (algo == PUBKEY_ALGO_DSA) err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey, *keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH) err = gen_ecc (algo, curve, pub_root, timestamp, expiredate, is_subkey, keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); else if (algo == PUBKEY_ALGO_RSA) err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey, *keygen_flags, passphrase, - cache_nonce_addr, passwd_nonce_addr); + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); else BUG(); @@ -5649,7 +5696,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, expire, 0, &keygen_flags, get_parameter_passphrase (para), - &cache_nonce, NULL); + &cache_nonce, NULL, + NULL, NULL); else err = gen_card_key (1, algo, 1, pub_root, &keytimestamp, @@ -5706,9 +5754,9 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, if (!err && get_parameter (para, pSUBKEYTYPE)) { + const char *cardbackupkey = NULL; int subkey_algo = get_parameter_algo (ctrl, para, pSUBKEYTYPE, NULL); - s = NULL; key_from_hexgrip = get_parameter_value (para, pSUBKEYGRIP); keygen_flags = outctrl->keygen_flags; @@ -5721,7 +5769,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, &keygen_flags); - else if (!card || (s = get_parameter_value (para, pCARDBACKUPKEY))) + else if (!card + || (cardbackupkey = get_parameter_value (para, pCARDBACKUPKEY))) { unsigned int mykeygenflags = KEYGEN_FLAG_NO_PROTECTION; @@ -5731,9 +5780,10 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, - s? &mykeygenflags : &keygen_flags, + cardbackupkey? &mykeygenflags : &keygen_flags, get_parameter_passphrase (para), - &cache_nonce, NULL); + &cache_nonce, NULL, + NULL, NULL); /* Get the pointer to the generated public subkey packet. */ if (!err) { @@ -5744,7 +5794,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, sub_psk = node->pkt->pkt.public_key; log_assert (sub_psk); - if (s) + if (cardbackupkey) err = card_store_key_with_backup (ctrl, sub_psk, gnupg_homedir ()); } @@ -6143,7 +6193,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, err = do_create (algo, nbits, curve, keyblock, cur_time, expire, 1, &keygen_flags, - passwd, &cache_nonce, &passwd_nonce); + passwd, &cache_nonce, &passwd_nonce, NULL, NULL); } if (err) goto leave; From 18320d692cfd52df25339fcb650898f5dda0c8c6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Jan 2024 10:15:29 +0100 Subject: [PATCH 325/869] doc: Fix description of gpg --unwrap -- --- doc/gpg.texi | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 7e51aff6f..a54bc1fee 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -638,12 +638,11 @@ The @option{--dearmor} command can also be used to dearmor PEM armors. @item --unwrap @opindex unwrap -This command is similar to @option{--decrypt} with the difference that the -output is not the usual plaintext but the original message with the -encryption layer removed. Thus the output will be an OpenPGP data -structure which often means a signed OpenPGP message. Note that this -option may or may not remove a compression layer which is often found -beneath the encryption layer. +This option modifies the command @option{--decrypt} to output the +original message with the encryption layer removed. Thus the output +will be an OpenPGP data structure which often means a signed OpenPGP +message. Note that this option may or may not remove a compression +layer which is often found beneath the encryption layer. @item --tofu-policy @{auto|good|unknown|bad|ask@} @var{keys} @opindex tofu-policy From 434a641d40cbff82beb9f485e0adca72419bfdf2 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Jan 2024 13:22:44 +0100 Subject: [PATCH 326/869] agent: Add "ephemeral" Assuan option. * agent/agent.h (struct ephemeral_private_key_s): New. (struct server_control_s): Add ephemeral_mode and ephemeral_keys. (GENKEY_FLAG_NO_PROTECTION, GENKEY_FLAG_PRESET): New. * agent/genkey.c (clear_ephemeral_keys): New. (store_key): Add arg ctrl and implement ephemeral_mode. Change all callers. (agent_genkey): Replace args no_protection and preset by a generic new flags arg. * agent/findkey.c (wipe_and_fclose): New. (agent_write_private_key): Add arg ctrl and implement ephemeral_mode. Change all callers. (agent_update_private_key): Ditto (read_key_file): Ditto. (agent_key_available): Ditto. * agent/command-ssh.c (card_key_available): Do not update display s/n in ephemeral mode. This is however enver triggred. * agent/gpg-agent.c (agent_deinit_default_ctrl): Cleanup ephemeral keys. * agent/command.c (cmd_genkey): Use the new flags instead of separate vars. (cmd_readkey): Create a shadow key only in non-ephemeral_mode. (cmd_getinfo): Add sub-command "ephemeral". (option_handler): Add option "ephemeral". -- The idea here that a session can be switched in an ephemeral mode which does not store or read keys from disk but keeps them local to the session. GnuPG-bug-id: 6944 --- agent/agent.h | 39 ++++- agent/command-ssh.c | 8 +- agent/command.c | 73 +++++---- agent/cvt-openpgp.c | 10 +- agent/divert-tpm2.c | 4 +- agent/findkey.c | 380 +++++++++++++++++++++++++++++++------------ agent/genkey.c | 156 +++++++++++++----- agent/gpg-agent.c | 1 + agent/learncard.c | 20 ++- agent/pksign.c | 5 +- agent/protect-tool.c | 6 +- 11 files changed, 496 insertions(+), 206 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 531fad210..f0b2a334e 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -225,6 +225,17 @@ typedef struct ssh_control_file_s *ssh_control_file_t; /* Forward reference for local definitions in call-scd.c. */ struct daemon_local_s; +/* Object to hold ephemeral secret keys. */ +struct ephemeral_private_key_s +{ + struct ephemeral_private_key_s *next; + unsigned char grip[KEYGRIP_LEN]; + unsigned char *keybuf; /* Canon-s-exp with the private key (malloced). */ + size_t keybuflen; +}; +typedef struct ephemeral_private_key_s *ephemeral_private_key_t; + + /* Collection of data per session (aka connection). */ struct server_control_s { @@ -246,6 +257,12 @@ struct server_control_s /* Private data of the daemon (call-XXX.c). */ struct daemon_local_s *d_local[DAEMON_MAX_TYPE]; + /* Linked list with ephemeral stored private keys. */ + ephemeral_private_key_t ephemeral_keys; + + /* If set functions will lookup keys in the ephemeral_keys list. */ + int ephemeral_mode; + /* Environment settings for the connection. */ session_env_t session_env; char *lc_ctype; @@ -452,7 +469,8 @@ void start_command_handler_ssh (ctrl_t, gnupg_fd_t); /*-- findkey.c --*/ gpg_error_t agent_modify_description (const char *in, const char *comment, const gcry_sexp_t key, char **result); -gpg_error_t agent_write_private_key (const unsigned char *grip, +gpg_error_t agent_write_private_key (ctrl_t ctrl, + const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, @@ -477,7 +495,7 @@ gpg_error_t agent_ssh_key_from_file (ctrl_t ctrl, gcry_sexp_t *result, int *r_order); int agent_pk_get_algo (gcry_sexp_t s_key); int agent_is_tpm2_key(gcry_sexp_t s_key); -int agent_key_available (const unsigned char *grip); +int agent_key_available (ctrl_t ctrl, const unsigned char *grip); gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, int *r_keytype, unsigned char **r_shadow_info, @@ -485,7 +503,8 @@ gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, gpg_error_t agent_delete_key (ctrl_t ctrl, const char *desc_text, const unsigned char *grip, int force, int only_stubs); -gpg_error_t agent_update_private_key (const unsigned char *grip, nvc_t pk); +gpg_error_t agent_update_private_key (ctrl_t ctrl, + const unsigned char *grip, nvc_t pk); /*-- call-pinentry.c --*/ void initialize_module_call_pinentry (void); @@ -541,15 +560,21 @@ gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, #define CHECK_CONSTRAINTS_NOT_EMPTY 1 #define CHECK_CONSTRAINTS_NEW_SYMKEY 2 +#define GENKEY_FLAG_NO_PROTECTION 1 +#define GENKEY_FLAG_PRESET 2 + +void clear_ephemeral_keys (ctrl_t ctrl); + int check_passphrase_constraints (ctrl_t ctrl, const char *pw, unsigned int flags, char **failed_constraint); gpg_error_t agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt, char **r_passphrase); -int agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, +int agent_genkey (ctrl_t ctrl, unsigned int flags, + const char *cache_nonce, time_t timestamp, const char *keyparam, size_t keyparmlen, - int no_protection, const char *override_passphrase, - int preset, membuf_t *outbuf); + const char *override_passphrase, + membuf_t *outbuf); gpg_error_t agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey, char **passphrase_addr); @@ -587,7 +612,7 @@ gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo, const unsigned char *s2ksalt, unsigned int s2kcount, unsigned char *key, size_t keylen); -gpg_error_t agent_write_shadow_key (const unsigned char *grip, +gpg_error_t agent_write_shadow_key (ctrl_t ctrl, const unsigned char *grip, const char *serialno, const char *keyid, const unsigned char *pkbuf, int force, const char *dispserialno); diff --git a/agent/command-ssh.c b/agent/command-ssh.c index ca3993321..189acd7f8 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -2430,14 +2430,14 @@ card_key_available (ctrl_t ctrl, const struct card_key_info_s *keyinfo, } hex2bin (keyinfo->keygrip, grip, sizeof (grip)); - if ( agent_key_available (grip) ) + if (!ctrl->ephemeral_mode && agent_key_available (ctrl, grip) ) { char *dispserialno; /* (Shadow)-key is not available in our key storage. */ agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, keyinfo->keygrip); - err = agent_write_shadow_key (grip, keyinfo->serialno, + err = agent_write_shadow_key (ctrl, grip, keyinfo->serialno, keyinfo->idstr, pkbuf, 0, dispserialno); xfree (dispserialno); if (err) @@ -3222,7 +3222,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, /* Check whether the key is already in our key storage. Don't do anything then besides (re-)adding it to sshcontrol. */ - if ( !agent_key_available (key_grip_raw) ) + if ( !agent_key_available (ctrl, key_grip_raw) ) goto key_exists; /* Yes, key is available. */ err = ssh_key_extract_comment (key, &comment); @@ -3286,7 +3286,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, /* Store this key to our key storage. We do not store a creation * timestamp because we simply do not know. */ - err = agent_write_private_key (key_grip_raw, buffer, buffer_n, 0, + err = agent_write_private_key (ctrl, key_grip_raw, buffer, buffer_n, 0, NULL, NULL, NULL, 0); if (err) goto out; diff --git a/agent/command.c b/agent/command.c index da91053d8..20ae08e9f 100644 --- a/agent/command.c +++ b/agent/command.c @@ -251,6 +251,9 @@ reset_notify (assuan_context_t ctx, char *line) clear_nonce_cache (ctrl); + /* Note that a RESET does not clear the ephemeral store becuase + * clients are used to issue a RESET on a connection. */ + return 0; } @@ -643,15 +646,15 @@ static const char hlp_havekey[] = static gpg_error_t cmd_havekey (assuan_context_t ctx, char *line) { - ctrl_t ctrl; + ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; unsigned char grip[20]; char *p; int list_mode = 0; /* Less than 0 for no limit. */ int info_mode = 0; int counter; - char *dirname; - gnupg_dir_t dir; + char *dirname = NULL; + gnupg_dir_t dir = NULL; gnupg_dirent_t dir_entry; char hexgrip[41]; struct card_key_info_s *keyinfo_on_cards, *l; @@ -668,14 +671,11 @@ cmd_havekey (assuan_context_t ctx, char *line) line = skip_options (line); - if (info_mode) { int keytype; const char *infostring; - ctrl = assuan_get_pointer (ctx); - err = parse_keygrip (ctx, line, grip); if (err) goto leave; @@ -706,7 +706,7 @@ cmd_havekey (assuan_context_t ctx, char *line) if (err) return err; - if (!agent_key_available (grip)) + if (!agent_key_available (ctrl, grip)) return 0; /* Found. */ while (*line && *line != ' ' && *line != '\t') @@ -724,7 +724,6 @@ cmd_havekey (assuan_context_t ctx, char *line) /* List mode. */ dir = NULL; dirname = NULL; - ctrl = assuan_get_pointer (ctx); if (ctrl->restricted) { @@ -1117,26 +1116,27 @@ cmd_genkey (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int rc; - int no_protection; unsigned char *value = NULL; size_t valuelen; unsigned char *newpasswd = NULL; membuf_t outbuf; char *cache_nonce = NULL; char *passwd_nonce = NULL; - int opt_preset; int opt_inq_passwd; size_t n; char *p, *pend; const char *s; time_t opt_timestamp; int c; + unsigned int flags = 0; if (ctrl->restricted) return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); - no_protection = has_option (line, "--no-protection"); - opt_preset = has_option (line, "--preset"); + if (has_option (line, "--no-protection")) + flags |= GENKEY_FLAG_NO_PROTECTION; + if (has_option (line, "--preset")) + flags |= GENKEY_FLAG_PRESET; opt_inq_passwd = has_option (line, "--inq-passwd"); passwd_nonce = option_value (line, "--passwd-nonce"); if (passwd_nonce) @@ -1191,7 +1191,7 @@ cmd_genkey (assuan_context_t ctx, char *line) /* If requested, ask for the password to be used for the key. If this is not used the regular Pinentry mechanism is used. */ - if (opt_inq_passwd && !no_protection) + if (opt_inq_passwd && !(flags & GENKEY_FLAG_NO_PROTECTION)) { /* (N is used as a dummy) */ assuan_begin_confidential (ctx); @@ -1204,16 +1204,17 @@ cmd_genkey (assuan_context_t ctx, char *line) /* Empty password given - switch to no-protection mode. */ xfree (newpasswd); newpasswd = NULL; - no_protection = 1; + flags |= GENKEY_FLAG_NO_PROTECTION; } } else if (passwd_nonce) newpasswd = agent_get_cache (ctrl, passwd_nonce, CACHE_MODE_NONCE); - rc = agent_genkey (ctrl, cache_nonce, opt_timestamp, - (char*)value, valuelen, no_protection, - newpasswd, opt_preset, &outbuf); + + rc = agent_genkey (ctrl, flags, cache_nonce, opt_timestamp, + (char*)value, valuelen, + newpasswd, &outbuf); leave: if (newpasswd) @@ -1317,7 +1318,7 @@ cmd_keyattr (assuan_context_t ctx, char *line) if (!err) err = nvc_set_private_key (keymeta, s_key); if (!err) - err = agent_update_private_key (grip, keymeta); + err = agent_update_private_key (ctrl, grip, keymeta); } nvc_release (keymeta); @@ -1327,6 +1328,8 @@ cmd_keyattr (assuan_context_t ctx, char *line) leave: return leave_cmd (ctx, err); } + + static const char hlp_readkey[] = "READKEY [--no-data] [--format=ssh] \n" @@ -1390,7 +1393,7 @@ cmd_readkey (assuan_context_t ctx, char *line) goto leave; } - if (agent_key_available (grip)) + if (!ctrl->ephemeral_mode && agent_key_available (ctrl, grip)) { /* (Shadow)-key is not available in our key storage. */ char *dispserialno; @@ -1398,7 +1401,7 @@ cmd_readkey (assuan_context_t ctx, char *line) bin2hex (grip, 20, hexgrip); agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, hexgrip); - rc = agent_write_shadow_key (grip, serialno, keyid, pkbuf, 0, + rc = agent_write_shadow_key (ctrl, grip, serialno, keyid, pkbuf, 0, dispserialno); xfree (dispserialno); if (rc) @@ -2934,7 +2937,7 @@ cmd_import_key (assuan_context_t ctx, char *line) } else { - if (!force && !agent_key_available (grip)) + if (!force && !agent_key_available (ctrl, grip)) err = gpg_error (GPG_ERR_EEXIST); else { @@ -2956,11 +2959,11 @@ cmd_import_key (assuan_context_t ctx, char *line) err = agent_protect (key, passphrase, &finalkey, &finalkeylen, ctrl->s2k_count); if (!err) - err = agent_write_private_key (grip, finalkey, finalkeylen, force, + err = agent_write_private_key (ctrl, grip, finalkey, finalkeylen, force, NULL, NULL, NULL, opt_timestamp); } else - err = agent_write_private_key (grip, key, realkeylen, force, + err = agent_write_private_key (ctrl, grip, key, realkeylen, force, NULL, NULL, NULL, opt_timestamp); leave: @@ -2979,7 +2982,8 @@ cmd_import_key (assuan_context_t ctx, char *line) static const char hlp_export_key[] = - "EXPORT_KEY [--cache-nonce=] [--openpgp|--mode1003] \n" + "EXPORT_KEY [--cache-nonce=] \\\n" + " [--openpgp|--mode1003] \n" "\n" "Export a secret key from the key store. The key will be encrypted\n" "using the current session's key wrapping key (cf. command KEYWRAP_KEY)\n" @@ -2987,8 +2991,8 @@ static const char hlp_export_key[] = "prior to using this command. The function takes the keygrip as argument.\n" "\n" "If --openpgp is used, the secret key material will be exported in RFC 4880\n" - "compatible passphrase-protected form. If --mode1003 is use the secret key\n" - "is exported as s-expression as storred locally. Without those options,\n" + "compatible passphrase-protected form. In --mode1003 the secret key\n" + "is exported as s-expression as stored locally. Without those options,\n" "the secret key material will be exported in the clear (after prompting\n" "the user to unlock it, if needed).\n"; static gpg_error_t @@ -3045,7 +3049,7 @@ cmd_export_key (assuan_context_t ctx, char *line) if (err) goto leave; - if (agent_key_available (grip)) + if (agent_key_available (ctrl, grip)) { err = gpg_error (GPG_ERR_NO_SECKEY); goto leave; @@ -3257,9 +3261,9 @@ cmd_keytocard (assuan_context_t ctx, char *line) if (err) goto leave; - if (agent_key_available (grip)) + if (agent_key_available (ctrl, grip)) { - err =gpg_error (GPG_ERR_NO_SECKEY); + err = gpg_error (GPG_ERR_NO_SECKEY); goto leave; } @@ -3577,7 +3581,7 @@ cmd_keytotpm (assuan_context_t ctx, char *line) if (err) goto leave; - if (agent_key_available (grip)) + if (agent_key_available (ctrl, grip)) { err =gpg_error (GPG_ERR_NO_SECKEY); goto leave; @@ -3869,6 +3873,7 @@ static const char hlp_getinfo[] = " getenv NAME - Return value of envvar NAME.\n" " connections - Return number of active connections.\n" " jent_active - Returns OK if Libgcrypt's JENT is active.\n" + " ephemeral - Returns OK if the connection is in ephemeral mode.\n" " restricted - Returns OK if the connection is in restricted mode.\n" " cmd_has_option CMD OPT\n" " - Returns OK if command CMD has option OPT.\n"; @@ -3922,6 +3927,10 @@ cmd_getinfo (assuan_context_t ctx, char *line) snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ()); rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); } + else if (!strcmp (line, "ephemeral")) + { + rc = ctrl->ephemeral_mode? 0 : gpg_error (GPG_ERR_FALSE); + } else if (!strcmp (line, "restricted")) { rc = ctrl->restricted? 0 : gpg_error (GPG_ERR_FALSE); @@ -4078,6 +4087,10 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) ctrl->server_local->allow_fully_canceled = gnupg_compare_version (value, "2.1.0"); } + else if (!strcmp (key, "ephemeral")) + { + ctrl->ephemeral_mode = *value? atoi (value) : 0; + } else if (ctrl->restricted) { err = gpg_error (GPG_ERR_FORBIDDEN); diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 6aad35bff..50755c0fd 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -969,7 +969,7 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp, int dontcare_exist, if (err) goto leave; - if (!dontcare_exist && !from_native && !agent_key_available (grip)) + if (!dontcare_exist && !from_native && !agent_key_available (ctrl, grip)) { err = gpg_error (GPG_ERR_EEXIST); goto leave; @@ -1147,14 +1147,16 @@ convert_from_openpgp_native (ctrl_t ctrl, if (!agent_protect (*r_key, passphrase, &protectedkey, &protectedkeylen, ctrl->s2k_count)) - agent_write_private_key (grip, protectedkey, protectedkeylen, 1, - NULL, NULL, NULL, 0); + agent_write_private_key (ctrl, grip, + protectedkey, + protectedkeylen, + 1, NULL, NULL, NULL, 0); xfree (protectedkey); } else { /* Empty passphrase: write key without protection. */ - agent_write_private_key (grip, + agent_write_private_key (ctrl, grip, *r_key, gcry_sexp_canon_len (*r_key, 0, NULL,NULL), 1, NULL, NULL, NULL, 0); diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index e7c6a8aae..2496d091a 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -57,7 +57,7 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, } len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); - err = agent_write_private_key (grip, shdkey, len, 1 /*force*/, + err = agent_write_private_key (ctrl, grip, shdkey, len, 1 /*force*/, NULL, NULL, NULL, 0); xfree (shdkey); if (err) @@ -70,7 +70,7 @@ agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip, return GPG_ERR_ENOMEM; gcry_sexp_sprint(s_key, GCRYSEXP_FMT_CANON, pkbuf, len); - err1 = agent_write_private_key (grip, pkbuf, len, 1 /*force*/, + err1 = agent_write_private_key (ctrl, grip, pkbuf, len, 1 /*force*/, NULL, NULL, NULL, 0); xfree(pkbuf); if (err1) diff --git a/agent/findkey.c b/agent/findkey.c index 4e55119e3..1f2938ea3 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -40,7 +40,7 @@ #endif -static gpg_error_t read_key_file (const unsigned char *grip, +static gpg_error_t read_key_file (ctrl_t ctrl, const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, char **r_orig_key_value); static gpg_error_t is_shadowed_key (gcry_sexp_t s_skey); @@ -73,6 +73,30 @@ fname_from_keygrip (const unsigned char *grip, int for_new) } +/* Helper until we have a "wipe" mode flag in es_fopen. */ +static void +wipe_and_fclose (estream_t fp) +{ + void *blob; + size_t blob_size; + + if (!fp) + ; + else if (es_fclose_snatch (fp, &blob, &blob_size)) + { + log_error ("error wiping buffer during fclose\n"); + es_fclose (fp); + } + else if (blob) + { + wipememory (blob, blob_size); + gpgrt_free (blob); + } +} + + + + /* Replace all linefeeds in STRING by "%0A" and return a new malloced * string. May return NULL on memory error. */ static char * @@ -110,7 +134,8 @@ linefeed_to_percent0A (const char *string) * TIMESTAMP is not zero and the key does not yet exists it will be * recorded as creation date. */ gpg_error_t -agent_write_private_key (const unsigned char *grip, +agent_write_private_key (ctrl_t ctrl, + const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, const char *dispserialno, @@ -120,7 +145,7 @@ agent_write_private_key (const unsigned char *grip, char *fname = NULL; char *tmpfname = NULL; estream_t fp = NULL; - int newkey; + int newkey = 0; nvc_t pk = NULL; gcry_sexp_t key = NULL; int removetmp = 0; @@ -134,11 +159,13 @@ agent_write_private_key (const unsigned char *grip, const char *s; int force_modify = 0; - fname = fname_from_keygrip (grip, 0); + fname = (ctrl->ephemeral_mode + ? xtrystrdup ("[ephemeral key store]") + : fname_from_keygrip (grip, 0)); if (!fname) return gpg_error_from_syserror (); - err = read_key_file (grip, &key, &pk, &orig_key_value); + err = read_key_file (ctrl, grip, &key, &pk, &orig_key_value); if (err) { if (gpg_err_code (err) == GPG_ERR_ENOENT) @@ -289,43 +316,99 @@ agent_write_private_key (const unsigned char *grip, goto leave; } - /* Create a temporary file for writing. */ - tmpfname = fname_from_keygrip (grip, 1); - fp = tmpfname ? es_fopen (tmpfname, "wbx,mode=-rw") : NULL; - if (!fp) + if (ctrl->ephemeral_mode) { - err = gpg_error_from_syserror (); - log_error ("can't create '%s': %s\n", tmpfname, gpg_strerror (err)); - goto leave; - } + ephemeral_private_key_t ek; + void *blob; + size_t blobsize; - err = nvc_write (pk, fp); - if (!err && es_fflush (fp)) - err = gpg_error_from_syserror (); - if (err) - { - log_error ("error writing '%s': %s\n", tmpfname, gpg_strerror (err)); - removetmp = 1; - goto leave; - } + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN)) + break; + if (!ek) + { + ek = xtrycalloc (1, sizeof *ek); + if (!ek) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (ek->grip, grip, KEYGRIP_LEN); + ek->next = ctrl->ephemeral_keys; + ctrl->ephemeral_keys = ek; + } - if (es_fclose (fp)) - { - err = gpg_error_from_syserror (); - log_error ("error closing '%s': %s\n", tmpfname, gpg_strerror (err)); - removetmp = 1; - goto leave; + fp = es_fopenmem (0, "wb,wipe"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("can't open memory stream: %s\n", gpg_strerror (err)); + goto leave; + } + + err = nvc_write (pk, fp); + if (err) + { + log_error ("error writing to memory stream: %s\n",gpg_strerror (err)); + goto leave; + } + + if (es_fclose_snatch (fp, &blob, &blobsize) || !blob) + { + err = gpg_error_from_syserror (); + log_error ("error getting memory stream buffer: %s\n", + gpg_strerror (err)); + /* Closing right away so that we don't try another snatch in + * the cleanup. */ + es_fclose (fp); + fp = NULL; + goto leave; + } + fp = NULL; + xfree (ek->keybuf); + ek->keybuf = blob; + ek->keybuflen = blobsize; } else - fp = NULL; - - err = gnupg_rename_file (tmpfname, fname, &blocksigs); - if (err) { - err = gpg_error_from_syserror (); - log_error ("error renaming '%s': %s\n", tmpfname, gpg_strerror (err)); - removetmp = 1; - goto leave; + /* Create a temporary file for writing. */ + tmpfname = fname_from_keygrip (grip, 1); + fp = tmpfname ? es_fopen (tmpfname, "wbx,mode=-rw") : NULL; + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("can't create '%s': %s\n", tmpfname, gpg_strerror (err)); + goto leave; + } + + err = nvc_write (pk, fp); + if (!err && es_fflush (fp)) + err = gpg_error_from_syserror (); + if (err) + { + log_error ("error writing '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } + + if (es_fclose (fp)) + { + err = gpg_error_from_syserror (); + log_error ("error closing '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } + else + fp = NULL; + + err = gnupg_rename_file (tmpfname, fname, &blocksigs); + if (err) + { + err = gpg_error_from_syserror (); + log_error ("error renaming '%s': %s\n", tmpfname, gpg_strerror (err)); + removetmp = 1; + goto leave; + } } bump_key_eventcounter (); @@ -333,7 +416,10 @@ agent_write_private_key (const unsigned char *grip, leave: if (blocksigs) gnupg_unblock_all_signals (); - es_fclose (fp); + if (ctrl->ephemeral_mode) + wipe_and_fclose (fp); + else + es_fclose (fp); if (removetmp && tmpfname) gnupg_remove (tmpfname); xfree (orig_key_value); @@ -350,7 +436,7 @@ agent_write_private_key (const unsigned char *grip, gpg_error_t -agent_update_private_key (const unsigned char *grip, nvc_t pk) +agent_update_private_key (ctrl_t ctrl, const unsigned char *grip, nvc_t pk) { gpg_error_t err; char *fname0 = NULL; /* The existing file name. */ @@ -359,6 +445,57 @@ agent_update_private_key (const unsigned char *grip, nvc_t pk) int removetmp = 0; int blocksigs = 0; + if (ctrl->ephemeral_mode) + { + ephemeral_private_key_t ek; + void *blob; + size_t blobsize; + + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN)) + break; + if (!ek) + { + err = gpg_error (GPG_ERR_ENOENT); + goto leave; + } + + fp = es_fopenmem (0, "wbx,wipe"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("can't open memory stream: %s\n", gpg_strerror (err)); + goto leave; + } + + err = nvc_write (pk, fp); + if (err) + { + log_error ("error writing to memory stream: %s\n",gpg_strerror (err)); + goto leave; + } + + if (es_fclose_snatch (fp, &blob, &blobsize) || !blob) + { + err = gpg_error_from_syserror (); + log_error ("error getting memory stream buffer: %s\n", + gpg_strerror (err)); + /* Closing right away so that we don't try another snatch in + * the cleanup. */ + es_fclose (fp); + fp = NULL; + goto leave; + } + fp = NULL; + /* No need to revisit the linked list because the found EK is + * not expected to change due to the other syscalls above. */ + xfree (ek->keybuf); + ek->keybuf = blob; + ek->keybuflen = blobsize; + goto leave; + } + + fname0 = fname_from_keygrip (grip, 0); if (!fname0) { @@ -404,7 +541,10 @@ agent_update_private_key (const unsigned char *grip, nvc_t pk) leave: if (blocksigs) gnupg_unblock_all_signals (); - es_fclose (fp); + if (ctrl->ephemeral_mode) + wipe_and_fclose (fp); + else + es_fclose (fp); if (removetmp && fname) gnupg_remove (fname); xfree (fname); @@ -888,17 +1028,17 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, * caller must free it. On failure returns an error code and stores * NULL at RESULT and R_KEYMETA. */ static gpg_error_t -read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, - char **r_orig_key_value) +read_key_file (ctrl_t ctrl, const unsigned char *grip, + gcry_sexp_t *result, nvc_t *r_keymeta, char **r_orig_key_value) { gpg_error_t err; char *fname; - estream_t fp; - struct stat st; - unsigned char *buf; + estream_t fp = NULL; + unsigned char *buf = NULL; size_t buflen, erroff; - gcry_sexp_t s_skey; + nvc_t pk = NULL; char first; + size_t keybuflen; *result = NULL; if (r_keymeta) @@ -906,19 +1046,42 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, if (r_orig_key_value) *r_orig_key_value = NULL; - fname = fname_from_keygrip (grip, 0); + fname = (ctrl->ephemeral_mode + ? xtrystrdup ("[ephemeral key store]") + : fname_from_keygrip (grip, 0)); if (!fname) { - return gpg_error_from_syserror (); + err = gpg_error_from_syserror (); + goto leave; + } + + if (ctrl->ephemeral_mode) + { + ephemeral_private_key_t ek; + + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN) + && ek->keybuf && ek->keybuflen) + break; + if (!ek || !ek->keybuf || !ek->keybuflen) + { + err = gpg_error (GPG_ERR_ENOENT); + goto leave; + } + keybuflen = ek->keybuflen; + fp = es_fopenmem_init (0, "rb", ek->keybuf, ek->keybuflen); + } + else + { + keybuflen = 0; /* Indicates that this is not ephemeral mode. */ + fp = es_fopen (fname, "rb"); } - fp = es_fopen (fname, "rb"); if (!fp) { err = gpg_error_from_syserror (); if (gpg_err_code (err) != GPG_ERR_ENOENT) log_error ("can't open '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - return err; + goto leave; } if (es_fread (&first, 1, 1, fp) != 1) @@ -926,28 +1089,22 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, err = gpg_error_from_syserror (); log_error ("error reading first byte from '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - return err; + goto leave; } if (es_fseek (fp, 0, SEEK_SET)) { err = gpg_error_from_syserror (); log_error ("error seeking in '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - return err; + goto leave; } if (first != '(') { /* Key is in extended format. */ - nvc_t pk = NULL; int line; err = nvc_parse_private_key (&pk, &line, fp); - es_fclose (fp); if (err) log_error ("error parsing '%s' line %d: %s\n", @@ -969,9 +1126,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, if (!*r_orig_key_value) { err = gpg_error_from_syserror (); - nvc_release (pk); - xfree (fname); - return err; + goto leave; } } } @@ -979,35 +1134,31 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, } } - if (!err && r_keymeta) - *r_keymeta = pk; - else - nvc_release (pk); - xfree (fname); - return err; + goto leave; /* Ready. */ } - if (fstat (es_fileno (fp), &st)) + if (keybuflen) + buflen = keybuflen; + else { - err = gpg_error_from_syserror (); - log_error ("can't stat '%s': %s\n", fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - return err; + struct stat st; + + if (fstat (es_fileno (fp), &st)) + { + err = gpg_error_from_syserror (); + log_error ("can't stat '%s': %s\n", fname, gpg_strerror (err)); + goto leave; + } + buflen = st.st_size; } - buflen = st.st_size; buf = xtrymalloc (buflen+1); if (!buf) { err = gpg_error_from_syserror (); log_error ("error allocating %zu bytes for '%s': %s\n", buflen, fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - xfree (buf); - return err; - + goto leave; } if (es_fread (buf, buflen, 1, fp) != 1) @@ -1015,25 +1166,32 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result, nvc_t *r_keymeta, err = gpg_error_from_syserror (); log_error ("error reading %zu bytes from '%s': %s\n", buflen, fname, gpg_strerror (err)); - xfree (fname); - es_fclose (fp); - xfree (buf); - return err; + goto leave; } /* Convert the file into a gcrypt S-expression object. */ - err = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); - xfree (fname); - es_fclose (fp); - xfree (buf); - if (err) - { + { + gcry_sexp_t s_skey; + + err = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); + if (err) log_error ("failed to build S-Exp (off=%u): %s\n", (unsigned int)erroff, gpg_strerror (err)); - return err; - } - *result = s_skey; - return 0; + else + *result = s_skey; + } + + leave: + if (!err && r_keymeta) + *r_keymeta = pk; + else + nvc_release (pk); + if (ctrl->ephemeral_mode) + wipe_and_fclose (fp); + else + es_fclose (fp); + xfree (fname); + return err; } @@ -1226,7 +1384,8 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, if (!grip && !ctrl->have_keygrip) return gpg_error (GPG_ERR_NO_SECKEY); - err = read_key_file (grip? grip : ctrl->keygrip, &s_skey, &keymeta, NULL); + err = read_key_file (ctrl, grip? grip : ctrl->keygrip, + &s_skey, &keymeta, NULL); if (err) { if (gpg_err_code (err) == GPG_ERR_ENOENT) @@ -1485,7 +1644,7 @@ agent_raw_key_from_file (ctrl_t ctrl, const unsigned char *grip, *result = NULL; - err = read_key_file (grip, &s_skey, r_keymeta, NULL); + err = read_key_file (ctrl, grip, &s_skey, r_keymeta, NULL); if (!err) *result = s_skey; return err; @@ -1528,7 +1687,7 @@ public_key_from_file (ctrl_t ctrl, const unsigned char *grip, if (r_sshorder) *r_sshorder = 0; - err = read_key_file (grip, &s_skey, for_ssh? &keymeta : NULL, NULL); + err = read_key_file (ctrl, grip, &s_skey, for_ssh? &keymeta : NULL, NULL); if (err) return err; @@ -1656,13 +1815,23 @@ agent_ssh_key_from_file (ctrl_t ctrl, /* Check whether the secret key identified by GRIP is available. - Returns 0 is the key is available. */ + Returns 0 is the key is available. */ int -agent_key_available (const unsigned char *grip) +agent_key_available (ctrl_t ctrl, const unsigned char *grip) { int result; char *fname; char hexgrip[40+4+1]; + ephemeral_private_key_t ek; + + if (ctrl && ctrl->ephemeral_mode) + { + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN) + && ek->keybuf && ek->keybuflen) + return 0; + return -1; + } bin2hex (grip, 20, hexgrip); strcpy (hexgrip+40, ".key"); @@ -1675,7 +1844,6 @@ agent_key_available (const unsigned char *grip) } - /* Return the information about the secret key specified by the binary keygrip GRIP. If the key is a shadowed one the shadow information will be stored at the address R_SHADOW_INFO as an allocated @@ -1700,7 +1868,7 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, { gcry_sexp_t sexp; - err = read_key_file (grip, &sexp, NULL, NULL); + err = read_key_file (ctrl, grip, &sexp, NULL, NULL); if (err) { if (gpg_err_code (err) == GPG_ERR_ENOENT) @@ -1784,7 +1952,13 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text, char *default_desc = NULL; int key_type; - err = read_key_file (grip, &s_skey, NULL, NULL); + if (ctrl->ephemeral_mode) + { + err = gpg_error (GPG_ERR_NO_SECKEY); + goto leave; + } + + err = read_key_file (ctrl, grip, &s_skey, NULL, NULL); if (gpg_err_code (err) == GPG_ERR_ENOENT) err = gpg_error (GPG_ERR_NO_SECKEY); if (err) @@ -1885,7 +2059,7 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text, card's SERIALNO and the IDSTRING. With FORCE passed as true an existing key with the given GRIP will get overwritten. */ gpg_error_t -agent_write_shadow_key (const unsigned char *grip, +agent_write_shadow_key (ctrl_t ctrl, const unsigned char *grip, const char *serialno, const char *keyid, const unsigned char *pkbuf, int force, const char *dispserialno) @@ -1915,7 +2089,7 @@ agent_write_shadow_key (const unsigned char *grip, } len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL); - err = agent_write_private_key (grip, shdkey, len, force, + err = agent_write_private_key (ctrl, grip, shdkey, len, force, serialno, keyid, dispserialno, 0); xfree (shdkey); if (err) diff --git a/agent/genkey.c b/agent/genkey.c index 741c05f4f..444f89f79 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -30,14 +30,36 @@ #include "../common/exechelp.h" #include "../common/sysutils.h" -static int -store_key (gcry_sexp_t private, const char *passphrase, int force, + +void +clear_ephemeral_keys (ctrl_t ctrl) +{ + while (ctrl->ephemeral_keys) + { + ephemeral_private_key_t next = ctrl->ephemeral_keys->next; + if (ctrl->ephemeral_keys->keybuf) + { + wipememory (ctrl->ephemeral_keys->keybuf, + ctrl->ephemeral_keys->keybuflen); + xfree (ctrl->ephemeral_keys->keybuf); + } + xfree (ctrl->ephemeral_keys); + ctrl->ephemeral_keys = next; + } +} + + +/* Store the key either to a file, or in ctrl->ephemeral_mode in the + * session data. */ +static gpg_error_t +store_key (ctrl_t ctrl, gcry_sexp_t private, + const char *passphrase, int force, unsigned long s2k_count, time_t timestamp) { - int rc; + gpg_error_t err; unsigned char *buf; size_t len; - unsigned char grip[20]; + unsigned char grip[KEYGRIP_LEN]; if ( !gcry_pk_get_keygrip (private, grip) ) { @@ -49,7 +71,10 @@ store_key (gcry_sexp_t private, const char *passphrase, int force, log_assert (len); buf = gcry_malloc_secure (len); if (!buf) - return out_of_core (); + { + err = gpg_error_from_syserror (); + goto leave; + } len = gcry_sexp_sprint (private, GCRYSEXP_FMT_CANON, buf, len); log_assert (len); @@ -57,20 +82,56 @@ store_key (gcry_sexp_t private, const char *passphrase, int force, { unsigned char *p; - rc = agent_protect (buf, passphrase, &p, &len, s2k_count); - if (rc) - { - xfree (buf); - return rc; - } + err = agent_protect (buf, passphrase, &p, &len, s2k_count); + if (err) + goto leave; xfree (buf); buf = p; } - rc = agent_write_private_key (grip, buf, len, force, - NULL, NULL, NULL, timestamp); + if (ctrl->ephemeral_mode) + { + ephemeral_private_key_t ek; + + for (ek = ctrl->ephemeral_keys; ek; ek = ek->next) + if (!memcmp (ek->grip, grip, KEYGRIP_LEN)) + break; + if (!ek) + { + ek = xtrycalloc (1, sizeof *ek); + if (!ek) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (ek->grip, grip, KEYGRIP_LEN); + ek->next = ctrl->ephemeral_keys; + ctrl->ephemeral_keys = ek; + } + if (ek->keybuf) + { + wipememory (ek->keybuf, ek->keybuflen); + xfree (ek->keybuf); + } + ek->keybuf = buf; + buf = NULL; + ek->keybuflen = len; + } + else + err = agent_write_private_key (ctrl, grip, buf, len, force, + NULL, NULL, NULL, timestamp); + + if (!err) + { + char hexgrip[2*KEYGRIP_LEN+1]; + + bin2hex (grip, KEYGRIP_LEN, hexgrip); + agent_write_status (ctrl, "KEYGRIP", hexgrip, NULL); + } + + leave: xfree (buf); - return rc; + return err; } @@ -450,16 +511,19 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt, /* Generate a new keypair according to the parameters given in - KEYPARAM. If CACHE_NONCE is given first try to lookup a passphrase - using the cache nonce. If NO_PROTECTION is true the key will not - be protected by a passphrase. If OVERRIDE_PASSPHRASE is true that - passphrase will be used for the new key. If TIMESTAMP is not zero - it will be recorded as creation date of the key (unless extended - format is disabled) . */ + * KEYPARAM. If CACHE_NONCE is given first try to lookup a passphrase + * using the cache nonce. If NO_PROTECTION is true the key will not + * be protected by a passphrase. If OVERRIDE_PASSPHRASE is true that + * passphrase will be used for the new key. If TIMESTAMP is not zero + * it will be recorded as creation date of the key (unless extended + * format is disabled). In ctrl_ephemeral_mode the key is stored in + * the session data and an identifier is returned using a status + * line. */ int -agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, - const char *keyparam, size_t keyparamlen, int no_protection, - const char *override_passphrase, int preset, membuf_t *outbuf) +agent_genkey (ctrl_t ctrl, unsigned int flags, + const char *cache_nonce, time_t timestamp, + const char *keyparam, size_t keyparamlen, + const char *override_passphrase, membuf_t *outbuf) { gcry_sexp_t s_keyparam, s_key, s_private, s_public; char *passphrase_buffer = NULL; @@ -478,7 +542,7 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, /* Get the passphrase now, cause key generation may take a while. */ if (override_passphrase) passphrase = override_passphrase; - else if (no_protection || !cache_nonce) + else if ((flags & GENKEY_FLAG_NO_PROTECTION) || !cache_nonce) passphrase = NULL; else { @@ -486,8 +550,8 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, passphrase = passphrase_buffer; } - if (passphrase || no_protection) - ; + if (passphrase || (flags & GENKEY_FLAG_NO_PROTECTION)) + ; /* No need to ask for a passphrase. */ else { rc = agent_ask_new_passphrase (ctrl, @@ -532,11 +596,14 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, gcry_sexp_release (s_key); s_key = NULL; /* store the secret key */ - if (DBG_CRYPTO) - log_debug ("storing private key\n"); - rc = store_key (s_private, passphrase, 0, ctrl->s2k_count, timestamp); - if (!rc) + if (opt.verbose) + log_info ("storing %sprivate key\n", + ctrl->ephemeral_mode?"ephemeral ":""); + rc = store_key (ctrl, s_private, passphrase, 0, ctrl->s2k_count, timestamp); + if (!rc && !ctrl->ephemeral_mode) { + /* FIXME: or does it make sense to also cache passphrases in + * ephemeral mode using a dedicated cache? */ if (!cache_nonce) { char tmpbuf[12]; @@ -544,21 +611,23 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp, cache_nonce = bin2hex (tmpbuf, 12, NULL); } if (cache_nonce - && !no_protection + && !(flags & GENKEY_FLAG_NO_PROTECTION) && !agent_put_cache (ctrl, cache_nonce, CACHE_MODE_NONCE, passphrase, ctrl->cache_ttl_opt_preset)) agent_write_status (ctrl, "CACHE_NONCE", cache_nonce, NULL); - if (preset && !no_protection) - { - unsigned char grip[20]; - char hexgrip[40+1]; - if (gcry_pk_get_keygrip (s_private, grip)) - { - bin2hex(grip, 20, hexgrip); - rc = agent_put_cache (ctrl, hexgrip, CACHE_MODE_ANY, passphrase, + if ((flags & GENKEY_FLAG_PRESET) + && !(flags & GENKEY_FLAG_NO_PROTECTION)) + { + unsigned char grip[20]; + char hexgrip[40+1]; + if (gcry_pk_get_keygrip (s_private, grip)) + { + bin2hex(grip, 20, hexgrip); + rc = agent_put_cache (ctrl, hexgrip, + CACHE_MODE_ANY, passphrase, ctrl->cache_ttl_opt_preset); - } - } + } + } } xfree (passphrase_buffer); passphrase_buffer = NULL; @@ -607,7 +676,8 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey, if (passphrase_addr && *passphrase_addr) { /* Take an empty string as request not to protect the key. */ - err = store_key (s_skey, **passphrase_addr? *passphrase_addr:NULL, 1, + err = store_key (ctrl, s_skey, + **passphrase_addr? *passphrase_addr:NULL, 1, ctrl->s2k_count, 0); } else @@ -623,7 +693,7 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey, L_("Please enter the new passphrase"), &pass); if (!err) - err = store_key (s_skey, pass, 1, ctrl->s2k_count, 0); + err = store_key (ctrl, s_skey, pass, 1, ctrl->s2k_count, 0); if (!err && passphrase_addr) *passphrase_addr = pass; else diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index b0150031d..a5448ac38 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1989,6 +1989,7 @@ agent_deinit_default_ctrl (ctrl_t ctrl) { unregister_progress_cb (); session_env_release (ctrl->session_env); + clear_ephemeral_keys (ctrl); xfree (ctrl->digest.data); ctrl->digest.data = NULL; diff --git a/agent/learncard.c b/agent/learncard.c index 8d80b809d..83945b8be 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -397,7 +397,7 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force) for (p=item->hexgrip, i=0; i < 20; p += 2, i++) grip[i] = xtoi_2 (p); - if (!force && !agent_key_available (grip)) + if (!force && !agent_key_available (ctrl, grip)) continue; /* The key is already available. */ /* Unknown key - store it. */ @@ -408,15 +408,17 @@ agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force) goto leave; } - { - char *dispserialno; + if (!ctrl->ephemeral_mode) + { + char *dispserialno; - agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, - item->hexgrip); - rc = agent_write_shadow_key (grip, serialno, item->id, pubkey, force, - dispserialno); - xfree (dispserialno); - } + agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, + item->hexgrip); + rc = agent_write_shadow_key (ctrl, + grip, serialno, item->id, pubkey, force, + dispserialno); + xfree (dispserialno); + } xfree (pubkey); if (rc) goto leave; diff --git a/agent/pksign.c b/agent/pksign.c index a7b5c579f..322918969 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -371,13 +371,14 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce, goto leave; } - if (keyref) + if (keyref && !ctrl->ephemeral_mode) { char *dispserialno; agent_card_getattr (ctrl, "$DISPSERIALNO", &dispserialno, hexgrip); - agent_write_shadow_key (ctrl->keygrip, serialno, keyref, pkbuf, + agent_write_shadow_key (ctrl, + ctrl->keygrip, serialno, keyref, pkbuf, 0, dispserialno); xfree (dispserialno); } diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 17f6fd559..c6450a20e 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -755,8 +755,9 @@ release_passphrase (char *pw) /* Stub function. */ int -agent_key_available (const unsigned char *grip) +agent_key_available (ctrl_t ctrl, const unsigned char *grip) { + (void)ctrl; (void)grip; return -1; /* Not available. */ } @@ -814,7 +815,7 @@ agent_askpin (ctrl_t ctrl, /* Replacement for the function in findkey.c. Here we write the key * to stdout. */ gpg_error_t -agent_write_private_key (const unsigned char *grip, +agent_write_private_key (ctrl_t ctrl, const unsigned char *grip, const void *buffer, size_t length, int force, const char *serialno, const char *keyref, const char *dispserialno, time_t timestamp) @@ -822,6 +823,7 @@ agent_write_private_key (const unsigned char *grip, char hexgrip[40+4+1]; char *p; + (void)ctrl; (void)force; (void)serialno; (void)keyref; From ead2982286f8ae94e96c0da09c6ed8c294711a47 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Jan 2024 16:52:22 +0100 Subject: [PATCH 327/869] gpg: Use ephemeral mode for generating card keys. * g10/call-agent.c (agent_set_ephemeral_mode): New. * g10/keyedit.c (keyedit_menu) : Switch to ephemeral mode. * g10/keygen.c (do_generate_keypair): Switch to ephemeral mode for card keys with backup. -- GnuPG-bug-id: 6944 --- g10/call-agent.c | 39 +++++++++++++++++++++++++++++++++++++++ g10/call-agent.h | 4 ++++ g10/keyedit.c | 32 ++++++++++++++++++++++---------- g10/keygen.c | 48 +++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 104 insertions(+), 19 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index 744c0fcb8..daf12fae7 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -3243,6 +3243,45 @@ agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc, int verify, } +/* Enable or disable the ephemeral mode. In ephemeral mode keys are + * created,searched and used in a per-session key store and not in the + * on-disk file. Set ENABLE to 1 to enable this mode, to 0 to disable + * this mode and to -1 to only query the current mode. If R_PREVIOUS + * is given the previously used state of the ephemeral mode is stored + * at that address. */ +gpg_error_t +agent_set_ephemeral_mode (ctrl_t ctrl, int enable, int *r_previous) +{ + gpg_error_t err; + + err = start_agent (ctrl, 0); + if (err) + goto leave; + + if (r_previous) + { + err = assuan_transact (agent_ctx, "GETINFO ephemeral", + NULL, NULL, NULL, NULL, NULL, NULL); + if (!err) + *r_previous = 1; + else if (gpg_err_code (err) == GPG_ERR_FALSE) + *r_previous = 0; + else + goto leave; + } + + /* Skip setting if we are only querying or if the mode is already set. */ + if (enable == -1 || (r_previous && !!*r_previous == !!enable)) + err = 0; + else + err = assuan_transact (agent_ctx, + enable? "OPTION ephemeral=1" : "OPTION ephemeral=0", + NULL, NULL, NULL, NULL, NULL, NULL); + leave: + return err; +} + + /* Return the version reported by gpg-agent. */ gpg_error_t agent_get_version (ctrl_t ctrl, char **r_version) diff --git a/g10/call-agent.h b/g10/call-agent.h index 45af95422..1e72dc03f 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -247,6 +247,10 @@ gpg_error_t agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, gpg_error_t agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc, int verify, char **cache_nonce_addr, char **passwd_nonce_addr); + +/* Set or get the ephemeral mode. */ +gpg_error_t agent_set_ephemeral_mode (ctrl_t ctrl, int enable, int *r_previous); + /* Get the version reported by gpg-agent. */ gpg_error_t agent_get_version (ctrl_t ctrl, char **r_version); diff --git a/g10/keyedit.c b/g10/keyedit.c index a12546f71..cae0f7841 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1905,6 +1905,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, PACKET *pkt; IOBUF a; struct parse_packet_ctx_s parsectx; + int lastmode; if (!*arg_string) { @@ -1959,17 +1960,28 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, xfree (fname); node = new_kbnode (pkt); - /* Transfer it to gpg-agent which handles secret keys. */ - err = transfer_secret_keys (ctrl, NULL, node, 1, 1, 0); - - /* Treat the pkt as a public key. */ - pkt->pkttype = PKT_PUBLIC_KEY; - - /* Ask gpg-agent to store the secret key to card. */ - if (card_store_subkey (node, 0, NULL)) + err = agent_set_ephemeral_mode (ctrl, 1, &lastmode); + if (err) + log_error ("error switching to ephemeral mode: %s\n", + gpg_strerror (err)); + else { - redisplay = 1; - sec_shadowing = 1; + /* Transfer it to gpg-agent which handles secret keys. */ + err = transfer_secret_keys (ctrl, NULL, node, 1, 1, 0); + if (!err) + { + /* Treat the pkt as a public key. */ + pkt->pkttype = PKT_PUBLIC_KEY; + + /* Ask gpg-agent to store the secret key to card. */ + if (card_store_subkey (node, 0, NULL)) + { + redisplay = 1; + sec_shadowing = 1; + } + } + if (!lastmode && agent_set_ephemeral_mode (ctrl, 0, NULL)) + log_error ("error clearing the ephemeral mode\n"); } release_kbnode (node); } diff --git a/g10/keygen.c b/g10/keygen.c index 886c3b007..b263a47de 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -5754,7 +5754,6 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, if (!err && get_parameter (para, pSUBKEYTYPE)) { - const char *cardbackupkey = NULL; int subkey_algo = get_parameter_algo (ctrl, para, pSUBKEYTYPE, NULL); key_from_hexgrip = get_parameter_value (para, pSUBKEYGRIP); @@ -5769,22 +5768,57 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, &keygen_flags); - else if (!card - || (cardbackupkey = get_parameter_value (para, pCARDBACKUPKEY))) + else if (get_parameter_value (para, pCARDBACKUPKEY)) { + int lastmode; unsigned int mykeygenflags = KEYGEN_FLAG_NO_PROTECTION; + err = agent_set_ephemeral_mode (ctrl, 1, &lastmode); + if (err) + log_error ("error switching to ephemeral mode: %s\n", + gpg_strerror (err)); + else + { + err = do_create (subkey_algo, + get_parameter_uint (para, pSUBKEYLENGTH), + get_parameter_value (para, pSUBKEYCURVE), + pub_root, + subkeytimestamp, + get_parameter_u32 (para, pSUBKEYEXPIRE), 1, + &mykeygenflags, + get_parameter_passphrase (para), + &cache_nonce, NULL, + NULL, NULL); + /* Get the pointer to the generated public subkey packet. */ + if (!err) + { + kbnode_t node; + + for (node = pub_root; node; node = node->next) + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + sub_psk = node->pkt->pkt.public_key; + log_assert (sub_psk); + err = card_store_key_with_backup (ctrl, + sub_psk, gnupg_homedir ()); + } + + /* Reset the ephemeral mode as needed. */ + if (!lastmode && agent_set_ephemeral_mode (ctrl, 0, NULL)) + log_error ("error clearing the ephemeral mode\n"); + } + } + else if (!card) + { err = do_create (subkey_algo, get_parameter_uint (para, pSUBKEYLENGTH), get_parameter_value (para, pSUBKEYCURVE), pub_root, subkeytimestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, - cardbackupkey? &mykeygenflags : &keygen_flags, + &keygen_flags, get_parameter_passphrase (para), &cache_nonce, NULL, NULL, NULL); - /* Get the pointer to the generated public subkey packet. */ if (!err) { kbnode_t node; @@ -5793,10 +5827,6 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) sub_psk = node->pkt->pkt.public_key; log_assert (sub_psk); - - if (cardbackupkey) - err = card_store_key_with_backup (ctrl, - sub_psk, gnupg_homedir ()); } } else From 9408c6bf51722a4b268f8fa9152998fd73695bcc Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 23 Jan 2024 15:36:26 +0900 Subject: [PATCH 328/869] sm: Fix ECDH encryption with dhSinglePass-stdDH-sha384kdf-scheme. * sm/encrypt.c (ecdh_encrypt): Cipher is AES192 for id-aes192-wrap. -- Signed-off-by: NIIBE Yutaka --- sm/encrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sm/encrypt.c b/sm/encrypt.c index 3c43edf61..741fe6206 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -260,7 +260,7 @@ ecdh_encrypt (DEK dek, gcry_sexp_t s_pkey, gcry_sexp_t *r_encval) encr_algo_str = "1.3.132.1.11.2"; wrap_algo_str = "2.16.840.1.101.3.4.1.25"; hash_algo = GCRY_MD_SHA384; - cipher_algo = GCRY_CIPHER_AES256; + cipher_algo = GCRY_CIPHER_AES192; keylen = 24; } else From b7c15948610b8c0a94f978860ba8123082f5836e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Jan 2024 09:04:10 +0100 Subject: [PATCH 329/869] speedo: Minor fix to the install target -- --- README | 4 ++-- build-aux/speedo.mk | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README b/README index 13205c275..b979234ce 100644 --- a/README +++ b/README @@ -93,9 +93,9 @@ libraries can be installed into an arbitrary location using for example: - make -f build-aux/speedo.mk install SYSROOT=/usr/local/gnupg-foo + make -f build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24 - and adding the directory to PATH. + and adding /usr/local/gnupg24/bin to PATH. ** Specific build problems on some machines: diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index be400c37a..335594b51 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -1125,13 +1125,13 @@ ifneq ($(TARGETOS),w32) fi; \ done; \ done; \ - echo "sysconfdir = /etc" >bin/gpgconf.ctl ;\ + echo "sysconfdir = /etc/gnupg" >bin/gpgconf.ctl ;\ echo "rootdir = $(idir)" >>bin/gpgconf.ctl ;\ echo "speedo: /*" ;\ echo "speedo: * Now copy $(idir)/ to the final location and" ;\ echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly" ;\ echo "speedo: * Or run:" ;\ - echo "speedo: * make -f build-aux/speedo.mk install SYSROOT=/somewhere" ;\ + echo "speedo: * make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24" ;\ echo "speedo: */") endif @@ -1146,7 +1146,7 @@ ifneq ($(TARGETOS),w32) echo "speedo: ERROR: SYSROOT has not been given";\ echo "speedo: Set SYSROOT to the desired install directory";\ echo "speedo: Example:";\ - echo "speedo: make -f build-aux/speedo.mk install SYSROOT=/usr/local";\ + echo "speedo: make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24";\ exit 1;\ fi;\ if [ ! -d "$$SYSROOT"/bin ]; then if ! mkdir "$$SYSROOT"/bin; then \ @@ -1170,8 +1170,8 @@ ifneq ($(TARGETOS),w32) -exec install -Dm 755 "{}" "$$SYSROOT/{}" \; ;\ find . -type f \! -executable \ -exec install -Dm 644 "{}" "$$SYSROOT/{}" \; ;\ - echo "sysconfdir = /etc" > "$$SYSROOT"/bin/gpgconf.ctl ;\ - echo "rootdir = $$SYSROOT" >> "$$SYSROOT"/bin/gpgconf.ctl ;\ + echo "sysconfdir = /etc/gnupg" > "$$SYSROOT"/bin/gpgconf.ctl ;\ + echo "rootdir = $$SYSROOT" >> "$$SYSROOT"/bin/gpgconf.ctl ;\ echo '/*' ;\ echo " * Installation to $$SYSROOT done" ;\ echo ' */' ) From 34d19d448dd3720bb0cdb3333e5b26d89309792d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Jan 2024 13:55:43 +0100 Subject: [PATCH 330/869] tests: Add two more sample p12 files -- GnuPG-bug-id: 6940 --- tests/cms/Makefile.am | 2 ++ tests/cms/samplekeys/Description-p12 | 12 ++++++++++++ .../credential_private_encrypted_3DES.p12 | Bin 0 -> 4220 bytes .../credential_private_encrypted_AES256.p12 | Bin 0 -> 4370 bytes 4 files changed, 14 insertions(+) create mode 100644 tests/cms/samplekeys/credential_private_encrypted_3DES.p12 create mode 100644 tests/cms/samplekeys/credential_private_encrypted_AES256.p12 diff --git a/tests/cms/Makefile.am b/tests/cms/Makefile.am index 557729770..f6a9c6099 100644 --- a/tests/cms/Makefile.am +++ b/tests/cms/Makefile.am @@ -102,6 +102,8 @@ EXTRA_DIST = $(XTESTS) $(KEYS) $(CERTS) $(TEST_FILES) \ samplekeys/t6752-ov-user-ff.p12 \ samplekeys/edward.tester@demo.gnupg.com.p12 \ samplekeys/nistp256-openssl-self-signed.p12 \ + samplekeys/credential_private_encrypted_AES256.p12 \ + samplekeys/credential_private_encrypted_3DES.p12 \ samplemsgs/pwri-sample.cbc.p7m \ samplemsgs/pwri-sample.cbc-2.p7m \ samplemsgs/pwri-sample.gcm.p7m \ diff --git a/tests/cms/samplekeys/Description-p12 b/tests/cms/samplekeys/Description-p12 index 01276087f..7d80caa1e 100644 --- a/tests/cms/samplekeys/Description-p12 +++ b/tests/cms/samplekeys/Description-p12 @@ -51,4 +51,16 @@ Pass: start Cert: 4753a910e0c8b4caa8663ca0e4273a884eb5397d Key: 93be89edd11214ab74280d988a665b6beef876c5 +Name: credential_private_encrypted_AES256.p12 +Desc: AES256 encrypted P12 file from T6940 +Pass: qeFGds84/Sf0eKkJwcp6 +Cert: 20f65740b4a15bac6d6a299026756088f7604937,cbb4b26f93cfd9715ac9fa43440470df9395571b +Key: 37eedaaf317edb69029eed79f69dd479fb10bf08 + +Name: credential_private_encrypted_3DES.p12 +Desc: 3DES encrypted P12 file from T6940 +Pass: qeFGds84/Sf0eKkJwcp6 +Cert: 20f65740b4a15bac6d6a299026756088f7604937,cbb4b26f93cfd9715ac9fa43440470df9395571b +Key: 37eedaaf317edb69029eed79f69dd479fb10bf08 + # eof # diff --git a/tests/cms/samplekeys/credential_private_encrypted_3DES.p12 b/tests/cms/samplekeys/credential_private_encrypted_3DES.p12 new file mode 100644 index 0000000000000000000000000000000000000000..58e80467d368a991ee1142efc904b12ea8e91af8 GIT binary patch literal 4220 zcmZWrbx;%zw_RYDT$YwvO1hVB0i{D&B&4K7knRwvB_$;Vqy?l)LIeaP7F@ywq#IE> zM0Q~%K7KRbd%rjH=FXWrbIzUf=eY-lpbWytBY+_&?-7y+#A?N2$?=HriV>8eKm?`W zEzJuQQwqj=@SA1b`iDklS8&Uxb8n|5YsjIC?eS$iqKv4S!OdUI zj&qvE1tj$S;r<<26UF>_dTJ^0z^pZUZiN~@Uk$r#p*UAA+9yj6`#X!l62*2#`BnY;Da)TE3( z+S8itpyE&XQ-u3$4t4L%N3S|Elx+`C>RT7?Yio*{G?&d-E!_DlT(N+G@tfL^H35gL z0%Pdj!tNIX5Z_$B=i=l%F>->i<;IMNz`hu^QvI-@JO9uAH< zaoAs(;wAamX?wD?^&1997{h5u`)cV zO|#?F6~bRZY9}vwqwU?kydi;%$Y%~durbQ|6kDV6wMAp^1L6*_f3@q1#A9aTu7*m9 zLxE>)5?e_;3wn-EFId3eJ2MOjXz{F0CZT350<#{s7F{`-!%yRWm-GoYnGwAy$j ziq(ICDr~FPAP0R&(*#LZ-tdDf-^)~S6q`qR436m0vJXBZLjv?KZEVsFJ;FFy@Na?} z_^GC}7Y_^?ubwy492u$k@k)^GER%ZdD!6H>ToV!;y~sZ-h%o{P^B;UU*Xq!m>51{t z=y)*Hl1d5YtTH4WI)`B_`_RP#2$@a&s;{ZC+k?*7uzYppjsTPh)VH(3#eaSfCxs-j zlPv^4u)5jGn&;KvI$#W6I+FWv*zne)KMUsOqWPKqXxirCIBG{sVZW>A3 z&d}Q?FR^zbiflfms7$cTL5NJBn`qY+D$}J3U-SuGfB&RXAe~44jPQAf=l0yiNSH~v z$Vx`+c7xHxmi^TL^|!or7E2;^$PK>tsE2rB)UM`0dPdbq0Q?8urbTr|^%DEWQ`i}( z+4Kc?InjLM%lt&K-AhB6u;_$Ri|d!lSLrQ0H(vuv)zDloEcz;4H#ofO0vIe&U9y6- zzB2dq-f$-a<)J9&ye1QvXP8foQYTHf(uFAnR`t`llYnGCC0ki%)8Io}--PdFPk&2K zOtsc`{n1}dizc&)$q)CoK18!e1J7h1?GiwypR%!0dqy7Q1~ZOQP4&=jZhK6aXRODt z(LITJ7UUAXY!x$5#YQdp2!Cg!mmVw0AEtB!$5?KGGDNn4zpe%TxUIQo8shM&cPL;h z1{1jJw;>Vz)hi`xW8YKKeP2O#^4ZlBctU~Bzr7}ajRp-Kp~1Zmr`}VHtG%WAsvy}; z(*uPhTUh5NQ_JA8>X$x_-|J&l*VP$|n?5`*?60VwiV5;$ES3Ou`+d`B@E%Tj~8UcTk6v8?99%p>!trq zjKbZ|G}PPMZFdODSh#WnuZ0T-4TcpwPqu2C0cq5N&L`Eu+sNR>Y^>7$gpPf1=3+8Y z*B)hRm}_o9tMp@U!uOMFuKU#P9p5?qlNz?J*+ImC0e*YJWfv7U=eoXYWCRJL$-d>B#Ri4@XexM?C-RW!%V zpuw|x>;g*bN!sva5t{B>evD_ZpjQX+Xb^GXm28Wz=nvNh$2GeOL}leK^)EQre#nlS zn{tUCv#s9gbNQ+kL1on(Wle{C#Bql4EF-xZwr?X-?KO)41DCnb9`^2?RO{q?R00}n zIy;JG?~hH@-Xf#r({!C=)Wy?09l@{PLi39;fX8nfFd>~6oZ09GqOVK+m0`Q0Geu=D zv>6X9_@<W*sH_#@w^{{D7g z0&NUY?99&~(Sy8!fWdc3J{A}ssFiI+mA2{;o6h9?Y42`Jp*{^JW>bEAMYVY$94ozU z22w%0oDzpTU>8s|HS`L-V=ltKI%|Zp9`^F(@>ximB3DridE8Eomm%`h_{eRv+wwWz z;hK-Nf9ZmGKzLr^n`8&a=nX$PjdpBOV0Bzyb;C*_cMJV*LdUj!)w-SFA0_2lJf@2b zYT|NUT_$$?7_d*^bw3B3Z9F0pK?AC3?pRgI`5-4C`(;XFnxKUl^0EE zGs#Cx!0Ka|S~Txll`?cwZm(f0+2)0EM}?Z=@=qI6m~c^ambz?h$-+sb5_F^Q6fcCa zXX8UMc_*gFX|4B{8vo2ZD|<37BBLnc$AEqY)}o`!n@AtPVDBBti$zyq?~f{?TBclB zpWy3^&;kRE0~r|01nN)6Kb*zY4hhM2H_9>GL!9w*mE7mF4D%srBUcOY{g4oPwwX8V zi3t^1N$kAdPqeOIp>57Xg}%;+!B}9Wfj$;VF2YBUw%h>u_kVC1kYi1z{zmpoDsY9~ z<=s?YUnfjfzL1uErEfwy&V`i!b$@oj5$ll${l;D%8MZ#fz+Hm9bzPH>P6X1{-?n^h zt9zUa(oYVfLWrUG^h1ZnnFINQI={EmtqUOc_x`JDn&G{Z!!|Q@vCEkkrRSSKRZi`T2-X*~?p4SP@ zo?*~-G30OdVjXwp+kMM!n^$ zR`o8ks-f>dFAM?l`ai|A7y+^aB0$!+wD~Pe2+97Zrjp{}7bAd&Fa&V-|F_o@)xvU7 zxNqt|?G=as4ilFUW7{*+e{j@VoM7Rq7R{@dZdxIw^p`{mbstMk?njIsAfn@4blIlo zAL0Bg=5=itHZ&JE`KB4Kj>yGCSIfWr{ZMD~E;moPy+_#hhrLNxVo^{kcDXmWFZp5* zl)fL6Zmx(eOE-su@zg`&(s7ynM|!t;djqV;l-8K+z4=AzVEC}OYE{v4c2T0-L#Ij1 zh&M_ZavT>%m6o>CErVY}QM;=6NQyWU`l+OM^o3HW?EH{)*vyjTDaq&Ch(FJ6hrJ$> zv9o?v;V$Y|0bHCP?(s+bC>+}FY}G}*nB4|edXs@;`C?4ZsGM5Z%<62DZ1yw+OGSz9 zOS;z)^e9~kvORlh@Vq}oQxVc7)8Z#9ivsO25_4D^m1MXzy;~M=FCCwAzWvfwoF7=e z_q~xac#;i*rM7EKz1`c*R9ih;i@9EFA;w;&AOhmt$i5 z>&kx1l^Yg_{l!0WGl>nb4mu;)4q?@0TD=4C??0aH*eh^E$|o2+bh@I+K22V$$O!E|3K3_j5mA3RlB*{4Ucpw?5VXiM9 zG?O#Xv)8z9*~c@&PLFbYIark7R%|uAzc3M`F%FxrPQ%%>Ue4CLvt_-``}C&Iy;*bq z-d}M?#uJ`sM(~GiV;HOa1sikLqw6auI_{VK@zoCtdn|PLO_Cx5pZC2agEgBp6QY+h zV&~y=Swh88Q$?R2qV!Lb9N~qXHXmI=gK<%2>Ix;}Op5?P&tszx>Z2Ojd@Xray0Z4e z-CB!23XU`?22p%%y>YbdT$myb{iNFS$*K7@89%K}!9CHa7Hrs#%{jJ#Wi^$c)NZIA z;XD{DTGQC%mWXFKgO2ERd5cI9<sBpo8OIP&ZZzPL>eU@{rpmREEe9??nH%4pQsCeBqaF)Jr|=*$Ps6V`lG-qnq@t?B$V9(z++A6e4YN zUlj%W9?b;tR)4uHPDwAoa3=spa}Z0(y4=q5-O|PO^SRd&p}xiy>K>C>amA&NC%^oy z)(j0>i}SFQU`dwx7MtAyvXzf{?C{ZWNcGgQWAU*_!l8C;=(rT?Q9Fl&zP6QF$p@bS zHmxYhRDL?_NsYTtxftFBOg*zO#2Mx@F!$Ik$~T`z8`jl?=qO6cP#%LV7A7xN9{VPK z?O;yK%Kkk0bhG$-e=M;|21lTl2UT2hDk9qfPQdJCeaybd%d86gsh<`NrB!LRTe>Jv zd&*56-Tx|ZvEo~!x0g*TN|g*ny)blY=ObGB>Dq~pSY@I(nWWkxP-5@_CqCM_a*iR- zr0BH3O#3vifeKkIN8`w|DRHjndcq#XG0A$<<~<{EKmvDL{v&1#U;4;?9nawpyuL2Ln2Syn)0*qbutT0TKfLgzA3) D`}_k0 literal 0 HcmV?d00001 diff --git a/tests/cms/samplekeys/credential_private_encrypted_AES256.p12 b/tests/cms/samplekeys/credential_private_encrypted_AES256.p12 new file mode 100644 index 0000000000000000000000000000000000000000..ced504c8593bc55e9d1fc4fe65b278cc1241cef0 GIT binary patch literal 4370 zcmai&bx;%x^T!W38WAK#i6alGqno2cknTo~?(_huqq_u2=@K|mQc@a^kP@Wx0F@(- z5)^oS=l7fE`SYEfot^!DcV_?F`OHEPl;pTLcn}1|AOZ1{SoPS;dpLwRB?yWZAcErk zU%3H-Ai@4?5tJZEw*N}&xHy2n<=ejw4#ec22LB%9DTMpqmJIS3NQ7!H7FhYEfRBqy z1b~nc5dGgaTw;6xgpq*QHdYQ##BICyN{=Q+xhPS+i0f%GLtSX><;yT|Oa|#hY|+QSZ(&+_0nGBI$r|nKhTa z=K(X>9>km+w|*s=X4tJ5vOXG04_?`m0(n%S&uR2b3_12EZU7}&Wd}baP6e}bnop~5 zJi_$Cy0NBHCj*^hGt!w0r{9BZWjEDf`BFl@>hFXw4r8rW_G($`JXET^uD}eUV;Z)K z=&w6XRVkF}jAtYgihA{f>Cc%Z$lX~jd@s*yWL!T@F?#V6d`RAj6TGb%d~v==sfY2i zwC{)D7~HEIi|7n}nVLbqU1)vOZc)f=(=De_RerZdJ7@GhB~T&+l+Ko5lbCUyU=xW% zV5^aRcOLn>bT%AaBJTJ~ht0J|JZb)N&m~jM6~bnId1u%S2=wk04dZCdQa%EskpbrO|*GmZ40trJou^*^R#|)^PQiy>2zG18-KP=WVMFw_R&dz*NgQR8%3M2vMZ=s zrhn5I+3l_jy}!Ywbl3IuqAZ+M%Q@Vvij7G(?uw_btxhA0UVfgcS7<-?JFku+P^4Mk zczZ-^f>VRMOXU}9%rk70^F|NObuS@QUaL)dfQt|BRS4{K$Kt0RQL$P+%sTCeM&YP$ zr;W3CBT#xo!!KiuUv`Fi>N#iKPJ0e6k$pL#8x<=#^X)lU*m+NSZ=v4GCqI7$WBzV` zm18vKn^63GD+?+o0H^*fH1#+f`;(iujbiwsuoJy z)A8c<$V#N@e6J}l4>2M2ip61btO40<&rY8 zjuj1^_36Dqqa)yL5gnV2tc|LcWUG0Pr;xvMd~sT;Rcn?XJsxERF7~O)cgOa2C4yG3 z82s!?SC*vGsA;aeNjx%h3P-*+<4enVedp>Gn(nKWba$&H(9=~Gx{&jDOeb795`LE= z0rxoveR4UunfWLzp4^iRuN2EMfIFWd7)R&Vv*f}Iyq;ihUSOu93w(szPa5=Z@=B(N zELzHAIM08St;a?)FpiEZ+&5|*dVP>s+{Me7j|kyEDXzmc4juNJY;jxQBXZGSe|QER z!+t)*bmp%!x}1*OF@(e~?7@tlJ^_e{m)v5P=DfcPsq+`Wy?C$Fs zuXfkf776a#G0l_QcS>p2qR^GEt6B6w_+*EJA4P0hy<$)B1}v3ebU#0Qqw7l#cI_(S z%pba8YbC=abrSZv!rLgn48pTY>SitelHqWcR>=TLl^2#>6>t<2*#?+6VNj@wN~`v3 zRjdx5p_f#A)F3GnY(OmR~=njjMDv9ki0j z7+yL?STU=OLkg|)wb_-y0zcUR(n}|&NRDsf&e~nC0uMWrUx%Ekd^oh?6AVX|_|Wj+ zKP3n2C&ZH!vj$ORUgwui>PWPdN%Kx71*>qut5X~Cm|Auy1A5m)+c&T$g-2V>y2y)j z3*Q~A=9QZ6;@f=@{MND!R9I-tOUKVWD=$J73t8ZaV~3dNrU= z#CW@8YETlJyd3MymV;l|gftYW2z+N%XVb!mhh~zsjfv1+QWc(+@pqofXJgc67oCuI z4RQpT7a#WviiASbni%3qdo_r=dK!^kb7B#O@B5r6JpG^Vk;uqbC`JC@T5Y$Az5J8- zZnOlPo>IsSB7dx8Jf7v;;wS+vzuQ{<71zXb(^uW32C~zd${(@^U$3a8Teenw{4m3k ztX;@Nkyzw9;>X42D5k&Lh^8aw#5F#Ti>|3MC=C6?x;@sTxOVSGs-BO`Scs{%>9vj>9QTj8M^}~KsaI? zt_=bqSDceCS&|uEaqDlfN@i^TKJW>QRqblDiwdLFGnJ*@=66ySY+~jKFIputaBI!|}_xJIY*08Mrdah|lN~O&Be8zWt2WvEKS^^} zHGb#iS@7|MM?VULgjct!yvfw_b|PZD2p_v1f-SBL0XN`YyG$sq=g~?!)|woevJX>C z4JnFdUH1Bo*1!bp-VWcM#dYe=MzHW(ZBMlnayOe6(MQ710Pxl991vuu6YIzHU2IXJ4LBcrJU5cx> zs_b2vUgp*jXOAN<@g*S${HA~S^}j%jUjanmm;99r|7I=$>Ho7b83_*VUsLd}$oIbh zIA3s%m93O*@P7huEaALGe|-Y6F~Oa$2*kz;hyYGmH670rUS+joyo>wnXL1^Xbra;^ zjm2QgAaZ4+2aD{QB`24O%8Abky=8s?p*nt)TbcVZZ4FqMntd9GOiLccKCir=Q6Vf+ z{L^hQEx7hrZMIoHpcLC{5|9^Y7}u*y`a%Hl5h~3{!{pJ~XEl)^A^n9vH_riaObV0c zH}p*qC2VP?+6qdLvHoyp8ds?~WnEK??i3K+Q*j+&D3_TMGak{a{b73cA$D%1_m1B; zhh=4o=_6=AhGyGyujK6^{9)@_?y~9-yYN7(n4tr-1_@Of79Q8Ngx3Z7ehifShNJNX zD^%fhnlU=qQx z$%3ug=%cFIo;@2XYe@OkAig*OL8;+Zcs!&El;CcgOFm-TU>AelmP2`YcNn0jKo>aP zP^mjvg{f2`HZbgiPY|^XkXLQw-g++g8*~s`mJiRiO2I&4SY-}xfPditCCWQN=V`a8 z_DfXs`^&HFa%$sqS$=MuEDC$}?WfyK6{jTx1k9$GW< znx-GaQJpUZea0ISe1AiT9A_(aHO`Au5mOg)IOsGi9|Ug(>*Bu>WH&wdkU9Rdjr_}Z zICVk0(1R_J(GPM)Y|V7{n%0C+GBrN1pg-|zI&RyG_O|l$OPBt~$13&rwROP0aW}PK zw&#*aBZuxWaK(1esO0@t7-?-|DI9}Um@Ro;=vn5%jeONzwrRI;l-^Dzl-$hY5g~4Q zS~1xsnPp}c*mER2VykUKrLY^r@kPq5jDK=Yk$`cz^7TPh?c(c(f=Mv*&Y7!2$C4n+ zl1TGfx{!)`NDZSSVdt+?dI(+6(RMq|({fpd!ZyU@ZlXT=UgKFIx!k_M|5 z%;<_{k8G8wz!kWMHW$180X?2W6DrhyCqwcJ7M%EP7tD*JDDkQ1GpfcPXZEj!;xB8n znpA?PaxUDHhIw|T)E`Peug93)y)(gPHM|hyM^%lU!Wkq!9{RQ(#A*o zCM8CT(CeYLiIw)L{aKV(`g`pnw1mM|aKKnkO=9aaL$8Ci6q~3RrJ-VjaW;p;N%CG( zN<}1_I~}y-KC>1l6D{`J$znk9MPOL+Vh;1VukEDz0x$iwreefQm4OOcr1nq0<52lj zMzHYUF#BHvtUQSaf(oz59x8-Ho5Ar9gDcZgb$ zg^3BE3vdRw0NnqE3&0z|0?-Ep06YP9fERx=2%-QHgxve*n}Cah4*;^5wgA_Oe|&Z# pJ}`TK2P;+J1QUVGfue*p0gCHMdU literal 0 HcmV?d00001 From fd6c38605a0b3c19f5c33d7062625fde6cb3bb58 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Jan 2024 14:19:40 +0100 Subject: [PATCH 331/869] speedo: Add a hint to run ldconfig -- --- README | 1 + build-aux/speedo.mk | 2 ++ g10/keyedit.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README b/README index b979234ce..a1e989356 100644 --- a/README +++ b/README @@ -94,6 +94,7 @@ example: make -f build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24 + ldconfig -n /usr/local/gnupg24/lib and adding /usr/local/gnupg24/bin to PATH. diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 335594b51..00244fa8e 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -1132,6 +1132,7 @@ ifneq ($(TARGETOS),w32) echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly" ;\ echo "speedo: * Or run:" ;\ echo "speedo: * make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24" ;\ + echo "speedo: * ldconfig -n /usr/local/gnupg24/lib";\ echo "speedo: */") endif @@ -1147,6 +1148,7 @@ ifneq ($(TARGETOS),w32) echo "speedo: Set SYSROOT to the desired install directory";\ echo "speedo: Example:";\ echo "speedo: make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24";\ + echo "speedo: ldconfig -n /usr/local/gnupg24/lib";\ exit 1;\ fi;\ if [ ! -d "$$SYSROOT"/bin ]; then if ! mkdir "$$SYSROOT"/bin; then \ diff --git a/g10/keyedit.c b/g10/keyedit.c index cae0f7841..e56e6d10b 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3336,7 +3336,7 @@ keyedit_quick_addadsk (ctrl_t ctrl, const char *fpr, const char *adskfpr) /* Unattended expiration setting function for the main key. If * SUBKEYFPRS is not NULL and SUBKEYSFPRS[0] is neither NULL, it is * expected to be an array of fingerprints for subkeys to change. It - * may also be an array which just one item "*" to indicate that all + * may also be an array with only the item "*" to indicate that all * keys shall be set to that expiration date. */ void From ccfbb9ebdf2ead9c8c9f824fa17b1e79c692c924 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 24 Jan 2024 13:45:49 +0900 Subject: [PATCH 332/869] kbx: Have threads monitoring socket takeover and homedir if no inotify. * kbx/keyboxd.c (CHECK_PROBLEMS_INTERVAL): New. (have_homedir_inotify): Remove the global. [HAVE_W32_SYSTEM] (create_an_event): New. (handle_tick): Remove. (handle_signal): Add handling SIGCONT. (keyboxd_kick_the_loop): New. (handle_connections): Spawn check_own_socket_thread and check_others_thread if no inotify. (check_own_socket_thread, check_others_thread): New. -- This change follows the change of gpg-agent. Signed-off-by: NIIBE Yutaka --- kbx/keyboxd.c | 350 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 231 insertions(+), 119 deletions(-) diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c index 66ffbcb3e..73905eb7d 100644 --- a/kbx/keyboxd.c +++ b/kbx/keyboxd.c @@ -144,14 +144,13 @@ static struct debug_flags_s debug_flags [] = { 77, NULL } /* 77 := Do not exit on "help" or "?". */ }; -/* The timer tick used for housekeeping stuff. Note that on Windows - * we use a SetWaitableTimer seems to signal earlier than about 2 - * seconds. Thus we use 4 seconds on all platforms. - * CHECK_OWN_SOCKET_INTERVAL defines how often we check - * our own socket in standard socket mode. If that value is 0 we - * don't check at all. All values are in seconds. */ -# define TIMERTICK_INTERVAL (4) -# define CHECK_OWN_SOCKET_INTERVAL (60) +/* CHECK_OWN_SOCKET_INTERVAL defines how often we check our own socket + * in standard socket mode. If that value is 0 we don't check at all. + * Values is in seconds. */ +#define CHECK_OWN_SOCKET_INTERVAL (60) +/* CHECK_PROBLEMS_INTERVAL defines how often we check the existence of + * homedir. Value is in seconds. */ +#define CHECK_PROBLEMS_INTERVAL (4) /* The list of open file descriptors at startup. Note that this list * has been allocated using the standard malloc. */ @@ -171,8 +170,10 @@ static int shutdown_pending; /* Flag indicating to start the daemon even if one already runs. */ static int steal_socket; -/* Counter for the currently running own socket checks. */ -static int check_own_socket_running; +/* Flag to monitor problems. */ +static int problem_detected; +#define KEYBOXD_PROBLEM_SOCKET_TAKEOVER (1 << 0) +#define KEYBOXD_PROBLEM_HOMEDIR_REMOVED (1 << 1) /* Flag to indicate that we shall not watch our own socket. */ static int disable_check_own_socket; @@ -192,6 +193,17 @@ static assuan_sock_nonce_t socket_nonce; * Let's try this as default. Change at runtime with --listen-backlog. */ static int listen_backlog = 64; +#ifdef HAVE_W32_SYSTEM +/* The event to break the select call. */ +static HANDLE the_event2; +#elif defined(HAVE_PSELECT_NO_EINTR) +/* An FD to break the select call. */ +static int event_pipe_fd; +#else +/* PID of the main thread. */ +static pid_t main_thread_pid; +#endif + /* Name of a config file, which will be reread on a HUP if it is not NULL. */ static char *config_filename; @@ -199,11 +211,6 @@ static char *config_filename; * the log file after a SIGHUP if it didn't changed. Malloced. */ static char *current_logfile; -/* This flag is true if the inotify mechanism for detecting the - * removal of the homedir is active. This flag is used to disable the - * alternative but portable stat based check. */ -static int have_homedir_inotify; - /* Number of active connections. */ static int active_connections; @@ -250,8 +257,11 @@ static void kbxd_init_default_ctrl (ctrl_t ctrl); static void kbxd_deinit_default_ctrl (ctrl_t ctrl); static void handle_connections (gnupg_fd_t listen_fd); -static void check_own_socket (void); static int check_for_running_kbxd (int silent); +#if CHECK_OWN_SOCKET_INTERVAL > 0 +static void *check_own_socket_thread (void *arg); +#endif +static void *check_others_thread (void *arg); /* * Functions. @@ -1055,6 +1065,44 @@ get_kbxd_active_connection_count (void) } +/* Under W32, this function returns the handle of the scdaemon + notification event. Calling it the first time creates that + event. */ +#if defined(HAVE_W32_SYSTEM) +static void * +create_an_event (void) +{ + HANDLE h, h2; + SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE}; + + /* We need to use a manual reset event object due to the way our + w32-pth wait function works: If we would use an automatic + reset event we are not able to figure out which handle has + been signaled because at the time we single out the signaled + handles using WFSO the event has already been reset due to + the WFMO. */ + h = CreateEvent (&sa, TRUE, FALSE, NULL); + if (!h) + log_error ("can't create an event: %s\n", w32_strerror (-1) ); + else if (!DuplicateHandle (GetCurrentProcess(), h, + GetCurrentProcess(), &h2, + EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0)) + { + log_error ("setting synchronize for an event failed: %s\n", + w32_strerror (-1) ); + CloseHandle (h); + } + else + { + CloseHandle (h); + return h2; + } + + return INVALID_HANDLE_VALUE; +} +#endif /*HAVE_W32_SYSTEM*/ + + /* Create a name for the socket in the home directory as using * STANDARD_NAME. We also check for valid characters as well as * against a maximum allowed length for a Unix domain socket is done. @@ -1267,38 +1315,6 @@ create_directories (void) -/* This is the worker for the ticker. It is called every few seconds - * and may only do fast operations. */ -static void -handle_tick (void) -{ - static time_t last_minute; - struct stat statbuf; - - if (!last_minute) - last_minute = time (NULL); - - /* Code to be run from time to time. */ -#if CHECK_OWN_SOCKET_INTERVAL > 0 - if (last_minute + CHECK_OWN_SOCKET_INTERVAL <= time (NULL)) - { - check_own_socket (); - last_minute = time (NULL); - } -#endif - - - /* Check whether the homedir is still available. */ - if (!shutdown_pending - && !have_homedir_inotify - && gnupg_stat (gnupg_homedir (), &statbuf) && errno == ENOENT) - { - shutdown_pending = 1; - log_info ("homedir has been removed - shutting down\n"); - } -} - - /* A global function which allows us to call the reload stuff from * other places too. This is only used when build for W32. */ void @@ -1344,6 +1360,11 @@ handle_signal (int signo) kbxd_sigusr2_action (); break; + case SIGCONT: + /* Do nothing, but break the syscall. */ + log_debug ("SIGCONT received - breaking select\n"); + break; + case SIGTERM: if (!shutdown_pending) log_info ("SIGTERM received - shutting down ...\n"); @@ -1435,6 +1456,28 @@ start_connection_thread (void *arg) } +static void +keyboxd_kick_the_loop (void) +{ + /* Kick the select loop. */ +#ifdef HAVE_W32_SYSTEM + int ret = SetEvent (the_event2); + if (ret == 0) + log_error ("SetEvent for agent_kick_the_loop failed: %s\n", + w32_strerror (-1)); +#else +# ifdef HAVE_PSELECT_NO_EINTR + write (event_pipe_fd, "", 1); +# else + int ret = kill (main_thread_pid, SIGCONT); + if (ret < 0) + log_error ("sending signal for agent_kick_the_loop failed: %s\n", + gpg_strerror (gpg_error_from_syserror ())); +# endif +#endif +} + + /* Connection handler loop. Wait for connection requests and spawn a * thread after accepting a connection. */ static void @@ -1449,12 +1492,14 @@ handle_connections (gnupg_fd_t listen_fd) gnupg_fd_t fd; int nfd; int saved_errno; - struct timespec abstime; - struct timespec curtime; - struct timespec timeout; #ifdef HAVE_W32_SYSTEM HANDLE events[2]; unsigned int events_set; +#else + int signo; +# ifdef HAVE_PSELECT_NO_EINTR + int pipe_fd[2]; +# endif #endif int sock_inotify_fd = -1; int home_inotify_fd = -1; @@ -1465,7 +1510,7 @@ handle_connections (gnupg_fd_t listen_fd) } listentbl[] = { { "std", start_connection_thread }, }; - + int have_homedir_inotify = 0; ret = npth_attr_init(&tattr); if (ret) @@ -1478,10 +1523,23 @@ handle_connections (gnupg_fd_t listen_fd) npth_sigev_add (SIGUSR1); npth_sigev_add (SIGUSR2); npth_sigev_add (SIGINT); + npth_sigev_add (SIGCONT); npth_sigev_add (SIGTERM); npth_sigev_fini (); +# ifdef HAVE_PSELECT_NO_EINTR + ret = gnupg_create_pipe (pipe_fd); + if (ret) + { + log_error ("pipe creation failed: %s\n", gpg_strerror (ret)); + return; + } + event_pipe_fd = pipe_fd[1]; +# else + main_thread_pid = getpid (); +# endif #else - events[0] = INVALID_HANDLE_VALUE; + events[0] = the_event2 = create_an_event (); + events[1] = INVALID_HANDLE_VALUE; #endif if (disable_check_own_socket) @@ -1503,6 +1561,26 @@ handle_connections (gnupg_fd_t listen_fd) else have_homedir_inotify = 1; +#if CHECK_OWN_SOCKET_INTERVAL > 0 + if (!disable_check_own_socket && sock_inotify_fd == -1) + { + npth_t thread; + + err = npth_create (&thread, &tattr, check_own_socket_thread, NULL); + if (err) + log_error ("error spawning check_own_socket_thread: %s\n", strerror (err)); + } +#endif + + if (!have_homedir_inotify) + { + npth_t thread; + + err = npth_create (&thread, &tattr, check_others_thread, NULL); + if (err) + log_error ("error spawning check_others_thread: %s\n", strerror (err)); + } + FD_ZERO (&fdset); FD_SET (FD2INT (listen_fd), &fdset); nfd = FD2NUM (listen_fd); @@ -1521,9 +1599,6 @@ handle_connections (gnupg_fd_t listen_fd) listentbl[0].l_fd = listen_fd; - npth_clock_gettime (&abstime); - abstime.tv_sec += TIMERTICK_INTERVAL; - for (;;) { /* Shutdown test. */ @@ -1556,28 +1631,21 @@ handle_connections (gnupg_fd_t listen_fd) read_fdset = fdset; - npth_clock_gettime (&curtime); - if (!(npth_timercmp (&curtime, &abstime, <))) - { - /* Timeout. */ - handle_tick (); - npth_clock_gettime (&abstime); - abstime.tv_sec += TIMERTICK_INTERVAL; - } - npth_timersub (&abstime, &curtime, &timeout); +#ifdef HAVE_PSELECT_NO_EINTR + FD_SET (pipe_fd[0], &read_fdset); + if (nfd < pipe_fd[0]) + nfd = pipe_fd[0]; +#endif #ifndef HAVE_W32_SYSTEM - ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, + ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, NULL, npth_sigev_sigmask ()); saved_errno = errno; - { - int signo; - while (npth_sigev_get_pending (&signo)) - handle_signal (signo); - } + while (npth_sigev_get_pending (&signo)) + handle_signal (signo); #else - ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, + ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, NULL, events, &events_set); saved_errno = errno; @@ -1593,6 +1661,22 @@ handle_connections (gnupg_fd_t listen_fd) gnupg_sleep (1); continue; } + + if ((problem_detected & KEYBOXD_PROBLEM_SOCKET_TAKEOVER)) + { + /* We may not remove the socket as it is now in use by another + server. */ + inhibit_socket_removal = 1; + shutdown_pending = 2; + log_info ("this process is useless - shutting down\n"); + } + + if ((problem_detected & KEYBOXD_PROBLEM_HOMEDIR_REMOVED)) + { + shutdown_pending = 1; + log_info ("homedir has been removed - shutting down\n"); + } + if (ret <= 0) { /* Interrupt or timeout. Will be handled when calculating the @@ -1600,6 +1684,15 @@ handle_connections (gnupg_fd_t listen_fd) continue; } +#ifdef HAVE_PSELECT_NO_EINTR + if (FD_ISSET (pipe_fd[0], &read_fdset)) + { + char buf[256]; + + read (pipe_fd[0], buf, sizeof buf); + } +#endif + /* The inotify fds are set even when a shutdown is pending (see * above). So we must handle them in any case. To avoid that * they trigger a second time we close them immediately. */ @@ -1670,13 +1763,21 @@ handle_connections (gnupg_fd_t listen_fd) close (sock_inotify_fd); if (home_inotify_fd != -1) close (home_inotify_fd); +#ifdef HAVE_W32_SYSTEM + if (the_event2 != INVALID_HANDLE_VALUE) + CloseHandle (the_event2); +#endif +#ifdef HAVE_PSELECT_NO_EINTR + close (pipe_fd[0]); + close (pipe_fd[1]); +#endif cleanup (); log_info (_("%s %s stopped\n"), gpgrt_strusage(11), gpgrt_strusage(13)); npth_attr_destroy (&tattr); } - +#if CHECK_OWN_SOCKET_INTERVAL > 0 /* Helper for check_own_socket. */ static gpg_error_t check_own_socket_pid_cb (void *opaque, const void *buffer, size_t length) @@ -1687,20 +1788,18 @@ check_own_socket_pid_cb (void *opaque, const void *buffer, size_t length) } -/* The thread running the actual check. We need to run this in a - * separate thread so that check_own_thread can be called from the - * timer tick. */ -static void * -check_own_socket_thread (void *arg) +/* Check whether we are still listening on our own socket. In case + another gpg-agent process started after us has taken ownership of + our socket, we would linger around without any real task. Thus we + better check once in a while whether we are really needed. */ +static int +do_check_own_socket (const char *sockname) { int rc; - char *sockname = arg; assuan_context_t ctx = NULL; membuf_t mb; char *buffer; - check_own_socket_running++; - rc = assuan_new (&ctx); if (rc) { @@ -1738,57 +1837,70 @@ check_own_socket_thread (void *arg) xfree (buffer); leave: - xfree (sockname); if (ctx) assuan_release (ctx); - if (rc) - { - /* We may not remove the socket as it is now in use by another - * server. */ - inhibit_socket_removal = 1; - shutdown_pending = 2; - log_info ("this process is useless - shutting down\n"); - } - check_own_socket_running--; - return NULL; + + return rc; } - -/* Check whether we are still listening on our own socket. In case - * another keyboxd process started after us has taken ownership of our - * socket, we would linger around without any real task. Thus we - * better check once in a while whether we are really needed. */ -static void -check_own_socket (void) +/* The thread running the actual check. */ +static void * +check_own_socket_thread (void *arg) { char *sockname; - npth_t thread; - npth_attr_t tattr; - int err; - if (disable_check_own_socket) - return; - - if (check_own_socket_running || shutdown_pending) - return; /* Still running or already shutting down. */ + (void)arg; sockname = make_filename_try (gnupg_socketdir (), KEYBOXD_SOCK_NAME, NULL); if (!sockname) - return; /* Out of memory. */ + return NULL; /* Out of memory. */ - err = npth_attr_init (&tattr); - if (err) + while (!problem_detected) { - xfree (sockname); - return; - } - npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED); - err = npth_create (&thread, &tattr, check_own_socket_thread, sockname); - if (err) - log_error ("error spawning check_own_socket_thread: %s\n", strerror (err)); - npth_attr_destroy (&tattr); -} + if (shutdown_pending) + goto leave; + gnupg_sleep (CHECK_OWN_SOCKET_INTERVAL); + + if (do_check_own_socket (sockname)) + problem_detected |= KEYBOXD_PROBLEM_SOCKET_TAKEOVER; + } + + keyboxd_kick_the_loop (); + + leave: + xfree (sockname); + return NULL; +} +#endif + +/* The thread running other checks. */ +static void * +check_others_thread (void *arg) +{ + const char *homedir = gnupg_homedir (); + + (void)arg; + + while (!problem_detected) + { + struct stat statbuf; + + if (shutdown_pending) + goto leave; + + gnupg_sleep (CHECK_PROBLEMS_INTERVAL); + + /* Check whether the homedir is still available. */ + if (gnupg_stat (homedir, &statbuf) && errno == ENOENT) + problem_detected |= KEYBOXD_PROBLEM_HOMEDIR_REMOVED; + } + + keyboxd_kick_the_loop (); + + leave: + return NULL; +} /* Figure out whether a keyboxd is available and running. Prints an From bea31c845aad89142ac43e67b188591cf9b73c50 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Jan 2024 10:39:23 +0100 Subject: [PATCH 333/869] card: flush stdout to get checkcmd's info messages in order. * tools/gpg-card.c (cmd_checkkeys): Insert an fflush. --- tools/gpg-card.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 442acdc84..185d04b62 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -1490,6 +1490,7 @@ cmd_checkkeys (card_info_t callerinfo, char *argstr) xfree (infostr); } } + es_fflush (es_stdout); if (delete_count) log_info ("Number of deleted key copies: %d\n", delete_count); From 154ecf17bddc85c1cea0786e5c5792aca45413ca Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Jan 2024 13:41:04 +0100 Subject: [PATCH 334/869] speedo: Build zlib, bzip2 and sqlite also on Unix. -- This avoids extra build dependencies. Note that bzip2 is not necessary statically linked but an existing bzip2 SO might be used. We would need to fix the bzip2 SO building and also provide a gnupg configure option to build statically against bzip2. --- build-aux/speedo.mk | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 00244fa8e..477873f60 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -304,14 +304,9 @@ w32src := $(topsrc)/build-aux/speedo/w32 # Fixme: Do we need to build pkg-config for cross-building? speedo_spkgs = \ - libgpg-error npth libgcrypt - -ifeq ($(TARGETOS),w32) -speedo_spkgs += \ - zlib bzip2 sqlite -endif - -speedo_spkgs += libassuan libksba ntbtls gnupg + libgpg-error npth libgcrypt \ + zlib bzip2 sqlite \ + libassuan libksba ntbtls gnupg ifeq ($(STATIC),0) speedo_spkgs += gpgme @@ -546,7 +541,7 @@ speedo_pkg_gnupg_configure = \ else speedo_pkg_gnupg_configure = --disable-g13 --enable-wks-tools endif -speedo_pkg_gnupg_extracflags = -g +speedo_pkg_gnupg_extracflags = # Create the version info files only for W32 so that they won't get # installed if for example INSTALL_PREFIX=/usr/local is used. From a227a0d54da693bae4fe709c65e53b81762269f4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Jan 2024 14:06:32 +0100 Subject: [PATCH 335/869] po: Update German translation. -- Just the new string for gpg-card's checkkeys. --- po/de.po | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/po/de.po b/po/de.po index 7afa2d086..d4bf929ee 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.4.1\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-05-30 13:46+0200\n" +"PO-Revision-Date: 2024-01-24 14:05+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German\n" "Language: de\n" @@ -230,8 +230,9 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Bitte geben Sie ein Passwort ein, um den empfangenen geheimen Schlüssel" -"%%0A %s%%0A %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu schützen." +"Bitte geben Sie ein Passwort ein, um den empfangenen geheimen " +"Schlüssel%%0A %s%%0A %s%%0Aim Schlüsselspeicher des Gpg-Agenten zu " +"schützen." #, c-format msgid "failed to create stream from socket: %s\n" @@ -710,9 +711,9 @@ msgid "" "Do you ultimately trust%%0A \"%s\"%%0Ato correctly certify user " "certificates?" msgstr "" -"Wenn Sie vollständiges Vertrauen haben, daß%%0A \"%s" -"\"%%0ABenutzerzertifikate verläßlich zertifiziert, so antworten Sie mit \"Ja" -"\"." +"Wenn Sie vollständiges Vertrauen haben, daß%%0A " +"\"%s\"%%0ABenutzerzertifikate verläßlich zertifiziert, so antworten Sie mit " +"\"Ja\"." msgid "Yes" msgstr "Ja" @@ -776,8 +777,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Möchten Sie den Schlüssel mit dem \"Keygrip\"%%0A %s%%0A %%C%%0Awirklich " "entfernen?" @@ -1837,14 +1838,14 @@ msgstr "Aufgrund des S2K-Modus kann ein SKESK Paket nicht benutzt werden\n" msgid "using cipher %s.%s\n" msgstr "benutze Cipher %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "`%s' ist bereits komprimiert\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "WARNUNG: '%s' ist eine leere Datei.\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "`%s' ist bereits komprimiert\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "Die Benutzung der Hashmethode %s ist im %s Modus nicht erlaubt.\n" @@ -9106,6 +9107,9 @@ msgstr "Ein Zertifikat in einem Datenobjekt speichern" msgid "store a private key to a data object" msgstr "Privaten Schlüssel in einem Datenobjekt speichern" +msgid "run various checks on the keys" +msgstr "Die Schlüssel verschiedener Prüfungen unterziehen" + msgid "Yubikey management commands" msgstr "Verwaltungskommandos für Yubikeys" @@ -10484,8 +10488,8 @@ msgstr "Verwaltung der Kommandohistorie" #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n" #~ msgstr "" -#~ "Die \"Trust\"-Datenbank ist beschädigt; verwenden Sie \"gpg --fix-trustdb" -#~ "\".\n" +#~ "Die \"Trust\"-Datenbank ist beschädigt; verwenden Sie \"gpg --fix-" +#~ "trustdb\".\n" #~ msgid "Please report bugs to <" #~ msgstr "Fehlerberichte bitte an <" @@ -10710,8 +10714,8 @@ msgstr "Verwaltung der Kommandohistorie" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." From d4976e35d2ca431b2a651aa11be8a4589c8dd39a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Jan 2024 18:23:02 +0100 Subject: [PATCH 336/869] gpg: Add sub-option ignore-attributes to --import-options. * g10/options.h (IMPORT_IGNORE_ATTRIBUTES): New. * g10/import.c (parse_import_options): Add new sub-option. (read_block): Implement sub-option. -- Suggested-by: Robin H. Johnson Tested using the import-export feature: gpg --export KEY_WITH_PICTURE \ | gpg --import --import-options import-export,ignore-attributes \ | gpg --show-key --- doc/gpg.texi | 4 ++++ g10/import.c | 12 ++++++++++++ g10/options.h | 1 + 3 files changed, 17 insertions(+) diff --git a/doc/gpg.texi b/doc/gpg.texi index a54bc1fee..1bc2bd9e4 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2579,6 +2579,10 @@ opposite meaning. The options are: import-clean it suppresses the final clean step after merging the imported key into the existing key. + @item ignore-attributes + Ignore all attribute user IDs (photo IDs) and their signatures while + importing a key. + @item repair-keys After import, fix various problems with the keys. For example, this reorders signatures, and strips duplicate diff --git a/g10/import.c b/g10/import.c index c1e76c3f0..8f874a7d1 100644 --- a/g10/import.c +++ b/g10/import.c @@ -209,6 +209,9 @@ parse_import_options(char *str,unsigned int *options,int noisy) {"repair-keys", IMPORT_REPAIR_KEYS, NULL, N_("repair keys on import")}, + /* New options. Right now, without description string. */ + {"ignore-attributes", IMPORT_IGNORE_ATTRIBUTES, NULL, NULL}, + /* Hidden options which are enabled by default and are provided * in case of problems with the respective implementation. */ {"collapse-uids", IMPORT_COLLAPSE_UIDS, NULL, NULL}, @@ -1008,6 +1011,15 @@ read_block( IOBUF a, unsigned int options, init_packet(pkt); continue; } + else if ((opt.import_options & IMPORT_IGNORE_ATTRIBUTES) + && (pkt->pkttype == PKT_USER_ID || pkt->pkttype == PKT_ATTRIBUTE) + && pkt->pkt.user_id->attrib_data) + { + skip_sigs = 1; + free_packet (pkt, &parsectx); + init_packet (pkt); + continue; + } if (skip_sigs) { diff --git a/g10/options.h b/g10/options.h index e0ee99533..146b78361 100644 --- a/g10/options.h +++ b/g10/options.h @@ -406,6 +406,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define IMPORT_COLLAPSE_UIDS (1<<15) #define IMPORT_COLLAPSE_SUBKEYS (1<<16) #define IMPORT_BULK (1<<17) +#define IMPORT_IGNORE_ATTRIBUTES (1<<18) #define EXPORT_LOCAL_SIGS (1<<0) #define EXPORT_ATTRIBUTES (1<<1) From 6481d410ec673b9defcc150057988d34b7c0e712 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 25 Jan 2024 09:07:11 +0900 Subject: [PATCH 337/869] po: Update Japanese Translation. -- Signed-off-by: NIIBE Yutaka --- po/ja.po | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/po/ja.po b/po/ja.po index d067bf202..ab6a8dda4 100644 --- a/po/ja.po +++ b/po/ja.po @@ -5,13 +5,13 @@ # Yoshihiro Kajiki , 1999. # Takashi P.KATOH, 2002. # NIIBE Yutaka , 2013, 2014, 2015, 2016, 2017, 2018, 2019, -# 2020, 2021, 2022, 2023. +# 2020, 2021, 2022, 2023, 2024. # msgid "" msgstr "" "Project-Id-Version: gnupg 2.4.3\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-11-20 10:50+0900\n" +"PO-Revision-Date: 2024-01-25 09:06+0900\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -8729,6 +8729,9 @@ msgstr "証明書をデータオブジェクトに保管します" msgid "store a private key to a data object" msgstr "プライベート鍵をデータオブジェクトに保管する" +msgid "run various checks on the keys" +msgstr "鍵に対して様々なチェックを実行する" + msgid "Yubikey management commands" msgstr "Yubikey管理コマンド" From 2a4180812ac21257a82c091df1bec1b6e087a0bd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Jan 2024 10:00:13 +0100 Subject: [PATCH 338/869] card: Tweak the checkcmds sub-command. * tools/gpg-card.c (cmd_checkkeys): Skip not found keys. --- doc/gpg-card.texi | 34 ++++++++++++++++++++++++++++++++++ tools/gpg-card.c | 13 ++++++++----- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/doc/gpg-card.texi b/doc/gpg-card.texi index 33cdbd96d..8787793f8 100644 --- a/doc/gpg-card.texi +++ b/doc/gpg-card.texi @@ -316,6 +316,40 @@ Write a private key object identified by @var{keygrip} to the card under the id @var{keyref}. Option @option{--force} allows overwriting an existing key. +@item CHECKKEYS [--ondisk] [--delete-clear-copy] [--delete-protected-copy] +@opindex checkkeys +Print a list of keys noticed on all inserted cards. With +@option{--ondisk} only smartcard keys with a copy on disk are listed. +With @option{--delete-clear-copy} copies of smartcard keys stored on +disk without any protection will be deleted. With +@option{--delete-protected-copy} password protected copies of +smartcard keys stored on disk will be deleted. + +This command creates missing shadow keys. The delete options print +the status of the keys before they are deleted. + +The format of the output is: +@table @var +@item Serial number +A hex-string with the serial number of the card. +@item Type +This gives the type of the card's application. For example "OpenPGP" +or "PIV". +@item Keygrip +A hex-string identifying a key. +@item Keyref +The application slot where the key is stored on the card. For example +"OpenPGP.1" +@item Status +The status of the key. The most common value is "shadowed" for a key +where only the public key along with the card's serial number is +stored on the disk. The value "clear" indicates that a copy of the +card's key is stored unprotected on disk. The value "protected" +indicated that a copy of the car's key is stored on disk but is +protected by a password. The value "error" may also be shown if there +was a problem reading information from the card. +@end table + @item YUBIKEY @var{cmd} @var{args} @opindex yubikey Various commands pertaining to Yubikey tokens with @var{cmd} being: diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 185d04b62..f65a17b3c 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -1397,11 +1397,12 @@ cmd_checkkeys (card_info_t callerinfo, char *argstr) if (!callerinfo) return print_help - ("CHECKKEYS [--ondisk] [--delete-clear-copy]\n\n" + ("CHECKKEYS [--ondisk] [--delete-clear-copy] [--delete-protected-copy]" + "\n\n" "Print a list of keys on all inserted cards. With --ondisk only\n" "keys are listed which also have a copy on disk. Missing shadow\n" - "keys are created. With --delete-clear, copies of keys also stored\n" - "on disk without any protection will be deleted.\n" + "keys are created. With --delete-clear-copy, copies of keys also\n" + "stored on disk without any protection will be deleted.\n" , 0); @@ -1461,11 +1462,13 @@ cmd_checkkeys (card_info_t callerinfo, char *argstr) scd_readkey (kinfo->keyref, 1, NULL); err = scd_havekey_info (kinfo->grip, &infostr); } - if (err) + if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND) log_error ("Error getting infos for a key: %s\n", gpg_strerror (err)); - if (opt_ondisk && infostr && !strcmp (infostr, "shadowed")) + if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) + ; /* does not make sense to show this. */ + else if (opt_ondisk && infostr && !strcmp (infostr, "shadowed")) ; /* Don't print this one. */ else { From c5429644e98b7231ddc03a1fb3a514245550cf88 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Jan 2024 11:05:48 +0100 Subject: [PATCH 339/869] po: msgmerge -- --- po/ca.po | 21 +++++++++------- po/cs.po | 23 +++++++++-------- po/da.po | 25 +++++++++++-------- po/el.po | 21 +++++++++------- po/eo.po | 21 +++++++++------- po/es.po | 31 ++++++++++++----------- po/et.po | 25 +++++++++++-------- po/fi.po | 21 +++++++++------- po/fr.po | 23 +++++++++-------- po/gl.po | 29 +++++++++++---------- po/hu.po | 21 +++++++++------- po/id.po | 21 +++++++++------- po/it.po | 19 ++++++++------ po/nb.po | 19 ++++++++------ po/pl.po | 72 ++++++++++++++++++++++++++++------------------------- po/pt.po | 31 +++++++++++++++++++++-- po/ro.po | 33 +++++++++++++----------- po/ru.po | 27 +++++++++++--------- po/sk.po | 29 +++++++++++---------- po/sv.po | 25 +++++++++++-------- po/tr.po | 15 ++++++----- po/uk.po | 23 +++++++++-------- po/zh_CN.po | 19 ++++++++------ po/zh_TW.po | 15 ++++++----- 24 files changed, 353 insertions(+), 256 deletions(-) diff --git a/po/ca.po b/po/ca.po index 9b7cd8d1c..b2c28e72f 100644 --- a/po/ca.po +++ b/po/ca.po @@ -810,8 +810,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Realment voleu eliminar les claus seleccionades? " #, fuzzy @@ -1953,16 +1953,16 @@ msgstr "no es pot usar un paquet asimètric ESK al estar en mode S2K\n" msgid "using cipher %s.%s\n" msgstr "Ha fallat el procés de signatura: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "«%s» ja està comprimida\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVÍS: «%s» és un fitxer buit\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "«%s» ja està comprimida\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "no podeu usar l'algorisme de resum %s mentre esteu en mode %s\n" @@ -9496,6 +9496,9 @@ msgstr "S'ha creat el certificat de revocació.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10682,8 +10685,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/cs.po b/po/cs.po index 7506778cd..8b6287734 100644 --- a/po/cs.po +++ b/po/cs.po @@ -786,8 +786,8 @@ msgstr "Vyžádáno použití klíče%%0A %s%%0A %s%%0APřejete si to povolit? #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Opravdu chcete smazat klíč určený pomocí keygripu%%0A %s%%0A %%C%%0A?" @@ -1831,14 +1831,14 @@ msgstr "v režimu S2K nelze použít SKESK paket\n" msgid "using cipher %s.%s\n" msgstr "použití šifry %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "„%s“ je již zkomprimován\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "POZOR: soubor „%s“ je prázdný\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "„%s“ je již zkomprimován\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "hashovací algoritmus „%s“ se nesmí používat v režimu %s\n" @@ -8974,6 +8974,9 @@ msgstr "uloží certifikát do datového objektu" msgid "store a private key to a data object" msgstr "uloží soukromý klíč do datového objektu" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Příkazy pro správu Yubikey" @@ -10568,8 +10571,8 @@ msgstr "spravuje historii příkazů" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -10616,8 +10619,8 @@ msgstr "spravuje historii příkazů" #~ "Answer \"yes\" if you really want to delete this user ID.\n" #~ "All certificates are then also lost!" #~ msgstr "" -#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte \"ano" -#~ "\".\n" +#~ "Pokud opravdu chcete smazat tento identifikátor uživatele, odpovězte " +#~ "\"ano\".\n" #~ "Všechny certifikáty budou také ztraceny!" #~ msgid "Answer \"yes\" if it is okay to delete the subkey" diff --git a/po/da.po b/po/da.po index a2b7ef163..602b28d75 100644 --- a/po/da.po +++ b/po/da.po @@ -259,8 +259,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Indtast venligst en adgangsfrase for at beskytte den modtaget hemmelige nøgle" -"%%0A %s%%0A %s%%0Ainden i gpg-agentens nøglelager" +"Indtast venligst en adgangsfrase for at beskytte den modtaget hemmelige " +"nøgle%%0A %s%%0A %s%%0Ainden i gpg-agentens nøglelager" #, c-format msgid "failed to create stream from socket: %s\n" @@ -868,8 +868,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Vil du virkelig slette de valgte nøgler? (j/N) " #, fuzzy @@ -1995,16 +1995,16 @@ msgstr "kan ikke bruge en symmetrisk ESK-pakke på grund af S2K-tilstanden\n" msgid "using cipher %s.%s\n" msgstr "bruger chiffer %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "»%s« allerede komprimeret\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "ADVARSEL: »%s« er en tom fil\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "»%s« allerede komprimeret\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm `%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -2527,8 +2527,8 @@ msgstr "ADVARSEL: Usikre indelukkede mapperettigheder på hjemmemappe »%s«\n" #, fuzzy, c-format #| msgid "" -#| "WARNING: unsafe enclosing directory permissions on configuration file `" -#| "%s'\n" +#| "WARNING: unsafe enclosing directory permissions on configuration file " +#| "`%s'\n" msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" @@ -9711,6 +9711,9 @@ msgstr " (certifkat oprettet den " msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" diff --git a/po/el.po b/po/el.po index 08f85c82c..9417187b7 100644 --- a/po/el.po +++ b/po/el.po @@ -777,8 +777,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Σίγουρα θέλετε να διαγραφούν τα επιλεγμένα κλειδιά; " #, fuzzy @@ -1885,16 +1885,16 @@ msgstr "αδυναμία χρήσης ενός συμμετρικού πακέτ msgid "using cipher %s.%s\n" msgstr "χρήση του κρυπταλγόριθμου: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' ήδη συμπιέστηκε\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: `%s' είναι ένα άδειο αρχείο\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' ήδη συμπιέστηκε\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -9320,6 +9320,9 @@ msgstr "Πιστοποιητικό ανάκλησης δημιουργήθηκε msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10489,8 +10492,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/eo.po b/po/eo.po index d77143896..3a9a4d130 100644 --- a/po/eo.po +++ b/po/eo.po @@ -776,8 +776,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Ĉu vi vere volas forviŝi la elektitajn ŝlosilojn? " #, fuzzy @@ -1878,16 +1878,16 @@ msgstr "" msgid "using cipher %s.%s\n" msgstr "subskribado malsukcesis: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "'%s' jam densigita\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVERTO: '%s' estas malplena dosiero\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "'%s' jam densigita\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "Tiu komando ne eblas en la reĝimo %s.\n" @@ -9231,6 +9231,9 @@ msgstr "ŝlosilo %08lX: revokatestilo aldonita\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10312,8 +10315,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/es.po b/po/es.po index 635084915..7edbe88d7 100644 --- a/po/es.po +++ b/po/es.po @@ -776,8 +776,8 @@ msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " "fingerprint:%%0A %s" msgstr "" -"Por favor verifique que el certificado identificado como:%%0A \"%s" -"\"%%0Atiene la huella digital:%%0A %s" +"Por favor verifique que el certificado identificado como:%%0A " +"\"%s\"%%0Atiene la huella digital:%%0A %s" #. TRANSLATORS: "Correct" is the label of a button and intended #. to be hit if the fingerprint matches the one of the CA. The @@ -821,8 +821,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "¿De verdad quiere borrar la clave identificada con el keygrip%%0A %s%%0A " "%%C%%0A?" @@ -1889,14 +1889,14 @@ msgstr "no puede usar un paquete simétrico ESK debido al modo S2K\n" msgid "using cipher %s.%s\n" msgstr "usando cifrado %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' ya está comprimido\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "ATENCIÓN '%s' es un fichero vacío\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' ya está comprimido\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "no puede usar el resumen '%s' en modo %s\n" @@ -5704,8 +5704,8 @@ msgstr "" "la clave secreta. De cualquier modo, si la clave secreta está disponible,\n" "es mejor generar un nuevo certificado de revocación y dar una razón para la " "misma\n" -"Para más detalles, lee la descripción de la orden gpg \"--generate-revocation" -"\"\n" +"Para más detalles, lee la descripción de la orden gpg \"--generate-" +"revocation\"\n" "en el manual GnuPG." msgid "" @@ -9157,6 +9157,9 @@ msgstr "añadir un certificado a la cache" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10532,8 +10535,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -10572,8 +10575,8 @@ msgstr "" #~ " al poseedor de la clave.\n" #~ "\n" #~ "Observe que los ejemplos dados en los niveles 2 y 3 son *solo* ejemplos.\n" -#~ "En definitiva, usted decide lo que significa \"informal\" y \"exhaustivo" -#~ "\"\n" +#~ "En definitiva, usted decide lo que significa \"informal\" y " +#~ "\"exhaustivo\"\n" #~ "para usted cuando firma las claves de otros.\n" #~ "\n" #~ "Si no sabe qué contestar, conteste \"0\"." diff --git a/po/et.po b/po/et.po index 1f07b58fc..139ed412c 100644 --- a/po/et.po +++ b/po/et.po @@ -774,8 +774,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Kas te tõesti soovite valitud võtmeid kustutada? " #, fuzzy @@ -1879,16 +1879,16 @@ msgstr "S2K moodi tõttu ei saa sümmeetrilist ESK paketti kasutada\n" msgid "using cipher %s.%s\n" msgstr "kasutan šiffrit %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' on juba pakitud\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "HOIATUS: `%s' on tühi fail\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' on juba pakitud\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "sõnumilühendi algoritm \"%s\" ei ole moodis %s lubatud\n" @@ -9235,6 +9235,9 @@ msgstr "Tühistamise sertifikaat on loodud.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10276,8 +10279,8 @@ msgstr "" #~ msgid "If you want to use this untrusted key anyway, answer \"yes\"." #~ msgstr "" -#~ "Kui te ikkagi soovite kasutada seda mitteusaldatavat võtit, vastake \"jah" -#~ "\"." +#~ "Kui te ikkagi soovite kasutada seda mitteusaldatavat võtit, vastake " +#~ "\"jah\"." #~ msgid "" #~ "Enter the user ID of the addressee to whom you want to send the message." @@ -10373,8 +10376,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/fi.po b/po/fi.po index 4248372d3..505f5c237 100644 --- a/po/fi.po +++ b/po/fi.po @@ -791,8 +791,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Haluatko varmasti poistaa valitut avaimet? " #, fuzzy @@ -1897,16 +1897,16 @@ msgstr "symmetristä ESK-pakettia ei voi käyttää S2K-tilan vuoksi\n" msgid "using cipher %s.%s\n" msgstr "käytetään salakirjoitusalgoritmia %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "\"%s\" on jo pakattu\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "VAROITUS: \"%s\" on tyhjä tiedosto\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "\"%s\" on jo pakattu\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "tiivistealgoritmia \"%s\" ei voi käyttää %s-tilassa\n" @@ -9303,6 +9303,9 @@ msgstr "Mitätöintivarmenne luotu.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10465,8 +10468,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/fr.po b/po/fr.po index e7ea9ffc2..7baf95d2c 100644 --- a/po/fr.po +++ b/po/fr.po @@ -246,8 +246,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Veuillez entrer une phrase secrète pour protéger la clef secrète%%0A %s" -"%%0A %s%%0Areçue dans l'espace de stockage de clefs de gpg-agent" +"Veuillez entrer une phrase secrète pour protéger la clef secrète%%0A " +"%s%%0A %s%%0Areçue dans l'espace de stockage de clefs de gpg-agent" #, c-format msgid "failed to create stream from socket: %s\n" @@ -824,8 +824,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Voulez-vous vraiment supprimer les clefs sélectionnées ? (o/N) " msgid "Delete key" @@ -1931,14 +1931,14 @@ msgstr "impossible d'utiliser un paquet ESK symétrique en mode S2K\n" msgid "using cipher %s.%s\n" msgstr "utilisation de l'algorithme de chiffrement %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "« %s » est déjà compressé\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "Attention : « %s » est un fichier vide\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "« %s » est déjà compressé\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm '%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -9514,6 +9514,9 @@ msgstr "ajouter un certificat au cache" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10997,8 +11000,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/gl.po b/po/gl.po index 73e3ff463..5f408eabd 100644 --- a/po/gl.po +++ b/po/gl.po @@ -779,8 +779,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "¿Seguro de que quere borra-las chaves seleccionadas? " #, fuzzy @@ -1889,16 +1889,16 @@ msgstr "non se pode empregar un paquete simétrico ESK debido ao modo S2K\n" msgid "using cipher %s.%s\n" msgstr "fallou a sinatura: %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' xa está comprimido\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVISO: `%s' é un ficheiro baleiro\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' xa está comprimido\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "non se pode empregar o algoritmo de resumo \"%s\" no modo %s\n" @@ -3173,8 +3173,8 @@ msgstr "chave %08lX: non hai ID de usuario para a sinatura\n" #, fuzzy, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"chave %08lX: algoritmo de chave pública non soportado no ID de usuario \"%s" -"\"\n" +"chave %08lX: algoritmo de chave pública non soportado no ID de usuario " +"\"%s\"\n" #, fuzzy, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" @@ -9315,6 +9315,9 @@ msgstr "Creouse o certificado de revocación.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10302,8 +10305,8 @@ msgstr "" #~ msgid "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n" #~ msgstr "" -#~ "a base de datos de confianza está corrompida; execute \"gpg --fix-trustdb" -#~ "\".\n" +#~ "a base de datos de confianza está corrompida; execute \"gpg --fix-" +#~ "trustdb\".\n" #~ msgid "Please report bugs to .\n" #~ msgstr "" @@ -10483,8 +10486,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/hu.po b/po/hu.po index a0e96c94d..0955d468a 100644 --- a/po/hu.po +++ b/po/hu.po @@ -774,8 +774,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Valóban törli a kiválasztott kulcsokat? " #, fuzzy @@ -1880,16 +1880,16 @@ msgstr "Nem tudok szimmetrikus ESK csomagot használni a S2K mód miatt!\n" msgid "using cipher %s.%s\n" msgstr "%s rejtjelezést használok.\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "\"%s\" már tömörített.\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "FIGYELEM: A(z) \"%s\" állomány üres.\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "\"%s\" már tömörített.\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -9262,6 +9262,9 @@ msgstr "Visszavonó igazolás létrehozva.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10418,8 +10421,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/id.po b/po/id.po index 259fe9937..5a22bb96d 100644 --- a/po/id.po +++ b/po/id.po @@ -779,8 +779,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Anda ingin menghapus kunci terpilih ini? " #, fuzzy @@ -1886,16 +1886,16 @@ msgstr "tidak dapat menggunakan paket simetri ESK karena mode S2K\n" msgid "using cipher %s.%s\n" msgstr "menggunakan cipher %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' sudah dikompresi\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "PERINGATAN: `%s' adalah file kosong\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' sudah dikompresi\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -9261,6 +9261,9 @@ msgstr "Sertifikat pembatalan tercipta.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10418,8 +10421,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/it.po b/po/it.po index f301780da..f3bcde883 100644 --- a/po/it.po +++ b/po/it.po @@ -225,8 +225,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Immettere una passphrase per proteggere la chiave segreta ricevuta%%0A %s" -"%%0A %s%%0A all'interno dell'archivio chiavi dell'agente gpg" +"Immettere una passphrase per proteggere la chiave segreta ricevuta%%0A " +"%s%%0A %s%%0A all'interno dell'archivio chiavi dell'agente gpg" #, c-format msgid "failed to create stream from socket: %s\n" @@ -771,8 +771,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Si desidera eliminare la chiave identificata da keygrip%%0A %s%%0A %%C%%0A?" @@ -1828,14 +1828,14 @@ msgstr "" msgid "using cipher %s.%s\n" msgstr "utilizzando il cifrario %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' già compresso\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "AVVISO: '%s' è un file vuoto\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' già compresso\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "l'algoritmo digest '%s' non può essere utilizzato in modalità %s\n" @@ -9069,6 +9069,9 @@ msgstr "archiviare un certificato in un oggetto dati" msgid "store a private key to a data object" msgstr "archiviare una chiave privata in un oggetto dati" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Comandi di gestione Yubikey" diff --git a/po/nb.po b/po/nb.po index dcbd64efa..e79896ccb 100644 --- a/po/nb.po +++ b/po/nb.po @@ -237,8 +237,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Skriv inn passordfrase som skal brukes til å beskytte mottatt hemmelig nøkkel" -"%%0A %s%%0A %s%%0Ai nøkkellageret for gpg-agent" +"Skriv inn passordfrase som skal brukes til å beskytte mottatt hemmelig " +"nøkkel%%0A %s%%0A %s%%0Ai nøkkellageret for gpg-agent" #, c-format msgid "failed to create stream from socket: %s\n" @@ -782,8 +782,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Er du sikker på at du vil slette nøkkel med nøkkelgrep%%0A %s%%0A %%C%%0A?" @@ -1858,14 +1858,14 @@ msgstr "klarte ikke å bruke symmetrisk ESK-pakke på grunn av S2K-modus\n" msgid "using cipher %s.%s\n" msgstr "bruker krypteringsmetode %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "«%s» er allerede komprimert\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "ADVARSEL: «%s» er en tom fil\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "«%s» er allerede komprimert\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "du kan ikke bruke algoritme «%s» i %s-modus\n" @@ -9046,6 +9046,9 @@ msgstr "legg til sertifikat i hurtiglager" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" diff --git a/po/pl.po b/po/pl.po index d9d98e9d2..1248d87c6 100644 --- a/po/pl.po +++ b/po/pl.po @@ -170,14 +170,15 @@ msgid "" "Please enter the passphrase to protect the imported object within the %s " "system." msgstr "" -"Proszę wprowadzić hasło do zabezpieczenia importowanego obiektu w systemie %s." +"Proszę wprowadzić hasło do zabezpieczenia importowanego obiektu w systemie " +"%s." msgid "" "This key (or subkey) is not protected with a passphrase. Please enter a new " "passphrase to export it." msgstr "" -"Ten klucz (lub podklucz) nie jest zabezpieczony hasłem. Proszę wprowadzić nowe " -"hasło, aby go wyeksportować." +"Ten klucz (lub podklucz) nie jest zabezpieczony hasłem. Proszę wprowadzić " +"nowe hasło, aby go wyeksportować." #, c-format msgid "ssh keys greater than %d bits are not supported\n" @@ -221,8 +222,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Proszę wprowadzić hasło do zabezpieczenia odebranego klucza tajnego%%0A %s" -"%%0A %s%%0Aw miejscu przechowywania kluczy gpg-agenta" +"Proszę wprowadzić hasło do zabezpieczenia odebranego klucza tajnego%%0A " +"%s%%0A %s%%0Aw miejscu przechowywania kluczy gpg-agenta" #, c-format msgid "failed to create stream from socket: %s\n" @@ -714,8 +715,8 @@ msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " "fingerprint:%%0A %s" msgstr "" -"Proszę sprawdzić, że certyfikat zidentyfikowany jako:%%0a „%s”%%0Ama " -"odcisk:%%0A %s" +"Proszę sprawdzić, że certyfikat zidentyfikowany jako:%%0a „%s”%%0Ama odcisk:" +"%%0A %s" #. TRANSLATORS: "Correct" is the label of a button and intended #. to be hit if the fingerprint matches the one of the CA. The @@ -752,8 +753,8 @@ msgstr "Zażądano użycia klucza%%0A %s%%0A %s%%0ACzy zezwolić na to?" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Czy na pewno usunąć klucz identyfikowany przez uchwyt%%0A %s%%0A %%C%%0A?" @@ -1796,14 +1797,14 @@ msgstr "nie można użyć pakietu SKESK ze względu na tryb S2K\n" msgid "using cipher %s.%s\n" msgstr "szyfrem %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "„%s” już jest skompresowany\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "OSTRZEŻENIE: plik „%s” jest pusty\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "„%s” już jest skompresowany\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "algorytm skrótu „%s” nie może być używany w trybie %s\n" @@ -2216,8 +2217,7 @@ msgstr "w definicji grupy „%s” brak znaku „=”\n" #, c-format msgid "WARNING: unsafe ownership on homedir '%s'\n" -msgstr "" -"OSTRZEŻENIE: niebezpieczne prawa własności do katalogu domowego „%s”\n" +msgstr "OSTRZEŻENIE: niebezpieczne prawa własności do katalogu domowego „%s”\n" #, c-format msgid "WARNING: unsafe ownership on configuration file '%s'\n" @@ -2316,7 +2316,8 @@ msgid "show revoked and expired subkeys in key listings" msgstr "pokazywanie unieważnionych i wygasłych podkluczy na listach kluczy" msgid "show signatures with invalid algorithms during signature listings" -msgstr "pokazywanie podpisów z niepoprawnymi algorytmami przy wypisywaniu podpisów" +msgstr "" +"pokazywanie podpisów z niepoprawnymi algorytmami przy wypisywaniu podpisów" msgid "show the keyring name in key listings" msgstr "pokazywanie nazwy zbioru kluczy na listach kluczy" @@ -3536,7 +3537,8 @@ msgstr "Dostępne są podklucze tajne.\n" msgid "" "Note: the local copy of the secret key will only be deleted with \"save\".\n" -msgstr "Uwaga: kopia lokalna klucza tajnego będzie usunięta tylko z \"save\".\n" +msgstr "" +"Uwaga: kopia lokalna klucza tajnego będzie usunięta tylko z \"save\".\n" msgid "Need the secret key to do this.\n" msgstr "Do wykonania tej operacji potrzebny jest klucz tajny.\n" @@ -4483,8 +4485,7 @@ msgstr "tworzenie mimo to\n" #, c-format msgid "Note: Use \"%s %s\" for a full featured key generation dialog.\n" msgstr "" -"Uwaga: pełną funkcjonalność generowania klucza można uzyskać przez „%s " -"%s”.\n" +"Uwaga: pełną funkcjonalność generowania klucza można uzyskać przez „%s %s”.\n" #, c-format msgid "Key generation canceled.\n" @@ -4827,7 +4828,9 @@ msgstr "błąd odszyfrowywania: %s\n" #, c-format msgid "operation forced to fail due to unfulfilled compliance rules\n" -msgstr "wymuszono niepowodzenie operacji ze względu na niespełnione zasady zgodności\n" +msgstr "" +"wymuszono niepowodzenie operacji ze względu na niespełnione zasady " +"zgodności\n" #, c-format msgid "Note: sender requested \"for-your-eyes-only\"\n" @@ -4839,8 +4842,7 @@ msgstr "pierwotna nazwa pliku='%.*s'\n" #, c-format msgid "standalone revocation - use \"gpg --import\" to apply\n" -msgstr "" -"osobny certyfikat unieważnienia - użyj „gpg --import” aby go wczytać\n" +msgstr "osobny certyfikat unieważnienia - użyj „gpg --import” aby go wczytać\n" #, c-format msgid "no signature found\n" @@ -5020,15 +5022,13 @@ msgstr "" #, c-format msgid "%s:%u: \"%s\" is obsolete in this file - it only has effect in %s\n" -msgstr "" -"%s:%u: „%s” jest przestarzałe w tym pliku - ma znaczenie tylko w %s\n" +msgstr "%s:%u: „%s” jest przestarzałe w tym pliku - ma znaczenie tylko w %s\n" #, c-format msgid "" "WARNING: \"%s%s\" is an obsolete option - it has no effect except on %s\n" msgstr "" -"OSTRZEŻENIE: „%s%s” jest przestarzałą opcją - nie ma efektu z wyjątkiem " -"%s\n" +"OSTRZEŻENIE: „%s%s” jest przestarzałą opcją - nie ma efektu z wyjątkiem %s\n" msgid "Uncompressed" msgstr "Nieskompresowany" @@ -5132,7 +5132,8 @@ msgid "Do you really want to permanently delete the OpenPGP secret key:" msgstr "Czy na pewno trwale usunąć klucz prywatny OpenPGP:" msgid "Please enter the passphrase to export the secret key with keygrip:" -msgstr "Proszę wprowadzić hasło do wyeksportowania klucza prywatnego z uchwytem:" +msgstr "" +"Proszę wprowadzić hasło do wyeksportowania klucza prywatnego z uchwytem:" #, c-format msgid "" @@ -5381,7 +5382,9 @@ msgstr "Uwaga: Data ważności tego klucza upłynęła!\n" #, c-format msgid "WARNING: The key's User ID is not certified with a trusted signature!\n" -msgstr "OSTRZEŻENIE: Identyfikator użytkownika tego klucza nie jest poświadczony zaufanym podpisem!\n" +msgstr "" +"OSTRZEŻENIE: Identyfikator użytkownika tego klucza nie jest poświadczony " +"zaufanym podpisem!\n" #, c-format msgid "WARNING: This key is not certified with a trusted signature!\n" @@ -6066,8 +6069,7 @@ msgstr[2] "Adres e-mail „%s” jest powiązany z %d kluczami!" msgid " Since this binding's policy was 'auto', it has been changed to 'ask'." msgstr "" -" Ponieważ polityką tego powiązania było „auto”, została zmieniona na „" -"ask”." +" Ponieważ polityką tego powiązania było „auto”, została zmieniona na „ask”." #, c-format msgid "" @@ -7862,8 +7864,7 @@ msgstr "nieprawidłowy znacznik czasu w „%s”, linia %u\n" #, c-format msgid "WARNING: invalid cache file hash in '%s' line %u\n" -msgstr "" -"UWAGA: nieprawidłowy skrót pliku pamięci podręcznej w „%s”, linia %u\n" +msgstr "UWAGA: nieprawidłowy skrót pliku pamięci podręcznej w „%s”, linia %u\n" #, c-format msgid "detected errors in cache dir file\n" @@ -7876,8 +7877,8 @@ msgstr "proszę sprawdzić przyczynę i ręcznie usunąć ten plik\n" #, c-format msgid "failed to create temporary cache dir file '%s': %s\n" msgstr "" -"nie udało się utworzyć pliku tymczasowego katalogu pamięci podręcznej „" -"%s”: %s\n" +"nie udało się utworzyć pliku tymczasowego katalogu pamięci podręcznej „%s”: " +"%s\n" #, c-format msgid "error renaming '%s' to '%s': %s\n" @@ -9046,6 +9047,9 @@ msgstr "dodanie certyfikatu do pamięci podręcznej" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" diff --git a/po/pt.po b/po/pt.po index cf440b3a3..c0b052b2e 100644 --- a/po/pt.po +++ b/po/pt.po @@ -881,8 +881,28 @@ msgid "waiting for process %d to terminate failed: %s\n" msgstr "falha ao aguardar pelo encerramento do processo %d: %s\n" #, c-format -msgid "waiting for process to terminate failed: ec=%d\n" -msgstr "falha ao esperar que o processo terminasse: ec=%d\n" +msgid "error running '%s': probably not installed\n" +msgstr "" + +#, fuzzy, c-format +#| msgid "error accessing '%s': http status %u\n" +msgid "error running '%s': exit status %d\n" +msgstr "erro ao aceder '%s': status http %u\n" + +#, fuzzy, c-format +#| msgid "error opening '%s': %s\n" +msgid "error running '%s': terminated\n" +msgstr "erro ao abrir '%s': %s\n" + +#, fuzzy, c-format +#| msgid "waiting for process %d to terminate failed: %s\n" +msgid "waiting for processes to terminate failed: %s\n" +msgstr "falha ao aguardar pelo encerramento do processo %d: %s\n" + +#, fuzzy, c-format +#| msgid "error getting list of cards: %s\n" +msgid "error getting exit code of process %d: %s\n" +msgstr "erro ao obter a lista de cartões: %s\n" #, c-format msgid "can't connect to '%s': %s\n" @@ -8968,8 +8988,15 @@ msgstr "armazenar um certificado em um objeto de dados" msgid "store a private key to a data object" msgstr "armazenar uma chave privada em um objeto de dados" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "comandos de gerir uma Yubikey" msgid "manage the command history" msgstr "gerir o histórico de comandos" + +#, c-format +#~ msgid "waiting for process to terminate failed: ec=%d\n" +#~ msgstr "falha ao esperar que o processo terminasse: ec=%d\n" diff --git a/po/ro.po b/po/ro.po index ab6fe8396..c7b55e2f1 100644 --- a/po/ro.po +++ b/po/ro.po @@ -792,8 +792,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Doriţi într-adevăr să ştergeţi cheile selectate? (d/N) " #, fuzzy @@ -1908,16 +1908,16 @@ msgstr "nu pot crea un pachet ESK simetric datorită modului S2K\n" msgid "using cipher %s.%s\n" msgstr "folosesc cifrul %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' deja compresat\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "AVERTISMENT: `%s' este un fişier gol\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' deja compresat\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm `%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -2449,8 +2449,8 @@ msgstr "" #, fuzzy, c-format #| msgid "" -#| "WARNING: unsafe enclosing directory permissions on configuration file `" -#| "%s'\n" +#| "WARNING: unsafe enclosing directory permissions on configuration file " +#| "`%s'\n" msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" @@ -3236,8 +3236,8 @@ msgstr "cheia %s: nici un ID utilizator pentru semnătură\n" #, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"cheia %s: algoritm cu cheie publică nesuportat pentru ID-ul utilizator \"%s" -"\"\n" +"cheia %s: algoritm cu cheie publică nesuportat pentru ID-ul utilizator " +"\"%s\"\n" #, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" @@ -9406,6 +9406,9 @@ msgstr "Certificat de revocare creat.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10620,8 +10623,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -11539,8 +11542,8 @@ msgstr "" #~ "crea\n" #~ "o cheie sigură pentru semnături: acest program face acest lucru, dar " #~ "alte\n" -#~ "implementări OpenPGP ar putea să nu înţeleagă varianta de semnare" -#~ "+cifrare.\n" +#~ "implementări OpenPGP ar putea să nu înţeleagă varianta de " +#~ "semnare+cifrare.\n" #~ "\n" #~ "Prima cheie (primară) trebuie să fie întotdeauna capabilă de semnare;\n" #~ "acesta este motivul pentru care cheia ElGamal nu este disponibilă în\n" diff --git a/po/ru.po b/po/ru.po index a144acd53..47b9e3b56 100644 --- a/po/ru.po +++ b/po/ru.po @@ -18,8 +18,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" #, c-format msgid "failed to acquire the pinentry lock: %s\n" @@ -328,8 +328,8 @@ msgstr[2] "" #, c-format msgid "A passphrase may not be a known term or match%%0Acertain pattern." msgstr "" -"Фраза-пароль не должна быть известным выражением и не должна быть составлена" -"%%0Aпо определенному образцу." +"Фраза-пароль не должна быть известным выражением и не должна быть " +"составлена%%0Aпо определенному образцу." msgid "Warning: You have entered an insecure passphrase." msgstr "Внимание: Вы ввели небезопасную фразу-пароль." @@ -786,8 +786,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Вы действительно хотите удалить ключ с кодом%%0A %s%%0A %%C%%0A?" msgid "Delete key" @@ -1843,14 +1843,14 @@ msgstr "не могу использовать симметричный паке msgid "using cipher %s.%s\n" msgstr "используется симметричный шифр %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' уже сжат\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "Внимание: файл '%s' пуст\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' уже сжат\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "хеш-функцию '%s' нельзя использовать в режиме %s\n" @@ -9147,6 +9147,9 @@ msgstr "добавить сертификат в буфер" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -9617,8 +9620,8 @@ msgstr "" #~ msgid "error setting policy for key %s, user id \"%s\": %s" #~ msgstr "" -#~ "ошибка установки правил для ключа %s с идентификатором пользователя \"%s" -#~ "\": %s" +#~ "ошибка установки правил для ключа %s с идентификатором пользователя " +#~ "\"%s\": %s" #~ msgid "only SHA-1 is supported for OCSP responses\n" #~ msgstr "для ответов OCSP поддерживается только SHA-1\n" diff --git a/po/sk.po b/po/sk.po index e730decf0..638bc8955 100644 --- a/po/sk.po +++ b/po/sk.po @@ -779,8 +779,8 @@ msgstr "" #, fuzzy, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Skutočne chcete zmazať vybrané kľúče? " #, fuzzy @@ -1886,16 +1886,16 @@ msgstr "v móde S2K nemožno použiť symetrický ESK paket\n" msgid "using cipher %s.%s\n" msgstr "použitá šifra %s\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "`%s' je už skomprimovaný\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "VAROVANIE: súbor `%s' je prázdny\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "`%s' je už skomprimovaný\n" + #, fuzzy, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "nemôžete použiť hashovací algoritmus \"%s\" v móde %s\n" @@ -3180,8 +3180,8 @@ msgstr "kľúč %08lX: neexistuje id užívateľa pre podpis\n" #, fuzzy, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" -"kľúč %08lX: nepodporovaný algoritmus verejného kľúča u užívateľského id \"%s" -"\"\n" +"kľúč %08lX: nepodporovaný algoritmus verejného kľúča u užívateľského id " +"\"%s\"\n" #, fuzzy, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" @@ -9295,6 +9295,9 @@ msgstr "Revokačný certifikát bol vytvorený.\n" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -10452,8 +10455,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." @@ -10496,8 +10499,8 @@ msgstr "" #, fuzzy #~ msgid "Answer \"yes\" if you want to sign ALL the user IDs" #~ msgstr "" -#~ "Pokiaľ chcete podpísať VŠETKY identifikátory užívateľov, odpovedzte \"ano" -#~ "\"" +#~ "Pokiaľ chcete podpísať VŠETKY identifikátory užívateľov, odpovedzte " +#~ "\"ano\"" #~ msgid "" #~ "Answer \"yes\" if you really want to delete this user ID.\n" diff --git a/po/sv.po b/po/sv.po index 5fcf6532c..0e6951f81 100644 --- a/po/sv.po +++ b/po/sv.po @@ -881,8 +881,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "Vill du verkligen ta bort de valda nycklarna? (j/N) " #, fuzzy @@ -2026,16 +2026,16 @@ msgstr "kan inte använda symmetriska ESK-paket pga S2K-läge\n" msgid "using cipher %s.%s\n" msgstr "använder %s-chiffer\n" -#, fuzzy, c-format -#| msgid "`%s' already compressed\n" -msgid "'%s' already compressed\n" -msgstr "\"%s\" är redan komprimerad\n" - #, fuzzy, c-format #| msgid "WARNING: `%s' is an empty file\n" msgid "WARNING: '%s' is an empty file\n" msgstr "VARNING: \"%s\" är en tom fil\n" +#, fuzzy, c-format +#| msgid "`%s' already compressed\n" +msgid "'%s' already compressed\n" +msgstr "\"%s\" är redan komprimerad\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm `%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -2570,8 +2570,8 @@ msgstr "" #, fuzzy, c-format #| msgid "" -#| "WARNING: unsafe enclosing directory permissions on configuration file `" -#| "%s'\n" +#| "WARNING: unsafe enclosing directory permissions on configuration file " +#| "`%s'\n" msgid "" "WARNING: unsafe enclosing directory permissions on configuration file '%s'\n" msgstr "" @@ -9851,6 +9851,9 @@ msgstr " (certifikat skapat " msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" @@ -11212,8 +11215,8 @@ msgstr "" #~ "\n" #~ "Note that the examples given above for levels 2 and 3 are *only* " #~ "examples.\n" -#~ "In the end, it is up to you to decide just what \"casual\" and \"extensive" -#~ "\"\n" +#~ "In the end, it is up to you to decide just what \"casual\" and " +#~ "\"extensive\"\n" #~ "mean to you when you sign other keys.\n" #~ "\n" #~ "If you don't know what the right answer is, answer \"0\"." diff --git a/po/tr.po b/po/tr.po index 27f15bc61..95aa0aef5 100644 --- a/po/tr.po +++ b/po/tr.po @@ -762,8 +762,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "%%0A %s%%0A %%C%%0A anahtar maşası tarafından tanımlanan anahtarı silmek " "istediğnizden emin misiniz?" @@ -1799,14 +1799,14 @@ msgstr "S2K kipi nedeniyle bir SKESK paketi kullanılamıyor\n" msgid "using cipher %s.%s\n" msgstr "%s.%s şifrelemesi kullanılıyor\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' halihazırda sıkıştırılmış\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "UYARI: '%s', boş bir dosya\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' halihazırda sıkıştırılmış\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "özet algoritması '%s', %s kipinde kullanılamayabilir\n" @@ -8910,6 +8910,9 @@ msgstr "bir veri nesnesine bir sertifika depola" msgid "store a private key to a data object" msgstr "bir veri nesnesine bir özel anahtar depola" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Yubikey yönetim konsolu" diff --git a/po/uk.po b/po/uk.po index c3e927947..3f5bfedba 100644 --- a/po/uk.po +++ b/po/uk.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11) ? 0 : ((n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20)) ? 1 : 2);\n" "X-Generator: Lokalize 20.11.70\n" #, c-format @@ -235,8 +235,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"Будь ласка, вкажіть пароль для захисту отриманого закритого ключа%%0A %s" -"%%0A %s%%0Aу сховищі ключів gpg-agent" +"Будь ласка, вкажіть пароль для захисту отриманого закритого ключа%%0A " +"%s%%0A %s%%0Aу сховищі ключів gpg-agent" #, c-format msgid "failed to create stream from socket: %s\n" @@ -787,8 +787,8 @@ msgstr "" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "Справді хочете вилучити ключ, що визначається keygrip%%0A %s%%0A %%C%%0A?" @@ -1860,14 +1860,14 @@ msgstr "не можна використовувати симетричний п msgid "using cipher %s.%s\n" msgstr "використано шифр %s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "«%s» вже стиснено\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "УВАГА: файл «%s» є порожнім\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "«%s» вже стиснено\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "" @@ -9240,6 +9240,9 @@ msgstr "додати сертифікат до кешу" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" diff --git a/po/zh_CN.po b/po/zh_CN.po index ef737a37d..f48fdec84 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -221,8 +221,8 @@ msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%0A " "%s%%0Awithin gpg-agent's key storage" msgstr "" -"请输入一个密码,以便于在 gpg-agent 的密钥存储中保护接收到的私钥 %%0A %s" -"%%0A %s%%0A" +"请输入一个密码,以便于在 gpg-agent 的密钥存储中保护接收到的私钥 %%0A " +"%s%%0A %s%%0A" #, c-format msgid "failed to create stream from socket: %s\n" @@ -742,8 +742,8 @@ msgstr "请求使用密钥%%0A %s%%0A %s%%0A您想要允许这一请求吗?" #, c-format msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "" "您真的想要删除这个被以下的 keygrip 所标识的密钥吗 %%0A %s%%0A %%C%%0A?" @@ -1774,14 +1774,14 @@ msgstr "由于在 S2K 模式,不能使用一个对称的 ESK 封包\n" msgid "using cipher %s.%s\n" msgstr "使用加密 %s.%s\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "‘%s’已被压缩\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "警告:‘%s’是一个空文件\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "‘%s’已被压缩\n" + #, c-format msgid "digest algorithm '%s' may not be used in %s mode\n" msgstr "摘要算法‘%s’不能在 %s 模式下使用\n" @@ -8666,6 +8666,9 @@ msgstr "储存一个证书到数据对象" msgid "store a private key to a data object" msgstr "储存私钥到数据对象" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "Yubikey 管理命令" diff --git a/po/zh_TW.po b/po/zh_TW.po index 4cb6f64bb..aa5a1125e 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -783,8 +783,8 @@ msgstr "" #, fuzzy, c-format #| msgid "Do you really want to delete the selected keys? (y/N) " msgid "" -"Do you really want to delete the key identified by keygrip%%0A %s%%0A %%C" -"%%0A?" +"Do you really want to delete the key identified by keygrip%%0A %s%%0A " +"%%C%%0A?" msgstr "你真的想要刪除所選的金鑰嗎? (y/N) " msgid "Delete key" @@ -1868,14 +1868,14 @@ msgstr "因處於 S2K 模式下而無法使用對稱式 ESK 封包\n" msgid "using cipher %s.%s\n" msgstr "正在使用 %s 編密法\n" -#, c-format -msgid "'%s' already compressed\n" -msgstr "'%s' 已經被壓縮了\n" - #, c-format msgid "WARNING: '%s' is an empty file\n" msgstr "警告: '%s' 是個空檔案\n" +#, c-format +msgid "'%s' already compressed\n" +msgstr "'%s' 已經被壓縮了\n" + #, fuzzy, c-format #| msgid "you may not use digest algorithm '%s' while in %s mode\n" msgid "digest algorithm '%s' may not be used in %s mode\n" @@ -9048,6 +9048,9 @@ msgstr "加入憑證至快取" msgid "store a private key to a data object" msgstr "" +msgid "run various checks on the keys" +msgstr "" + msgid "Yubikey management commands" msgstr "" From a43271cc08e2068acc75a1742f90740afe0479e0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Jan 2024 11:04:33 +0100 Subject: [PATCH 340/869] Release 2.4.4 --- NEWS | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 4e2d84d67..7ed00a015 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ -Noteworthy changes in version 2.4.4 (unreleased) +Noteworthy changes in version 2.4.4 (2024-01-25) ------------------------------------------------ + * gpg: Do not keep an unprotected smartcard backup key on disk. See + https://gnupg.org/blog/20240125-smartcard-backup-key.html for a + security advisory. [T6944] + * gpg: Allow to specify seconds since Epoch beyond 2038 on 32-bit platforms. [T6736] @@ -10,11 +14,14 @@ Noteworthy changes in version 2.4.4 (unreleased) * gpg: Add option --with-v5-fingerprint. [T6705] - * gpg: Fix validity of re-imported keys. [T6399] + * gpg: Add sub-option ignore-attributes to --import-options. + [rGd4976e35d2] * gpg: Add --list-filter properties sig_expires/sig_expires_d. [rGbf662d0f93af] + * gpg: Fix validity of re-imported keys. [T6399] + * gpg: Report BEGIN_ status before examining the input. [T6481] * gpg: Don't try to compress a read-only keybox. [T6811] From 367ae86019063ca0af74aea556414aff44693bea Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Jan 2024 11:30:37 +0100 Subject: [PATCH 341/869] Post release updates -- --- NEWS | 7 +++++++ configure.ac | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 7ed00a015..26228b242 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +Noteworthy changes in version 2.4.5 (unreleased) +------------------------------------------------ + + + Release-info: https://dev.gnupg.org/T6960 + + Noteworthy changes in version 2.4.4 (2024-01-25) ------------------------------------------------ diff --git a/configure.ac b/configure.ac index 26d7f7b55..ac4f08c12 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ min_automake_version="1.16.3" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [4]) -m4_define([mym4_micro], [4]) +m4_define([mym4_micro], [5]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release From af6ac2ac0293a1863503a2c05cfc2192b8d2f804 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 26 Jan 2024 14:13:01 +0900 Subject: [PATCH 342/869] gpg: Clean up pk_ecdh_decrypt function. * g10/ecdh.c (pk_ecdh_decrypt): Allocate just the right size of memory for the session key, simplifying the decrypt process. -- Signed-off-by: NIIBE Yutaka --- g10/ecdh.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/g10/ecdh.c b/g10/ecdh.c index eb14154a1..dbce846b9 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -524,8 +524,7 @@ pk_ecdh_decrypt (gcry_mpi_t *r_result, const byte sk_fp[MAX_FINGERPRINT_LEN], size_t nbytes; byte *data_buf; int data_buf_size; - byte *in; - const void *p; + const unsigned char *p; unsigned int nbits; *r_result = NULL; @@ -546,7 +545,10 @@ pk_ecdh_decrypt (gcry_mpi_t *r_result, const byte sk_fp[MAX_FINGERPRINT_LEN], return gpg_error (GPG_ERR_BAD_DATA); } - data_buf = xtrymalloc_secure( 1 + 2*data_buf_size + 8); + /* The first octet is for length. It's longer than the result + because of one additional block of AESWRAP. */ + data_buf_size -= 1 + 8; + data_buf = xtrymalloc_secure (data_buf_size); if (!data_buf) { err = gpg_error_from_syserror (); @@ -560,22 +562,18 @@ pk_ecdh_decrypt (gcry_mpi_t *r_result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_cipher_close (hd); return gpg_error (GPG_ERR_BAD_MPI); } - memcpy (data_buf, p, nbytes); - if (data_buf[0] != nbytes-1) + if (p[0] != nbytes-1) { log_error ("ecdh inconsistent size\n"); xfree (data_buf); gcry_cipher_close (hd); return gpg_error (GPG_ERR_BAD_MPI); } - in = data_buf+data_buf_size; - data_buf_size = data_buf[0]; if (DBG_CRYPTO) - log_printhex (data_buf+1, data_buf_size, "ecdh decrypting :"); + log_printhex (p+1, nbytes-1, "ecdh decrypting :"); - err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, - data_buf_size); + err = gcry_cipher_decrypt (hd, data_buf, data_buf_size, p+1, nbytes-1); gcry_cipher_close (hd); if (err) { @@ -585,10 +583,8 @@ pk_ecdh_decrypt (gcry_mpi_t *r_result, const byte sk_fp[MAX_FINGERPRINT_LEN], return err; } - data_buf_size -= 8; - if (DBG_CRYPTO) - log_printhex (in, data_buf_size, "ecdh decrypted to :"); + log_printhex (data_buf, data_buf_size, "ecdh decrypted to :"); /* Padding is removed later. */ /* if (in[data_buf_size-1] > 8 ) */ @@ -598,7 +594,8 @@ pk_ecdh_decrypt (gcry_mpi_t *r_result, const byte sk_fp[MAX_FINGERPRINT_LEN], /* return gpg_error (GPG_ERR_BAD_KEY); */ /* } */ - err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); + err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, data_buf, + data_buf_size, NULL); xfree (data_buf); if (err) { From eaf6a7ab8796a7128fc64516eac4351717a5b2f7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 Jan 2024 10:27:40 +0100 Subject: [PATCH 343/869] common,w32: Fix use of GNUPG_SPAWN_KEEP_STDERR. * common/exechelp-w32.c (gnupg_spawn_process): Fix macro. -- Fixes-commit: 6d6438a361d25f3b269f702e017f5e39fd1f5c38 GnuPG-bug-id: 6961 --- common/exechelp-w32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 0034e03f2..2093f0d8b 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -561,7 +561,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], nullhd[1] = ((flags & GNUPG_SPAWN_KEEP_STDOUT)? GetStdHandle (STD_OUTPUT_HANDLE) : w32_open_null (1)); if (errpipe[1] == INVALID_HANDLE_VALUE) - nullhd[2] = ((flags & GNUPG_SPAWN_KEEP_STDOUT)? + nullhd[2] = ((flags & GNUPG_SPAWN_KEEP_STDERR)? GetStdHandle (STD_ERROR_HANDLE) : w32_open_null (1)); memset (&si, 0, sizeof si); From 4dc09bc5e7f349948a0bb68bdacfdbbc221a2b45 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 Jan 2024 13:14:14 +0100 Subject: [PATCH 344/869] dirmngr: For CRL issuer verification trust the system's root CA. * dirmngr/crlcache.c (crl_parse_insert): Add VALIDATE_FLAG_TRUST_SYSTEM. -- GnuPG-bug-id: 6963 --- dirmngr/crlcache.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index ac673a8d5..d3fe5c272 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -2086,6 +2086,7 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl, err = validate_cert_chain (ctrl, crlissuer_cert, NULL, (VALIDATE_FLAG_TRUST_CONFIG + | VALIDATE_FLAG_TRUST_SYSTEM | VALIDATE_FLAG_CRL | VALIDATE_FLAG_RECURSIVE), r_trust_anchor); From 97b283765353d885ab21e160d5675c6d7eacc46a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 Jan 2024 16:01:06 +0100 Subject: [PATCH 345/869] speedo: Improve parsing of the ~./.gnupg-autogen.rc -- We now allow spaces around the variable name and the value. --- Makefile.am | 10 ++++++---- build-aux/speedo.mk | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile.am b/Makefile.am index 67ee98e20..1b6933484 100644 --- a/Makefile.am +++ b/Makefile.am @@ -247,8 +247,8 @@ release: mkopt=""; \ if [ -n "$$CUSTOM_SWDB" ]; then \ mkopt="CUSTOM_SWB=1"; \ - x=$$(grep '^OVERRIDE_TARBALLS=' \ - $$HOME/.gnupg-autogen.rc|cut -d= -f2);\ + x=$$(grep '^[[:blank:]]*OVERRIDE_TARBALLS[[:blank:]]*=' \ + $$HOME/.gnupg-autogen.rc|cut -d= -f2|xargs);\ if [ -f "$$x/swdb.lst" ]; then \ echo "/* Copying swdb.lst from the overrides directory */"; \ cp "$$x/swdb.lst" . ; \ @@ -275,13 +275,15 @@ release: sign-release: +(set -e; \ test $$(pwd | sed 's,.*/,,') = dist || cd dist; \ - x=$$(grep '^RELEASE_ARCHIVE=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\ + x=$$(grep '^[[:blank:]]*RELEASE_ARCHIVE[[:blank:]]*=' \ + $$HOME/.gnupg-autogen.rc|cut -d= -f2|xargs);\ if [ -z "$$x" ]; then \ echo "error: RELEASE_ARCHIVE missing in ~/.gnupg-autogen.rc">&2; \ exit 2;\ fi;\ myarchive="$$x/$(RELEASE_ARCHIVE_SUFFIX)";\ - x=$$(grep '^RELEASE_SIGNKEY=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\ + x=$$(grep '^[[:blank:]]*RELEASE_SIGNKEY[[:blank:]]*=' \ + $$HOME/.gnupg-autogen.rc|cut -d= -f2|xargs);\ if [ -z "$$x" ]; then \ echo "error: RELEASE_SIGNKEY missing in ~/.gnupg-autogen.rc">&2; \ exit 2;\ diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 477873f60..d69556472 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -238,7 +238,7 @@ PATCHELF := $(shell patchelf --version 2>/dev/null >/dev/null || echo "echo plea # Read signing information from ~/.gnupg-autogen.rc define READ_AUTOGEN_template -$(1) = $$(shell grep '^$(1)=' $$$$HOME/.gnupg-autogen.rc|cut -d= -f2) +$(1) = $$(shell grep '^[[:blank:]]*$(1)[[:blank:]]*=' $$$$HOME/.gnupg-autogen.rc|cut -d= -f2|xargs) endef $(eval $(call READ_AUTOGEN_template,AUTHENTICODE_SIGNHOST)) $(eval $(call READ_AUTOGEN_template,AUTHENTICODE_TOOL)) From 2ed1f68b48db7b5503045386de0500fddf70077e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 29 Jan 2024 09:16:21 +0100 Subject: [PATCH 346/869] doc: Fix spelling errors found by lintian. -- Reported-by: Andreas Metzler --- NEWS | 14 +++++++------- common/compliance.c | 2 +- common/tlv.c | 2 +- dirmngr/dirmngr_ldap.c | 2 +- dirmngr/http.c | 4 ++-- dirmngr/ks-engine-ldap.c | 2 +- dirmngr/server.c | 2 +- doc/dirmngr.texi | 2 +- doc/gpg-agent.texi | 6 +++--- doc/gpg-card.texi | 2 +- doc/gpg.texi | 16 ++++++++-------- doc/gpgsm.texi | 2 +- doc/scdaemon.texi | 2 +- doc/tools.texi | 2 +- g10/getkey.c | 2 +- g10/mainproc.c | 2 +- scd/app-nks.c | 2 +- tests/openpgp/README | 2 +- tools/gpg-card.c | 2 +- tools/watchgnupg.c | 2 +- 20 files changed, 36 insertions(+), 36 deletions(-) diff --git a/NEWS b/NEWS index 26228b242..f800e3dab 100644 --- a/NEWS +++ b/NEWS @@ -1398,7 +1398,7 @@ Noteworthy changes in version 2.3.0 (2021-04-07) Changes also found in 2.2.12: * tools: New commands --install-key and --remove-key for - gpg-wks-client. This allows to prepare a Web Key Directory on a + gpg-wks-client. This allows one to prepare a Web Key Directory on a local file system for later upload to a web server. * gpg: New --list-option "show-only-fpr-mbox". This makes the use @@ -1442,7 +1442,7 @@ Noteworthy changes in version 2.3.0 (2021-04-07) query. * gpg: Do not store the TOFU trust model in the trustdb. This - allows to enable or disable a TOFO model without triggering a + allows one to enable or disable a TOFO model without triggering a trustdb rebuild. [#4134] * scd: Fix cases of "Bad PIN" after using "forcesig". [#4177] @@ -1861,7 +1861,7 @@ Noteworthy changes in version 2.1.23 (2017-08-09) to your gpg.conf. * agent: Option --no-grab is now the default. The new option --grab - allows to revert this. + allows one to revert this. * gpg: New import option "show-only". @@ -2991,7 +2991,7 @@ Noteworthy changes in version 2.1.0 (2014-11-06) * gpg: Allow use of Brainpool curves. * gpg: Accepts a space separated fingerprint as user ID. This - allows to copy and paste the fingerprint from the key listing. + allows one to copy and paste the fingerprint from the key listing. * gpg: The hash algorithm is now printed for signature records in key listings. @@ -3771,7 +3771,7 @@ Noteworthy changes in version 1.9.10 (2004-07-22) * Fixed a serious bug in the checking of trusted root certificates. - * New configure option --enable-agent-pnly allows to build and + * New configure option --enable-agent-only allows one to build and install just the agent. * Fixed a problem with the log file handling. @@ -4166,7 +4166,7 @@ Noteworthy changes in version 1.1.92 (2002-09-11) extension specified with --load-extension are checked, along with their enclosing directories. - * The configure option --with-static-rnd=auto allows to build gpg + * The configure option --with-static-rnd=auto allows one to build gpg with all available entropy gathering modules included. At runtime the best usable one will be selected from the list linux, egd, unix. This is also the default for systems lacking @@ -4549,7 +4549,7 @@ Noteworthy changes in version 1.0.2 (2000-07-12) * New command --export-secret-subkeys which outputs the the _primary_ key with it's secret parts deleted. This is useful for automated decryption/signature creation as it - allows to keep the real secret primary key offline and + allows one to keep the real secret primary key offline and thereby protecting the key certificates and allowing to create revocations for the subkeys. See the FAQ for a procedure to install such secret keys. diff --git a/common/compliance.c b/common/compliance.c index 04978ed1b..84449af25 100644 --- a/common/compliance.c +++ b/common/compliance.c @@ -41,7 +41,7 @@ static int initialized; static int module; /* This value is used by DSA and RSA checks in addition to the hard - * coded length checks. It allows to increase the required key length + * coded length checks. It allows one to increase the required key length * using a confue file. */ static unsigned int min_compliant_rsa_length; diff --git a/common/tlv.c b/common/tlv.c index 4ba9ef20d..c77f4cc4f 100644 --- a/common/tlv.c +++ b/common/tlv.c @@ -152,7 +152,7 @@ find_tlv_unchecked (const unsigned char *buffer, size_t length, /* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag * and the length part from the TLV triplet. Update BUFFER and SIZE * on success. Note that this function does not check that the value - * fits into the provided buffer; this allows to work on the TL part + * fits into the provided buffer; this allows one to work on the TL part * of a TLV. */ gpg_error_t parse_ber_header (unsigned char const **buffer, size_t *size, diff --git a/dirmngr/dirmngr_ldap.c b/dirmngr/dirmngr_ldap.c index 412d0ad1f..d999ee87e 100644 --- a/dirmngr/dirmngr_ldap.c +++ b/dirmngr/dirmngr_ldap.c @@ -107,7 +107,7 @@ static gpgrt_opt_t opts[] = { " a record oriented format"}, { oProxy, "proxy", 2, "|NAME|ignore host part and connect through NAME"}, - { oStartTLS, "starttls", 0, "use STARTLS for the conenction"}, + { oStartTLS, "starttls", 0, "use STARTLS for the connection"}, { oLdapTLS, "ldaptls", 0, "use a TLS for the connection"}, { oNtds, "ntds", 0, "authenticate using AD"}, { oARecOnly, "areconly", 0, "do only an A record lookup"}, diff --git a/dirmngr/http.c b/dirmngr/http.c index 4899a5d55..a6892479e 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2882,7 +2882,7 @@ send_request (ctrl_t ctrl, if (proxy && proxy->is_http_proxy) { - use_http_proxy = 1; /* We want to use a proxy for the conenction. */ + use_http_proxy = 1; /* We want to use a proxy for the connection. */ err = connect_server (ctrl, *proxy->uri->host ? proxy->uri->host : "localhost", proxy->uri->port ? proxy->uri->port : 80, @@ -4411,7 +4411,7 @@ same_host_p (parsed_uri_t a, parsed_uri_t b) } /* Also consider hosts the same if they differ only in a subdomain; - * in both direction. This allows to have redirection between the + * in both direction. This allows one to have redirection between the * WKD advanced and direct lookup methods. */ for (i=0; i < DIM (subdomains); i++) { diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index c2a210542..749c0de09 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -605,7 +605,7 @@ interrogate_ldap_dn (LDAP *ldap_conn, const char *basedn_search, * including whether to use TLS and the username and password (see * ldap_parse_uri for a description of the various fields). Be * default a PGP keyserver is assumed; if GENERIC is true a generic - * ldap conenction is instead established. + * ldap connection is instead established. * * Returns: The ldap connection handle in *LDAP_CONNP, R_BASEDN is set * to the base DN for the PGP key space, several flags will be stored diff --git a/dirmngr/server.c b/dirmngr/server.c index 1dbc87878..32c85d07b 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -3325,7 +3325,7 @@ dirmngr_status_help (ctrl_t ctrl, const char *text) /* Print a help status line using a printf like format. The function - * splits text at LFs. With CTRL beeing NULL, the function behaves + * splits text at LFs. With CTRL being NULL, the function behaves * like log_info. */ gpg_error_t dirmngr_status_helpf (ctrl_t ctrl, const char *format, ...) diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index cd7969828..e50406035 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -172,7 +172,7 @@ socket. Set compatibility flags to work around certain problems or to emulate bugs. The @var{flags} are given as a comma separated list of flag names and are OR-ed together. The special flag "none" clears the list -and allows to start over with an empty list. To get a list of +and allows one to start over with an empty list. To get a list of available flags the sole word "help" can be used. @item --faked-system-time @var{epoch} diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 49cf16e39..74c4c10af 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -302,7 +302,7 @@ debugging. @item --steal-socket @opindex steal-socket In @option{--daemon} mode, gpg-agent detects an already running -gpg-agent and does not allow to start a new instance. This option can +gpg-agent and does not allow one to start a new instance. This option can be used to override this check: the new gpg-agent process will try to take over the communication sockets from the already running process and start anyway. This option should in general not be used. @@ -643,7 +643,7 @@ gpg-agent as a replacement for PuTTY's Pageant, the option In this mode of operation, the agent does not only implement the gpg-agent protocol, but also the agent protocol used by OpenSSH (through a separate socket or via Named Pipes) or the protocol used by -PuTTY. Consequently, this allows to use the gpg-agent as a drop-in +PuTTY. Consequently, this allows one to use the gpg-agent as a drop-in replacement for the ssh-agent. SSH keys, which are to be used through the agent, need to be added to @@ -693,7 +693,7 @@ The order in which keys are presented to ssh are: @item Negative Use-for-ssh values If a key file has the attribute "Use-for-ssh" and its value is negative, these keys are presented first to ssh. The negative - values are capped at -999 with -999 beeing lower ranked than -1. + values are capped at -999 with -999 being lower ranked than -1. These values can be used to prefer on-disk keys over keys taken from active cards. diff --git a/doc/gpg-card.texi b/doc/gpg-card.texi index 8787793f8..3a659e80f 100644 --- a/doc/gpg-card.texi +++ b/doc/gpg-card.texi @@ -226,7 +226,7 @@ OpenPGP or X.509 keys. @item LOGIN [--clear] [< @var{file}] @opindex login Set the login data object of OpenPGP cards. If @var{file} is given -the data is is read from that file. This allows to store binary data +the data is is read from that file. This allows one to store binary data in the login field. The option @option{--clear} deletes the login data object. diff --git a/doc/gpg.texi b/doc/gpg.texi index 1bc2bd9e4..9c1721500 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -716,7 +716,7 @@ inserted smartcard, the special string ``card'' can be used for will figure them out and creates an OpenPGP key consisting of the usual primary key and one subkey. This works only with certain smartcards. Note that the interactive @option{--full-gen-key} command -allows to do the same but with greater flexibility in the selection of +allows one to do the same but with greater flexibility in the selection of the smartcard keys. Note that it is possible to create a primary key and a subkey using @@ -1947,20 +1947,20 @@ list. The default is "local,wkd". @item ntds Locate the key using the Active Directory (Windows only). This - method also allows to search by fingerprint using the command + method also allows one to search by fingerprint using the command @option{--locate-external-key}. Note that this mechanism is actually a shortcut for the mechanism @samp{keyserver} but using "ldap:///" as the keyserver. @item keyserver - Locate a key using a keyserver. This method also allows to search + Locate a key using a keyserver. This method also allows one to search by fingerprint using the command @option{--locate-external-key} if any of the configured keyservers is an LDAP server. @item keyserver-URL In addition, a keyserver URL as used in the @command{dirmngr} configuration may be used here to query that particular keyserver. - This method also allows to search by fingerprint using the command + This method also allows one to search by fingerprint using the command @option{--locate-external-key} if the URL specifies an LDAP server. @item local @@ -3151,7 +3151,7 @@ Prompt before overwriting any files. Set compatibility flags to work around problems due to non-compliant keys or data. The @var{flags} are given as a comma separated list of flag names and are OR-ed together. The special flag "none" -clears the list and allows to start over with an empty list. To get a +clears the list and allows one to start over with an empty list. To get a list of available flags the sole word "help" can be used. @item --debug-level @var{level} @@ -3207,7 +3207,7 @@ and may thus be changed or removed at any time without notice. @item --debug-allow-large-chunks @opindex debug-allow-large-chunks -To facilitate software tests and experiments this option allows to +To facilitate software tests and experiments this option allows one to specify a limit of up to 4 EiB (@code{--chunk-size 62}). @item --debug-ignore-expiration @@ -3646,7 +3646,7 @@ not need to be listed explicitly. @opindex allow-weak-key-signatures To avoid a minor risk of collision attacks on third-party key signatures made using SHA-1, those key signatures are considered -invalid. This options allows to override this restriction. +invalid. This options allows one to override this restriction. @item --override-compliance-check This was a temporary introduced option and has no more effect. @@ -4111,7 +4111,7 @@ Operation is further controlled by a few environment variables: @item GNUPG_EXEC_DEBUG_FLAGS @efindex GNUPG_EXEC_DEBUG_FLAGS - This variable allows to enable diagnostics for process management. + This variable allows one to enable diagnostics for process management. A numeric decimal value is expected. Bit 0 enables general diagnostics, bit 1 enables certain warnings on Windows. diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 497b33203..d00ad447e 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -767,7 +767,7 @@ is given as fingerprint or keygrip. Set compatibility flags to work around problems due to non-compliant certificates or data. The @var{flags} are given as a comma separated list of flag names and are OR-ed together. The special flag "none" -clears the list and allows to start over with an empty list. To get a +clears the list and allows one to start over with an empty list. To get a list of available flags the sole word "help" can be used. @item --debug-level @var{level} diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index d4e663eff..d57326125 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -309,7 +309,7 @@ with lower priority should be used by default. @item --application-priority @var{namelist} @opindex application-priority -This option allows to change the order in which applications of a card +This option allows one to change the order in which applications of a card a tried if no specific application was requested. @var{namelist} is a space or comma delimited list of application names. Unknown names are simply skipped. Applications not mentioned in the list are put in the diff --git a/doc/tools.texi b/doc/tools.texi index 80ec7c6fe..da537b6d0 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -400,7 +400,7 @@ expected in the current GnuPG home directory. This command is usually not required because GnuPG is able to detect and remove stale lock files. Before using the command make sure that the file protected by the lock file is actually not in use. The lock command may be used to -lock an accidently removed lock file. Note that the commands have no +lock an accidentally removed lock file. Note that the commands have no effect on Windows because the mere existence of a lock file does not mean that the lock is active. diff --git a/g10/getkey.c b/g10/getkey.c index b959d77c7..ce59628a0 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1921,7 +1921,7 @@ get_pubkey_byfprint_fast (ctrl_t ctrl, PKT_public_key * pk, * R_HD may be NULL. If LOCK is set the handle has been opend in * locked mode and keydb_disable_caching () has been called. On error * R_KEYBLOCK is set to NULL but R_HD must be released by the caller; - * it may have a value of NULL, though. This allows to do an insert + * it may have a value of NULL, though. This allows one to do an insert * operation on a locked keydb handle. */ gpg_error_t get_keyblock_byfprint_fast (ctrl_t ctrl, diff --git a/g10/mainproc.c b/g10/mainproc.c index ce0fdaaac..430d7ff08 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -898,7 +898,7 @@ proc_encrypted (CTX c, PACKET *pkt) * encrypted packet. */ literals_seen++; - /* The --require-compliance option allows to simplify decryption in + /* The --require-compliance option allows one to simplify decryption in * de-vs compliance mode by just looking at the exit status. */ if (opt.flags.require_compliance && opt.compliance == CO_DE_VS diff --git a/scd/app-nks.c b/scd/app-nks.c index cdbdde8fb..c207fd500 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -1613,7 +1613,7 @@ verify_pin (app_t app, int pwid, const char *desc, memset (&pininfo, 0, sizeof pininfo); pininfo.fixedlen = -1; - /* FIXME: TCOS allows to read the min. and max. values - do this. */ + /* FIXME: TCOS allows one to read the min. and max. values - do this. */ if (app->appversion == 15) { if (app->app_local->active_nks_app == NKS_APP_NKS && pwid == 0x03) diff --git a/tests/openpgp/README b/tests/openpgp/README index 1225d4aad..86ff4624c 100644 --- a/tests/openpgp/README +++ b/tests/openpgp/README @@ -99,7 +99,7 @@ suite. This envvar gives the root directory of the build tree. See tests/gpgconf.ctl.in for the way we tell the GnuPG components this location. Note that we can't use that envvar directly because this -would allow user scripts and other software to accidently mess up the +would allow user scripts and other software to accidentally mess up the used components. **** argv[0] run-tests.scm depends on being able to re-exec gpgscm. It uses diff --git a/tools/gpg-card.c b/tools/gpg-card.c index f65a17b3c..b34b42698 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -402,7 +402,7 @@ nullnone (const char *s) * success returns 0 and stores the number of bytes read at R_BUFLEN * and the address of a newly allocated buffer at R_BUFFER. A * complementary nul byte is always appended to the data but not - * counted; this allows to pass NULL for R-BUFFER and consider the + * counted; this allows one to pass NULL for R-BUFFER and consider the * returned data as a string. */ static gpg_error_t get_data_from_file (const char *fname, char **r_buffer, size_t *r_buflen) diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c index 7a7544bb5..39746d489 100644 --- a/tools/watchgnupg.c +++ b/tools/watchgnupg.c @@ -461,7 +461,7 @@ main (int argc, char **argv) if (!tcp && argc == 1) ; else if (tcp && (argc == 1 || argc == 2)) - ; /* Option --tcp optionally allows to also read from a socket. */ + ; /* Option --tcp optionally allows one to also read from a socket. */ else if (!tcp && !argc) { /* No args given - figure out the socket using gpgconf. We also From 78eae9ffe8cecfcfcf19e353c8d0a5afd8f343e5 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 29 Jan 2024 09:24:19 +0100 Subject: [PATCH 347/869] doc: Mark --textmode as legacy option. -- --- .git-blame-ignore-revs | 2 ++ doc/gpg.texi | 37 +++++++++++++++++++------------------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 7182d90d9..ec5aae1c7 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,2 +1,4 @@ # indent: Modernize mem2str. 6a80d6f9206eae2c867c45daa5cd3e7d6c6ad114 +# doc: Fix spelling errors found by lintian. +2ed1f68b48db7b5503045386de0500fddf70077e diff --git a/doc/gpg.texi b/doc/gpg.texi index 9c1721500..93abd45cd 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2899,24 +2899,6 @@ done with @code{--with-colons}. @table @gnupgtabopt -@item -t, --textmode -@itemx --no-textmode -@opindex textmode -Treat input files as text and store them in the OpenPGP canonical text -form with standard "CRLF" line endings. This also sets the necessary -flags to inform the recipient that the encrypted or signed data is text -and may need its line endings converted back to whatever the local -system uses. This option is useful when communicating between two -platforms that have different line ending conventions (UNIX-like to Mac, -Mac to Windows, etc). @option{--no-textmode} disables this option, and -is the default. - -@item --force-v3-sigs -@itemx --no-force-v3-sigs -@item --force-v4-certs -@itemx --no-force-v4-certs -These options are obsolete and have no effect since GnuPG 2.1. - @item --force-ocb @itemx --force-aead @opindex force-ocb @@ -3891,6 +3873,25 @@ all on Windows. @table @gnupgtabopt +@item -t, --textmode +@itemx --no-textmode +@opindex textmode +Treat input files as text and store them in the OpenPGP canonical text +form with standard "CRLF" line endings. This also sets the necessary +flags to inform the recipient that the encrypted or signed data is text +and may need its line endings converted back to whatever the local +system uses. This option was useful when communicating between two +platforms with different line ending conventions (UNIX-like to Mac, +Mac to Windows, etc). @option{--no-textmode} disables this option, and +is the default. Note that this is a legacy option which should not +anymore be used by any modern software. + +@item --force-v3-sigs +@itemx --no-force-v3-sigs +@item --force-v4-certs +@itemx --no-force-v4-certs +These options are obsolete and have no effect since GnuPG 2.1. + @item --show-photos @itemx --no-show-photos @opindex show-photos From ae0a755e0d8c3780bb24a777efa0ed31ed3916bd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 29 Jan 2024 09:26:26 +0100 Subject: [PATCH 348/869] gpg: Hide --textmode from the help output. -- --- g10/gpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/gpg.c b/g10/gpg.c index 18df7de67..d4fbecdbe 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -753,7 +753,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oNoEscapeFrom, "no-escape-from-lines", "@"), ARGPARSE_s_n (oMimemode, "mimemode", "@"), ARGPARSE_s_n (oTextmodeShort, NULL, "@"), - ARGPARSE_s_n (oTextmode, "textmode", N_("use canonical text mode")), + ARGPARSE_s_n (oTextmode, "textmode", "@"), ARGPARSE_s_n (oNoTextmode, "no-textmode", "@"), ARGPARSE_s_s (oSetFilename, "set-filename", "@"), ARGPARSE_s_n (oForYourEyesOnly, "for-your-eyes-only", "@"), From 03207f62e80ac03826f7dbe04a59f15df0f57530 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 29 Jan 2024 10:30:40 +0100 Subject: [PATCH 349/869] gpg: Minor code cleanup for fingerprint computation. * g10/keyid.c (do_hash_public_key): Simplify code for clarity. --- g10/keyid.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/g10/keyid.c b/g10/keyid.c index 4a041ce0e..89bba0d7a 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -234,20 +234,16 @@ do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5) if (use_v5) { gcry_md_putc ( md, 0x9a ); /* ctb */ - gcry_md_putc ( md, n >> 24 ); /* 4 byte length header */ + gcry_md_putc ( md, n >> 24 ); /* 4 byte length header (upper bits) */ gcry_md_putc ( md, n >> 16 ); - gcry_md_putc ( md, n >> 8 ); - gcry_md_putc ( md, n ); - /* Note that the next byte may either be 4 or 5. */ - gcry_md_putc ( md, pk->version ); } else { gcry_md_putc ( md, 0x99 ); /* ctb */ - gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */ - gcry_md_putc ( md, n ); - gcry_md_putc ( md, pk->version ); } + gcry_md_putc ( md, n >> 8 ); /* lower bits of the length header. */ + gcry_md_putc ( md, n ); + gcry_md_putc ( md, pk->version ); gcry_md_putc ( md, pk->timestamp >> 24 ); gcry_md_putc ( md, pk->timestamp >> 16 ); gcry_md_putc ( md, pk->timestamp >> 8 ); @@ -255,7 +251,7 @@ do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5) gcry_md_putc ( md, pk->pubkey_algo ); - if (use_v5) + if (use_v5) /* Hash the 32 bit length */ { n -= 10; gcry_md_putc ( md, n >> 24 ); From 300c9eeace35b04f0f108e93ce17fd37a779de58 Mon Sep 17 00:00:00 2001 From: Jakub Bogusz Date: Sun, 28 Jan 2024 15:54:01 +0100 Subject: [PATCH 350/869] po: update Polish translation --- po/pl.po | 639 ++++++++----------------------------------------------- 1 file changed, 91 insertions(+), 548 deletions(-) diff --git a/po/pl.po b/po/pl.po index 1248d87c6..1606612ef 100644 --- a/po/pl.po +++ b/po/pl.po @@ -2,13 +2,13 @@ # Copyright (C) 1998, 1999, 2000, 2001, 2002, # 2007 Free Software Foundation, Inc. # Janusz A. Urbanowicz , 1999, 2000, 2001, 2002, 2003-2004 -# Jakub Bogusz , 2003-2023. +# Jakub Bogusz , 2003-2024. # msgid "" msgstr "" -"Project-Id-Version: gnupg-2.4.3\n" +"Project-Id-Version: gnupg-2.4.4\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-10-20 21:29+0200\n" +"PO-Revision-Date: 2024-01-28 15:45+0100\n" "Last-Translator: Jakub Bogusz \n" "Language-Team: Polish \n" "Language: pl\n" @@ -923,43 +923,35 @@ msgstr "OSTRZEŻENIE: „%s%s” jest przestarzałą opcją - nie ma efektu\n" msgid "unknown debug flag '%s' ignored\n" msgstr "nieznana flaga diagnostyczna „%s” zignorowana\n" -#, fuzzy, c-format -#| msgid "waiting for the %s to come up ... (%ds)\n" +#, c-format msgid "waiting for the dirmngr to come up ... (%ds)\n" -msgstr "oczekiwanie na uruchomienie procesu %s... (%ds)\n" +msgstr "oczekiwanie na uruchomienie procesu dirmngr... (%ds)\n" -#, fuzzy, c-format -#| msgid "waiting for the %s to come up ... (%ds)\n" +#, c-format msgid "waiting for the keyboxd to come up ... (%ds)\n" -msgstr "oczekiwanie na uruchomienie procesu %s... (%ds)\n" +msgstr "oczekiwanie na uruchomienie procesu keyboxd... (%ds)\n" -#, fuzzy, c-format -#| msgid "waiting for the %s to come up ... (%ds)\n" +#, c-format msgid "waiting for the agent to come up ... (%ds)\n" -msgstr "oczekiwanie na uruchomienie procesu %s... (%ds)\n" +msgstr "oczekiwanie na uruchomienie procesu agenta... (%ds)\n" -#, fuzzy, c-format -#| msgid "connection to %s established\n" +#, c-format msgid "connection to the dirmngr established\n" -msgstr "ustanowiono połączenie z procesem %s\n" +msgstr "ustanowiono połączenie z procesem dirmngr\n" -#, fuzzy, c-format -#| msgid "connection to %s established\n" +#, c-format msgid "connection to the keyboxd established\n" -msgstr "ustanowiono połączenie z procesem %s\n" +msgstr "ustanowiono połączenie z procesem keyboxd\n" -#, fuzzy, c-format -#| msgid "connection to %s established\n" +#, c-format msgid "connection to the agent established\n" -msgstr "ustanowiono połączenie z procesem %s\n" +msgstr "ustanowiono połączenie z procesem agenta\n" -#, fuzzy, c-format -#| msgid "no running Dirmngr - starting '%s'\n" +#, c-format msgid "no running %s - starting '%s'\n" -msgstr "Dirmngr nie działa - uruchamianie „%s”\n" +msgstr "brak działającego %s - uruchamianie „%s”\n" -#, fuzzy, c-format -#| msgid "connection to agent is in restricted mode\n" +#, c-format msgid "connection to the agent is in restricted mode\n" msgstr "połączenie z agentem jest w trybie ograniczonym\n" @@ -1332,10 +1324,9 @@ msgstr "problem z agentem: %s\n" msgid "no dirmngr running in this session\n" msgstr "brak działającego dirmngr w tej sesji\n" -#, fuzzy, c-format -#| msgid "keyserver option \"%s\" may not be used in %s mode\n" +#, c-format msgid "keyserver option \"honor-keyserver-url\" may not be used in Tor mode\n" -msgstr "opcja serwera kluczy „%s” nie może być używana w trybie %s\n" +msgstr "opcja serwera kluczy „honor-keyserver-url” nie może być używana w trybie Tor\n" msgid "WKD uses a cached result" msgstr "WKD używa zapamiętanego wyniku" @@ -1402,7 +1393,7 @@ msgstr "wymuszono" #, c-format msgid "Please try command \"%s\" if the listing does not look correct\n" -msgstr "Proszę spróbować polecenia ,,%s'', jeśli lista nie wygląda poprawnie\n" +msgstr "Proszę spróbować polecenia „%s”, jeśli lista nie wygląda poprawnie\n" msgid "Error: Only plain ASCII is currently allowed.\n" msgstr "Błąd: aktualnie dopuszczalne jest tylko czyste ASCII.\n" @@ -1768,14 +1759,13 @@ msgstr "" "OSTRZEŻENIE: wymuszone użycie szyfru %s (%d) kłóci się z ustawieniami " "adresata\n" -#, fuzzy, c-format -#| msgid "cipher algorithm '%s' may not be used in %s mode\n" +#, c-format msgid "cipher algorithm '%s' may not be used for encryption\n" -msgstr "szyfr „%s” nie może być używany w trybie %s\n" +msgstr "algorytm szyfru „%s” nie może być używany do szyfrowania\n" #, c-format msgid "(use option \"%s\" to override)\n" -msgstr "" +msgstr "(opcją „%s” można to obejść)\n" #, c-format msgid "cipher algorithm '%s' may not be used in %s mode\n" @@ -1821,17 +1811,15 @@ msgstr "" "OSTRZEŻENIE: wymuszone użycie kompresji %s (%d) kłóci się z ustawieniami " "adresata\n" -#, fuzzy, c-format -#| msgid "%s/%s encrypted for: \"%s\"\n" +#, c-format msgid "%s/%s.%s encrypted for: \"%s\"\n" -msgstr "%s/%s zaszyfrowany dla: „%s”\n" +msgstr "%s/%s.%s zaszyfrowany dla: „%s”\n" #, c-format msgid "option '%s' may not be used in %s mode\n" msgstr "opcja „%s” nie może być używana w trybie %s\n" -#, fuzzy, c-format -#| msgid "%s encrypted data\n" +#, c-format msgid "%s encrypted data\n" msgstr "dane zaszyfrowano za pomocą %s\n" @@ -2798,12 +2786,11 @@ msgstr "" #, c-format msgid " \"%s\": preference for cipher algorithm %s\n" -msgstr " „%s”: preferowany szyfr %s\n" +msgstr " „%s”: preferowany algorytm szyfru %s\n" -#, fuzzy, c-format -#| msgid " \"%s\": preference for cipher algorithm %s\n" +#, c-format msgid " \"%s\": preference for AEAD algorithm %s\n" -msgstr " „%s”: preferowany szyfr %s\n" +msgstr " „%s”: preferowany algorytm AEAD %s\n" #, c-format msgid " \"%s\": preference for digest algorithm %s\n" @@ -3905,7 +3892,7 @@ msgstr "Czy podano odcisk podklucza?\n" #, c-format msgid "key \"%s\" is already on this keyblock\n" -msgstr "klucz ,,%s'' jest już w tym bloku kluczy\n" +msgstr "klucz „%s” jest już w tym bloku kluczy\n" msgid "" "Are you sure you want to change the expiration time for multiple subkeys? (y/" @@ -4154,77 +4141,64 @@ msgstr " (%c) Przełączenie możliwości uwierzytelniania\n" msgid " (%c) Finished\n" msgstr " (%c) Zakończenie\n" -#, fuzzy, c-format -#| msgid " (%d) RSA and RSA (default)\n" +#, c-format msgid " (%d) RSA and RSA%s\n" -msgstr " (%d) RSA i RSA (domyślne)\n" +msgstr " (%d) RSA i RSA%s\n" -#, fuzzy, c-format -#| msgid " (%d) DSA and Elgamal\n" +#, c-format msgid " (%d) DSA and Elgamal%s\n" -msgstr " (%d) DSA i Elgamala\n" +msgstr " (%d) DSA i Elgamala%s\n" -#, fuzzy, c-format -#| msgid " (%d) DSA (sign only)\n" +#, c-format msgid " (%d) DSA (sign only)%s\n" -msgstr " (%d) DSA (tylko do podpisywania)\n" +msgstr " (%d) DSA (tylko do podpisywania)%s\n" -#, fuzzy, c-format -#| msgid " (%d) RSA (sign only)\n" +#, c-format msgid " (%d) RSA (sign only)%s\n" -msgstr " (%d) RSA (tylko do podpisywania)\n" +msgstr " (%d) RSA (tylko do podpisywania)%s\n" -#, fuzzy, c-format -#| msgid " (%d) Elgamal (encrypt only)\n" +#, c-format msgid " (%d) Elgamal (encrypt only)%s\n" -msgstr " (%d) Elgamala (tylko do szyfrowania)\n" +msgstr " (%d) Elgamala (tylko do szyfrowania)%s\n" -#, fuzzy, c-format -#| msgid " (%d) RSA (encrypt only)\n" +#, c-format msgid " (%d) RSA (encrypt only)%s\n" -msgstr " (%d) RSA (tylko do szyfrowania)\n" +msgstr " (%d) RSA (tylko do szyfrowania)%s\n" -#, fuzzy, c-format -#| msgid " (%d) DSA (set your own capabilities)\n" +#, c-format msgid " (%d) DSA (set your own capabilities)%s\n" -msgstr " (%d) DSA (możliwości do ustawienia)\n" +msgstr " (%d) DSA (możliwości do ustawienia)%s\n" -#, fuzzy, c-format -#| msgid " (%d) RSA (set your own capabilities)\n" +#, c-format msgid " (%d) RSA (set your own capabilities)%s\n" -msgstr " (%d) RSA (możliwości do ustawienia)\n" +msgstr " (%d) RSA (możliwości do ustawienia)%s\n" -#, fuzzy, c-format -#| msgid " (%d) sign, encrypt\n" +#, c-format msgid " (%d) ECC (sign and encrypt)%s\n" -msgstr " (%d) podpisywanie, szyfrowanie\n" +msgstr " (%d) ECC (podpisywanie i szyfrowanie)%s\n" msgid " *default*" -msgstr "" +msgstr " *domyślne*" #, c-format msgid " (%d) ECC (sign only)\n" msgstr " (%d) ECC (tylko do podpisywania)\n" -#, fuzzy, c-format -#| msgid " (%d) ECC (set your own capabilities)\n" +#, c-format msgid " (%d) ECC (set your own capabilities)%s\n" -msgstr " (%d) ECC (możliwości do ustawienia)\n" +msgstr " (%d) ECC (możliwości do ustawienia)%s\n" -#, fuzzy, c-format -#| msgid " (%d) ECC (encrypt only)\n" +#, c-format msgid " (%d) ECC (encrypt only)%s\n" -msgstr " (%d) ECC (tylko do szyfrowania)\n" +msgstr " (%d) ECC (tylko do szyfrowania)%s\n" -#, fuzzy, c-format -#| msgid " (%d) Existing key\n" +#, c-format msgid " (%d) Existing key%s\n" -msgstr " (%d) Istniejący klucz\n" +msgstr " (%d) Istniejący klucz%s\n" -#, fuzzy, c-format -#| msgid " (%d) Existing key from card\n" +#, c-format msgid " (%d) Existing key from card%s\n" -msgstr " (%d) Istniejący klucz z karty\n" +msgstr " (%d) Istniejący klucz z karty%s\n" msgid "Enter the keygrip: " msgstr "Uchwyt klucza: " @@ -5336,25 +5310,21 @@ msgstr "" "OSTRZEŻENIE: ten klucz mógł zostać unieważniony\n" " (brak klucza unieważniającego aby to sprawdzić)\n" -#, fuzzy, c-format -#| msgid "user ID: \"%s\"\n" +#, c-format msgid "checking User ID \"%s\"\n" -msgstr "identyfikator użytkownika: „%s”\n" +msgstr "sprawdzanie identyfikatora użytkownika: „%s”\n" -#, fuzzy, c-format -#| msgid "option '%s' given, but option '%s' not given\n" +#, c-format msgid "option %s given but issuer \"%s\" does not match\n" -msgstr "podano opcję „%s”, ale nie podano opcji „%s”\n" +msgstr "podano opcję %s, ale wystawca „%s” nie pasuje\n" -#, fuzzy, c-format -#| msgid "key %s: doesn't match our copy\n" +#, c-format msgid "issuer \"%s\" does not match any User ID\n" -msgstr "klucz %s: nie zgadza się z lokalną kopią\n" +msgstr "klucz „%s” nie pasuje do żadnego identyfikatora użytkownika\n" -#, fuzzy, c-format -#| msgid "option '%s' given, but option '%s' not given\n" +#, c-format msgid "option %s given but no matching User ID found\n" -msgstr "podano opcję „%s”, ale nie podano opcji „%s”\n" +msgstr "podano opcję %s, ale nie znaleziono pasującego identyfikatora użytkownika\n" #, c-format msgid "WARNING: This key has been revoked by its designated revoker!\n" @@ -6524,15 +6494,13 @@ msgstr "linia wejścia %u zbyt długa lub brak znaku LF\n" msgid "can't open fd %d: %s\n" msgstr "nie można otworzyć fd %d: %s\n" -#, fuzzy, c-format -#| msgid "WARNING: message was not integrity protected\n" +#, c-format msgid "WARNING: encrypting without integrity protection is dangerous\n" -msgstr "OSTRZEŻENIE: wiadomość nie była zabezpieczona przed manipulacją\n" +msgstr "OSTRZEŻENIE: szyfrowanie bez ochrony przed manipulacją jest niebezpieczne\n" -#, fuzzy, c-format -#| msgid "ambiguous option '%s'\n" +#, c-format msgid "Hint: Do not use option %s\n" -msgstr "niejednoznaczna opcja „%s”\n" +msgstr "Podpowiedź: nie używać opcji %s\n" msgid "set debugging flags" msgstr "ustawienie flag diagnostycznych" @@ -8553,7 +8521,7 @@ msgstr "%s:%u: podano hasło bez użytkownika\n" #, c-format msgid "%s:%u: ignoring unknown flag '%s'\n" -msgstr "%s:%u: zignorowano nieznaną flagę ,,%s''\n" +msgstr "%s:%u: zignorowano nieznaną flagę „%s”\n" #, c-format msgid "%s:%u: skipping this line\n" @@ -8986,489 +8954,64 @@ msgstr "" "Składnia: gpg-check-pattern [opcje] plik-wzorców\n" "Sprawdzanie hasła ze standardowego wejścia względem pliku wzorców\n" -#, fuzzy, c-format -#| msgid "Note: keys are already stored on the card!\n" +#, c-format msgid "Note: key %s is already stored on the card!\n" -msgstr "Uwaga: klucze są już zapisane na karcie!\n" +msgstr "Uwaga: klucz %s jest już zapisany na karcie!\n" -#, fuzzy, c-format -#| msgid "Note: keys are already stored on the card!\n" +#, c-format msgid "Note: Keys are already stored on the card!\n" msgstr "Uwaga: klucze są już zapisane na karcie!\n" -#, fuzzy, c-format -#| msgid "Replace existing keys? (y/N) " +#, c-format msgid "Replace existing key %s ? (y/N) " -msgstr "Zastąpić istniejące klucze? (t/N) " +msgstr "Zastąpić istniejące klucz %s? (t/N) " -#, fuzzy, c-format -#| msgid "OpenPGP card no. %s detected\n" +#, c-format msgid "%s card no. %s detected\n" -msgstr "Wykryto kartę OpenPGP nr %s\n" +msgstr "Wykryto kartę %s nr %s\n" #, c-format msgid "User Interaction Flag is set to \"%s\" - can't change\n" -msgstr "" +msgstr "Flaga interakcji użytkownika (UIF) jest ustawiona na „%s” - nie można zmienić\n" #, c-format msgid "" "Warning: Setting the User Interaction Flag to \"%s\"\n" " can only be reverted using a factory reset!\n" msgstr "" +"Uwaga: ustawienie flagi interakcji użytkownika (UIF) na „%s”\n" +" może być odwrócone tylko przez reset do ustawień fabrycznych!\n" #, c-format msgid "Please use \"uif --yes %d %s\"\n" -msgstr "" +msgstr "Proszę użyć „uif --yes %d %s”\n" -#, fuzzy -#| msgid "add a certificate to the cache" msgid "authenticate to the card" -msgstr "dodanie certyfikatu do pamięci podręcznej" +msgstr "uwierzytelnienie względem karty" msgid "send a reset to the card daemon" -msgstr "" +msgstr "wysłanie resetu do demona kart" msgid "setup KDF for PIN authentication" msgstr "ustawienie KDF do uwierzytelniania PIN-em" msgid "change a private data object" -msgstr "" +msgstr "zmiana obiektu danych prywatnych" -#, fuzzy -#| msgid "add a certificate to the cache" msgid "read a certificate from a data object" -msgstr "dodanie certyfikatu do pamięci podręcznej" +msgstr "odczyt certyfikatu z obiektu danych" -#, fuzzy -#| msgid "add a certificate to the cache" msgid "store a certificate to a data object" -msgstr "dodanie certyfikatu do pamięci podręcznej" +msgstr "zapis certyfikatu w obiekcie danych" msgid "store a private key to a data object" -msgstr "" +msgstr "zapis klucza prywatnego w obiekcie danych" msgid "run various checks on the keys" -msgstr "" +msgstr "wykonanie różnych sprawdzeń kluczy" msgid "Yubikey management commands" -msgstr "" +msgstr "polecenia zarządzające kluczami Yubikey" msgid "manage the command history" -msgstr "" - -#, fuzzy -#~| msgid "selected digest algorithm is invalid\n" -#~ msgid "selected AEAD algorithm is invalid\n" -#~ msgstr "wybrany algorytm skrótów wiadomości jest niepoprawny\n" - -#, fuzzy -#~| msgid "invalid personal cipher preferences\n" -#~ msgid "invalid personal AEAD preferences\n" -#~ msgstr "niewłaściwe ustawienia szyfrów\n" - -#, fuzzy -#~| msgid "cipher algorithm '%s' may not be used in %s mode\n" -#~ msgid "AEAD algorithm '%s' may not be used in %s mode\n" -#~ msgstr "szyfr „%s” nie może być używany w trybie %s\n" - -#~ msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" -#~ msgstr "wymuszone użycie szyfru %s (%d) kłóci się z ustawieniami adresata\n" - -#~ msgid "error writing to temporary file: %s\n" -#~ msgstr "błąd zapisu do pliku tymczasowego: %s\n" - -#~ msgid "run in supervised mode" -#~ msgstr "uruchomienie w trybie dozorowanym" - -#~ msgid "Name may not start with a digit\n" -#~ msgstr "Imię lub nazwisko nie może zaczynać się od cyfry\n" - -#~ msgid "Name must be at least 5 characters long\n" -#~ msgstr "Imię i nazwisko muszą mieć co najmniej 5 znaków długości.\n" - -#~ msgid "Configuration for Keyservers" -#~ msgstr "Konfiguracja dla serwerów kluczy" - -#~ msgid "Configuration of LDAP servers to use" -#~ msgstr "Konfiguracja używanych serwerów LDAP" - -#~ msgid "selfsigned certificate has a BAD signature" -#~ msgstr "certyfikat z własnym podpisem ma BŁĘDNY podpis" - -#~ msgid "requesting key %s from %s server %s\n" -#~ msgstr "zapytanie o klucz %s z serwera %s %s\n" - -#~ msgid "%s:%u: no hostname given\n" -#~ msgstr "%s:%u: nie podano nazwy hosta\n" - -#~ msgid "could not parse keyserver\n" -#~ msgstr "niezrozumiały adres serwera kluczy\n" - -#~ msgid "return all values in a record oriented format" -#~ msgstr "zwrócenie wszystkich wartości w formacie rekordu" - -#~ msgid "|NAME|ignore host part and connect through NAME" -#~ msgstr "|NAZWA|zignorowanie części z hostem i połączenie poprzez NAZWĘ" - -#~ msgid "|NAME|connect to host NAME" -#~ msgstr "|NAZWA|połączenie z hostem NAZWA" - -#~ msgid "|N|connect to port N" -#~ msgstr "|N|połączenie z portem N" - -#~ msgid "|NAME|use user NAME for authentication" -#~ msgstr "|NAZWA|użycie NAZWY użytkownika do uwierzytelnienia" - -#~ msgid "|PASS|use password PASS for authentication" -#~ msgstr "|HASŁO|użycie HASŁA do uwierzytelnienia" - -#~ msgid "take password from $DIRMNGR_LDAP_PASS" -#~ msgstr "pobranie hasła z $DIRMNGR_LDAP_PASS" - -#~ msgid "|STRING|query DN STRING" -#~ msgstr "|ŁAŃCUCH|ŁAŃCUCH zapytania DN" - -#~ msgid "|STRING|use STRING as filter expression" -#~ msgstr "|ŁAŃCUCH|użycie ŁAŃCUCHA jako wyrażenia filtra" - -#~ msgid "|STRING|return the attribute STRING" -#~ msgstr "|ŁAŃCUCH|zwrócenie atrybutu ŁAŃCUCH" - -#~ msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n" -#~ msgstr "Składnia: dirmngr_ldap [opcje] [URL] (-h wyświetla pomoc)\n" - -#~ msgid "" -#~ "Syntax: dirmngr_ldap [options] [URL]\n" -#~ "Internal LDAP helper for Dirmngr\n" -#~ "Interface and options may change without notice\n" -#~ msgstr "" -#~ "Składnia: dirmngr_ldap [opcje] [URL]\n" -#~ "Wewnętrzny program pomocniczy LDAP dla Dirmngr\n" -#~ "Interfejs i opcje mogą się zmienić bez uprzedzenia\n" - -#~ msgid "invalid port number %d\n" -#~ msgstr "błędny numer portu %d\n" - -#~ msgid "scanning result for attribute '%s'\n" -#~ msgstr "przeszukiwanie wyniku pod kątem atrybutu „%s”\n" - -#~ msgid "error writing to stdout: %s\n" -#~ msgstr "błąd zapisu na standardowe wyjście: %s\n" - -#~ msgid " available attribute '%s'\n" -#~ msgstr " dostępny atrybut „%s”\n" - -#~ msgid "attribute '%s' not found\n" -#~ msgstr "nie znaleziono atrybutu „%s”\n" - -#~ msgid "found attribute '%s'\n" -#~ msgstr "znaleziono atrybut „%s”\n" - -#~ msgid "processing url '%s'\n" -#~ msgstr "przetwarzanie URL-a „%s”\n" - -#~ msgid " user '%s'\n" -#~ msgstr " użytkownik „%s”\n" - -#~ msgid " pass '%s'\n" -#~ msgstr " hasło „%s”\n" - -#~ msgid " host '%s'\n" -#~ msgstr " host „%s”\n" - -#~ msgid " port %d\n" -#~ msgstr " port %d\n" - -#~ msgid " DN '%s'\n" -#~ msgstr " DN „%s”\n" - -#~ msgid " filter '%s'\n" -#~ msgstr " filtr „%s”\n" - -#~ msgid " attr '%s'\n" -#~ msgstr " atrybut „%s”\n" - -#~ msgid "no host name in '%s'\n" -#~ msgstr "brak nazwy hosta w „%s”\n" - -#~ msgid "no attribute given for query '%s'\n" -#~ msgstr "nie podano atrybutu dla zapytania „%s”\n" - -#~ msgid "WARNING: using first attribute only\n" -#~ msgstr "OSTRZEŻENIE: użyto tylko pierwszego atrybutu\n" - -#~ msgid "LDAP init to '%s:%d' failed: %s\n" -#~ msgstr "nie udało się zainicjować LDAP na „%s:%d”: %s\n" - -#, fuzzy -#~| msgid "LDAP init to '%s:%d' failed: %s\n" -#~ msgid "LDAP init to '%s' failed: %s\n" -#~ msgstr "nie udało się zainicjować LDAP na „%s:%d”: %s\n" - -#, fuzzy -#~| msgid "LDAP init to '%s:%d' failed: %s\n" -#~ msgid "LDAP init to '%s' done\n" -#~ msgstr "nie udało się zainicjować LDAP na „%s:%d”: %s\n" - -#~ msgid "binding to '%s:%d' failed: %s\n" -#~ msgstr "dowiązanie do „%s:%d” nie powiodło się: %s\n" - -#~ msgid "searching '%s' failed: %s\n" -#~ msgstr "szukanie „%s” nie powiodło się: %s\n" - -#~ msgid "start_cert_fetch: invalid pattern '%s'\n" -#~ msgstr "start_cert_fetch: błędny wzorzec „%s”\n" - -#~ msgid "ldapserver missing" -#~ msgstr "brak pola ldapserver" - -#, fuzzy -#~| msgid "change a passphrase" -#~ msgid "Suggest a random passphrase." -#~ msgstr "zmiana hasła" - -#~ msgid "detected card with S/N: %s\n" -#~ msgstr "wykryto kartę o numerze seryjnym: %s\n" - -#~ msgid "no authentication key for ssh on card: %s\n" -#~ msgstr "nie znaleziono klucza uwierzytelniającego dla ssh na karcie: %s\n" - -#~ msgid "Please remove the current card and insert the one with serial number" -#~ msgstr "Proszę wyjąć obecną kartę i włożyć kartę z numerem seryjnym" - -#~ msgid "use a log file for the server" -#~ msgstr "użycie pliku loga dla serwera" - -#~ msgid "no running gpg-agent - starting '%s'\n" -#~ msgstr "gpg-agent nie działa - uruchamianie „%s”\n" - -#~ msgid "argument not expected" -#~ msgstr "nieoczekiwany argument" - -#~ msgid "read error" -#~ msgstr "błąd odczytu" - -#~ msgid "keyword too long" -#~ msgstr "słowo kluczowe zbyt długie" - -#~ msgid "missing argument" -#~ msgstr "brak argumentu" - -#~ msgid "invalid argument" -#~ msgstr "niepoprawny argument" - -#~ msgid "invalid command" -#~ msgstr "błędne polecenie" - -#~ msgid "invalid alias definition" -#~ msgstr "błędna definicja aliasu" - -#~ msgid "out of core" -#~ msgstr "brak pamięci" - -#, fuzzy -#~| msgid "invalid command" -#~ msgid "invalid meta command" -#~ msgstr "błędne polecenie" - -#, fuzzy -#~| msgid "unknown command '%s'\n" -#~ msgid "unknown meta command" -#~ msgstr "nieznane polecenie „%s”\n" - -#, fuzzy -#~| msgid "unexpected armor: " -#~ msgid "unexpected meta command" -#~ msgstr "nieoczekiwane opakowanie: " - -#~ msgid "invalid option" -#~ msgstr "błędna opcja" - -#~ msgid "missing argument for option \"%.50s\"\n" -#~ msgstr "brak argumentu dla opcji „%.50s”\n" - -#~ msgid "option \"%.50s\" does not expect an argument\n" -#~ msgstr "opcja „%.50s” nie może mieć argumentów\n" - -#~ msgid "invalid command \"%.50s\"\n" -#~ msgstr "błędne polecenie „%.50s”\n" - -#~ msgid "option \"%.50s\" is ambiguous\n" -#~ msgstr "opcja „%.50s” jest niejednoznaczna\n" - -#~ msgid "command \"%.50s\" is ambiguous\n" -#~ msgstr "polecenie „%.50s” jest niejednoznaczne\n" - -#~ msgid "invalid option \"%.50s\"\n" -#~ msgstr "błędna opcja „%.50s”\n" - -#~ msgid "Note: no default option file '%s'\n" -#~ msgstr "Uwaga: brak domyślnego pliku opcji „%s”\n" - -#~ msgid "option file '%s': %s\n" -#~ msgstr "plik opcji „%s”: %s\n" - -#~ msgid "unable to execute program '%s': %s\n" -#~ msgstr "nie można uruchomić programu „%s”: %s\n" - -#~ msgid "unable to execute external program\n" -#~ msgstr "nie można uruchomić zewnętrznego programu\n" - -#~ msgid "unable to read external program response: %s\n" -#~ msgstr "nie można odczytać odpowiedzi programu zewnętrznego: %s\n" - -#~ msgid "validate signatures with PKA data" -#~ msgstr "sprawdzanie podpisów z danymi PKA" - -#~ msgid "elevate the trust of signatures with valid PKA data" -#~ msgstr "zwiększenie zaufania podpisów z poprawnymi danymi PKA" - -#~ msgid " (%d) ECC and ECC\n" -#~ msgstr " (%d) ECC i ECC\n" - -#~ msgid "honor the PKA record set on a key when retrieving keys" -#~ msgstr "honorowanie rekordu PKA ustawionego w kluczu przy pobieraniu kluczy" - -#~ msgid "Note: Verified signer's address is '%s'\n" -#~ msgstr "Uwaga: Sprawdzony adres pospisującego to „%s”\n" - -#~ msgid "Note: Signer's address '%s' does not match DNS entry\n" -#~ msgstr "Uwaga: Adres podpisującego „%s” nie pasuje do wpisu DNS\n" - -#~ msgid "trustlevel adjusted to FULL due to valid PKA info\n" -#~ msgstr "" -#~ "poziom zaufania poprawiony na PEŁNY ze względu na poprawne informacje " -#~ "PKA\n" - -#~ msgid "trustlevel adjusted to NEVER due to bad PKA info\n" -#~ msgstr "" -#~ "poziom zaufania poprawiony na ŻADEN ze względu na błędne informacje PKA\n" - -#~ msgid "|FILE|write a server mode log to FILE" -#~ msgstr "|PLIK|zapisanie logów trybu serwerowego do PLIKU" - -#~ msgid "run without asking a user" -#~ msgstr "działanie bez pytania użytkownika" - -#~ msgid "allow PKA lookups (DNS requests)" -#~ msgstr "zezwolenie na wyszukiwania PKA (żądania DNS)" - -#~ msgid "Options controlling the format of the output" -#~ msgstr "Opcje sterujące formatem wyjścia" - -#~ msgid "Options controlling the use of Tor" -#~ msgstr "Opcje sterujące użyciem Tora" - -#~ msgid "LDAP server list" -#~ msgstr "lista serwerów LDAP" - -#~ msgid "Note: old default options file '%s' ignored\n" -#~ msgstr "Uwaga: stary domyślny plik opcji „%s” został zignorowany\n" - -#~ msgid "" -#~ "@\n" -#~ "Commands:\n" -#~ " " -#~ msgstr "" -#~ "@\n" -#~ "Polecenia:\n" -#~ " " - -#~ msgid "decryption modus" -#~ msgstr "tryb rozszyfrowywania" - -#~ msgid "encryption modus" -#~ msgstr "tryb szyfrowania" - -#~ msgid "tool class (confucius)" -#~ msgstr "klasa narzędzia (confucius)" - -#~ msgid "program filename" -#~ msgstr "nazwa programu" - -#~ msgid "secret key file (required)" -#~ msgstr "plik klucza tajnego (wymagany)" - -#~ msgid "input file name (default stdin)" -#~ msgstr "nazwa pliku wejściowego (domyślnie standardowe wejście)" - -#~ msgid "Usage: symcryptrun [options] (-h for help)" -#~ msgstr "Składnia: symcryptrun [opcje] (-h wyświetla pomoc)" - -#~ msgid "" -#~ "Syntax: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE " -#~ "[options...] COMMAND [inputfile]\n" -#~ "Call a simple symmetric encryption tool\n" -#~ msgstr "" -#~ "Składnia: symcryptrun --class KLASA --program PROGRAM --keyfile " -#~ "PLIK_KLUCZA [opcje...] POLECENIE [plik-weściowy]\n" -#~ "Wywołanie prostego narzędzia do szyfrowania symetrycznego\n" - -#~ msgid "%s on %s aborted with status %i\n" -#~ msgstr "%s na %s przerwany ze stanem %i\n" - -#~ msgid "%s on %s failed with status %i\n" -#~ msgstr "%s na %s nie powiódł się ze stanem %i\n" - -#~ msgid "can't create temporary directory '%s': %s\n" -#~ msgstr "nie można utworzyć katalogu tymczasowego „%s”: %s\n" - -#~ msgid "could not open %s for writing: %s\n" -#~ msgstr "nie udało się otworzyć %s do zapisu: %s\n" - -#~ msgid "error closing %s: %s\n" -#~ msgstr "błąd zamykania %s: %s\n" - -#~ msgid "no --program option provided\n" -#~ msgstr "nie podano opcji --program\n" - -#~ msgid "only --decrypt and --encrypt are supported\n" -#~ msgstr "obsługiwane są tylko --decrypt i --encrypt\n" - -#~ msgid "no --keyfile option provided\n" -#~ msgstr "nie podano opcji --keyfile\n" - -#~ msgid "cannot allocate args vector\n" -#~ msgstr "nie można przydzielić wektora args\n" - -#~ msgid "could not create pipe: %s\n" -#~ msgstr "nie udało się utworzyć potoku: %s\n" - -#~ msgid "could not create pty: %s\n" -#~ msgstr "nie udało się utworzyć pty: %s\n" - -#~ msgid "could not fork: %s\n" -#~ msgstr "nie udało się wykonać fork: %s\n" - -#~ msgid "execv failed: %s\n" -#~ msgstr "execv nie powiodło się: %s\n" - -#~ msgid "select failed: %s\n" -#~ msgstr "select nie powiodło się: %s\n" - -#~ msgid "read failed: %s\n" -#~ msgstr "odczyt nie powiódł się: %s\n" - -#~ msgid "pty read failed: %s\n" -#~ msgstr "odczyt pty nie powiódł się: %s\n" - -#~ msgid "waitpid failed: %s\n" -#~ msgstr "waitpid nie powiodło się: %s\n" - -#~ msgid "child aborted with status %i\n" -#~ msgstr "potomek został przerwany ze stanem %i\n" - -#~ msgid "cannot allocate infile string: %s\n" -#~ msgstr "nie można przydzielić łańcucha pliku wejściowego: %s\n" - -#~ msgid "cannot allocate outfile string: %s\n" -#~ msgstr "nie można przydzielić łańcucha pliku wyjściowego: %s\n" - -#~ msgid "either %s or %s must be given\n" -#~ msgstr "musi być podane %s lub %s\n" - -#~ msgid "no class provided\n" -#~ msgstr "nie podano klasy\n" - -#~ msgid "class %s is not supported\n" -#~ msgstr "klasa %s nie jest obsługiwana\n" +msgstr "zarządzanie historią poleceń" From d6dedda3f2a2ed7dd1f422856e9cc05f8f01d8cd Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Tue, 30 Jan 2024 10:20:43 +0100 Subject: [PATCH 351/869] w32, msi: Fix directory of gpg-card, add keyboxd * build-aux/speedo/w32/wixlib.wxs: Fix gpg-card directory id. Add keyboxd. --- build-aux/speedo/w32/wixlib.wxs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build-aux/speedo/w32/wixlib.wxs b/build-aux/speedo/w32/wixlib.wxs index 02568fe2f..e11455813 100644 --- a/build-aux/speedo/w32/wixlib.wxs +++ b/build-aux/speedo/w32/wixlib.wxs @@ -61,9 +61,12 @@ and then manually edited: - + + + + From 40b85d8e8cecadf35e51e84b30de4fac820d714b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 30 Jan 2024 15:50:09 +0100 Subject: [PATCH 352/869] scd:openpgp: Allow PIN length of 6 also with a reset code. * scd/app-openpgp.c (do_change_pin): Fix PIN length check. Add "R" flag to the reset code prompt. -- When using the reset code it was not possible to set a PIN of length 6. The "R" flags fixes a funny prompt. Fixes-commit: efe325ffdf21205b90f888c8f0248bbd4f61404b scd:openpgp: Allow PIN length of 6 also with a reset code. * scd/app-openpgp.c (do_change_pin): Fix PIN length check. Add "R" flag to the reset code prompt. -- When using the reset code it was not possible to set a PIN of length 6. The "R" flags fixes a funny prompt. Fixes-commit: 2376cdff1318688d94c95fd01adc4b2139c4a8c7 --- scd/app-openpgp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 3bc709602..1f5d64e6a 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -3306,6 +3306,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, char *pinvalue = NULL; int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET); int set_resetcode = 0; + int use_resetcode = 0; pininfo_t pininfo; int use_pinpad = 0; int minlen = 6; @@ -3458,7 +3459,7 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, } rc = pincb (pincb_arg, - _("||Please enter the Reset Code for the card"), + _("|R|Please enter the Reset Code for the card"), &resetcode); if (rc) { @@ -3473,13 +3474,14 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, rc = gpg_error (GPG_ERR_BAD_RESET_CODE); goto leave; } + use_resetcode = 1; } else { rc = gpg_error (GPG_ERR_INV_ID); goto leave; } - } + } /* End version 2 cards. */ if (chvno == 3) app->did_chv3 = 0; @@ -3511,6 +3513,17 @@ do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, goto leave; } } + else if (use_resetcode) + { + minlen = 6; /* Reset from the RC value to the PIN value. */ + if (strlen (pinvalue) < minlen) + { + log_info (_("PIN for CHV%d is too short;" + " minimum length is %d\n"), 1, minlen); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; + } + } else { if (chvno == 3) From 375c3a238ab67be9d52d1c4436f9855324c3f5dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Gonz=C3=A1lez?= Date: Mon, 5 Feb 2024 00:30:02 +0100 Subject: [PATCH 353/869] gpgsm: cleanup on error paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * sm/minip12.c (p12_parse): set err on the different error paths -- GnuPG-bug-id: 6973 Fixes-commit: 101433dfb42b333e48427baf9dd58ac4787c9786 Signed-off-by: Ángel González --- sm/minip12.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/sm/minip12.c b/sm/minip12.c index 2e7b50e1c..84a5f423c 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -1945,43 +1945,46 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, } where = "pfx"; - if (tlv_next (tlv)) + if ((err = tlv_next (tlv))) goto bailout; - if (tlv_expect_sequence (tlv)) + if ((err = tlv_expect_sequence (tlv))) goto bailout; where = "pfxVersion"; - if (tlv_next (tlv)) + if ((err = tlv_next (tlv))) goto bailout; - if (tlv_expect_integer (tlv, &intval) || intval != 3) + if ((err = tlv_expect_integer (tlv, &intval)) || intval != 3) goto bailout; where = "authSave"; - if (tlv_next (tlv)) + if ((err = tlv_next (tlv))) goto bailout; - if (tlv_expect_sequence (tlv)) + if ((err = tlv_expect_sequence (tlv))) goto bailout; - if (tlv_next (tlv)) + if ((err = tlv_next (tlv))) goto bailout; - if (tlv_expect_object_id (tlv, &oid, &oidlen)) + if ((err = tlv_expect_object_id (tlv, &oid, &oidlen))) goto bailout; if (oidlen != DIM(oid_data) || memcmp (oid, oid_data, DIM(oid_data))) + { + err = gpg_error (GPG_ERR_INV_OBJ); + goto bailout; + } + + if ((err = tlv_next (tlv))) + goto bailout; + if ((err = tlv_expect_context_tag (tlv, &intval)) || intval != 0 ) goto bailout; - if (tlv_next (tlv)) + if ((err = tlv_next (tlv))) goto bailout; - if (tlv_expect_context_tag (tlv, &intval) || intval != 0 ) - goto bailout; - - if (tlv_next (tlv)) - goto bailout; - if (tlv_expect_octet_string (tlv, 1, NULL, NULL)) + if ((err = tlv_expect_octet_string (tlv, 1, NULL, NULL))) goto bailout; if (tlv_peek (tlv, CLASS_UNIVERSAL, TAG_OCTET_STRING)) { - if (tlv_next (tlv)) + if ((err = tlv_next (tlv))) goto bailout; err = tlv_expect_octet_string (tlv, 1, NULL, NULL); if (err) @@ -1989,9 +1992,9 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, } where = "bags"; - if (tlv_next (tlv)) + if ((err = tlv_next (tlv))) goto bailout; - if (tlv_expect_sequence (tlv)) + if ((err = tlv_expect_sequence (tlv))) goto bailout; startlevel = tlv_parser_level (tlv); @@ -2000,12 +2003,12 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, { where = "bag-sequence"; tlv_parser_dump_state (where, NULL, tlv); - if (tlv_expect_sequence (tlv)) + if ((err = tlv_expect_sequence (tlv))) goto bailout; - if (tlv_next (tlv)) + if ((err = tlv_next (tlv))) goto bailout; - if (tlv_expect_object_id (tlv, &oid, &oidlen)) + if ((err = tlv_expect_object_id (tlv, &oid, &oidlen))) goto bailout; if (oidlen == DIM(oid_encryptedData) From 214d3ffe0f91b1a4ce11a278289fedef18323bb1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 5 Feb 2024 07:59:02 +0100 Subject: [PATCH 354/869] gpgsm: Increase salt size in pkcs#12 parser. * sm/minip12.c (parse_bag_encrypted_data): Need 32 bytes. -- GnuPG-bug-id: 6757 --- sm/minip12.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sm/minip12.c b/sm/minip12.c index 84a5f423c..4a1fab050 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -677,7 +677,7 @@ parse_bag_encrypted_data (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv) const unsigned char *data; size_t datalen; int intval; - char salt[20]; + char salt[32]; size_t saltlen; char iv[16]; unsigned int iter; From e5f24218fcd8a3e59ed638a27b85d7b9c1295d4c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 5 Feb 2024 08:35:16 +0100 Subject: [PATCH 355/869] doc: Improve warning for --use-embedded-filename. -- GnuPG-bug-id: 6972 --- doc/gpg.texi | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 93abd45cd..748c02da6 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -3360,9 +3360,23 @@ to display the message. This option overrides @option{--set-filename}. @itemx --no-use-embedded-filename @opindex use-embedded-filename Try to create a file with a name as embedded in the data. This can be -a dangerous option as it enables overwriting files. Defaults to no. +a dangerous option as it enables overwriting files by giving the +sender control on how to store files. Defaults to no. Note that the option @option{--output} overrides this option. +A better approach than using this option is to decrypt to a temporary +filename and then rename that file to the embedded file name after +checking that the embedded filename is harmless. When using the +@option{--status-fd} option gpg tells the filename as part of the +PLAINTEXT status message. If the filename is important, the use of +@command{gpgtar} is another option because gpgtar will never overwrite +a file but decrypt the files to a new directory. + +Note also that unless a modern version 5 signature is used the +embedded filename is not part of the signed data. + + + @item --cipher-algo @var{name} @opindex cipher-algo Use @var{name} as cipher algorithm. Running the program with the From 5842eee80523ad1bbfa86d61b62875beacc33f9d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 5 Feb 2024 08:53:06 +0100 Subject: [PATCH 356/869] doc: Suggest the use of a fingerprint for --default-key. -- GnuPG-bug-id: 6975 --- doc/gpg.texi | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 748c02da6..2f5b613d8 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1290,19 +1290,22 @@ are usually found in the option file. @item --default-key @var{name} @opindex default-key -Use @var{name} as the default key to sign with. If this option is not -used, the default key is the first key found in the secret keyring. -Note that @option{-u} or @option{--local-user} overrides this option. -This option may be given multiple times. In this case, the last key -for which a secret key is available is used. If there is no secret -key available for any of the specified values, GnuPG will not emit an -error message but continue as if this option wasn't given. +Use @var{name} as the default key to sign with. It is suggested to +use a fingerprint or at least a long keyID for @var{name}. If this +option is not used, the default key is the first key found in the +secret keyring. Note that @option{-u} or @option{--local-user} +overrides this option. This option may be given multiple times. In +this case, the last key for which a secret key is available is used. +If there is no secret key available for any of the specified values, +GnuPG will not emit an error message but continue as if this option +wasn't given. + @item --default-recipient @var{name} @opindex default-recipient Use @var{name} as default recipient if option @option{--recipient} is not used and don't ask if this is a valid one. @var{name} must be -non-empty. +non-empty and it is suggested to use a fingerprint for @var{name}. @item --default-recipient-self @opindex default-recipient-self @@ -2336,19 +2339,21 @@ the key in this file is fully valid. @opindex encrypt-to Same as @option{--recipient} but this one is intended for use in the options file and may be used with your own user-id as an -"encrypt-to-self". These keys are only used when there are other -recipients given either by use of @option{--recipient} or by the asked -user id. No trust checking is performed for these user ids and even -disabled keys can be used. +"encrypt-to-self". It is suggested to use a fingerprint or at least a +long keyID for @var{name}. These keys are only used when there are +other recipients given either by use of @option{--recipient} or by the +asked user id. No trust checking is performed for these user ids and +even disabled keys can be used. @item --hidden-encrypt-to @var{name} @opindex hidden-encrypt-to -Same as @option{--hidden-recipient} but this one is intended for use in the -options file and may be used with your own user-id as a hidden -"encrypt-to-self". These keys are only used when there are other -recipients given either by use of @option{--recipient} or by the asked user id. -No trust checking is performed for these user ids and even disabled -keys can be used. +Same as @option{--hidden-recipient} but this one is intended for use +in the options file and may be used with your own user-id as a hidden +"encrypt-to-self". It is suggested to use a fingerprint or at least a +long keyID for @var{name}. These keys are only used when there are +other recipients given either by use of @option{--recipient} or by the +asked user id. No trust checking is performed for these user ids and +even disabled keys can be used. @item --no-encrypt-to @opindex no-encrypt-to From 302afcb6f6af1dc88357acacfaa6829f0717b1c6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 10 Feb 2024 14:24:50 +0100 Subject: [PATCH 357/869] 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 --- common/status.h | 1 + common/t-support.h | 13 ++-- doc/DETAILS | 6 ++ doc/gpg.texi | 23 +++++++ doc/gpgv.texi | 5 +- g10/Makefile.am | 6 +- g10/gpg.c | 39 ++++++++--- g10/gpgv.c | 30 ++++++++- g10/keydb.h | 1 + g10/keyid.c | 124 +++++++++++++++++++++++++++++++++++ g10/main.h | 2 + g10/mainproc.c | 19 +++--- g10/options.h | 4 ++ g10/t-keydb-get-keyblock.c | 9 --- g10/t-keydb.c | 10 --- g10/t-keyid.c | 129 +++++++++++++++++++++++++++++++++++++ g10/t-stutter.c | 9 --- g10/test-stubs.c | 18 ++++++ g10/test.c | 1 + g10/verify.c | 33 +++++++++- 20 files changed, 424 insertions(+), 58 deletions(-) create mode 100644 g10/t-keyid.c diff --git a/common/status.h b/common/status.h index d249174d1..0a1266d3c 100644 --- a/common/status.h +++ b/common/status.h @@ -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, diff --git a/common/t-support.h b/common/t-support.h index 7aa46c00c..aa1b560fc 100644 --- a/common/t-support.h +++ b/common/t-support.h @@ -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) diff --git a/doc/DETAILS b/doc/DETAILS index fd95e511c..29e39708b 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -527,6 +527,12 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: --assert-signer is used. The fingerprint is printed with uppercase hex digits. +*** ASSERT_PUBKEY_ALGO + 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 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 diff --git a/doc/gpg.texi b/doc/gpg.texi index 2f5b613d8..26e0ebdcd 100644 --- a/doc/gpg.texi +++ b/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 diff --git a/doc/gpgv.texi b/doc/gpgv.texi index 2dd9576b6..54ab23383 100644 --- a/doc/gpgv.texi +++ b/doc/gpgv.texi @@ -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 - diff --git a/g10/Makefile.am b/g10/Makefile.am index c5691f551..e8d8e9017 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -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 diff --git a/g10/gpg.c b/g10/gpg.c index d4fbecdbe..1d0b9d09e 100644 --- a/g10/gpg.c +++ b/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); } diff --git a/g10/gpgv.c b/g10/gpgv.c index f2895563e..c3b09f752 100644 --- a/g10/gpgv.c +++ b/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); } diff --git a/g10/keydb.h b/g10/keydb.h index b18f6e93a..798c24da3 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -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 ); diff --git a/g10/keyid.c b/g10/keyid.c index 89bba0d7a..ce977de0b 100644 --- a/g10/keyid.c +++ b/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. */ diff --git a/g10/main.h b/g10/main.h index b29e23e51..2482fbde2 100644 --- a/g10/main.h +++ b/g10/main.h @@ -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 ); diff --git a/g10/mainproc.c b/g10/mainproc.c index 430d7ff08..5f3f6df86 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -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"), diff --git a/g10/options.h b/g10/options.h index 146b78361..1e1110334 100644 --- a/g10/options.h +++ b/g10/options.h @@ -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 diff --git a/g10/t-keydb-get-keyblock.c b/g10/t-keydb-get-keyblock.c index e40be9cc1..90ce6e9a6 100644 --- a/g10/t-keydb-get-keyblock.c +++ b/g10/t-keydb-get-keyblock.c @@ -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; -} diff --git a/g10/t-keydb.c b/g10/t-keydb.c index 9055d5b94..4c78dac48 100644 --- a/g10/t-keydb.c +++ b/g10/t-keydb.c @@ -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; -} diff --git a/g10/t-keyid.c b/g10/t-keyid.c new file mode 100644 index 000000000..d42399027 --- /dev/null +++ b/g10/t-keyid.c @@ -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 . + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#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; +} diff --git a/g10/t-stutter.c b/g10/t-stutter.c index 7b2ea4b37..503a92004 100644 --- a/g10/t-stutter.c +++ b/g10/t-stutter.c @@ -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; -} diff --git a/g10/test-stubs.c b/g10/test-stubs.c index 6ae0f4eb7..d9bead754 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -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; +} diff --git a/g10/test.c b/g10/test.c index 648148a10..f6c697a35 100644 --- a/g10/test.c +++ b/g10/test.c @@ -15,6 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . + * SPDX-License-Identifier: GPL-3.0-or-later */ #include diff --git a/g10/verify.c b/g10/verify.c index e9792939d..1c3de767c 100644 --- a/g10/verify.c +++ b/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); + } +} From 27f66148f7f0c0e4c30488b47970900256ed5390 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 15 Feb 2024 14:38:10 +0900 Subject: [PATCH 358/869] dirmngr:w32: Add include files. * dirmngr/ks-engine-ldap.c: Include winldap.h and winber.h. -- Definition of ber_free is in winber.h. Signed-off-by: NIIBE Yutaka --- dirmngr/ks-engine-ldap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index c2a210542..d404a04ac 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -31,6 +31,8 @@ # define WINVER 0x0500 /* Same as in common/sysutils.c */ # endif # include +# include +# include # include #endif From 874918ab915263b5e3de5ad6296045d936164542 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 15 Feb 2024 14:40:33 +0900 Subject: [PATCH 359/869] common,dirmngr:w32: Add include files. * common/dynload.h: Include windows.h. Don't define RTLD_LAZY, if already defined. * common/init.c: Include wctype.h. * dirmngr/certcache.c: Include wincrypt.h. * dirmngr/dns-stuff.c: Include ws2tcpip.h. -- GnuPG-bug-id: 5894 Signed-off-by: NIIBE Yutaka --- common/dynload.h | 11 +++++++---- common/init.c | 1 + dirmngr/certcache.c | 3 ++- dirmngr/dns-stuff.c | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/common/dynload.h b/common/dynload.h index 6ac7b4e17..af3906c81 100644 --- a/common/dynload.h +++ b/common/dynload.h @@ -34,12 +34,15 @@ #ifndef __MINGW32__ # include #else -# include -# include -# include +# ifdef HAVE_WINSOCK2_H +# include +# endif +# include # include "utf8conv.h" # include "mischelp.h" -# define RTLD_LAZY 0 +# ifndef RTLD_LAZY +# define RTLD_LAZY 0 +# endif static inline void * dlopen (const char *name, int flag) diff --git a/common/init.c b/common/init.c index 62a48f8c7..8ea51c8b0 100644 --- a/common/init.c +++ b/common/init.c @@ -37,6 +37,7 @@ # include # endif # include +# include #endif #include diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index 6b194f31c..b7b5b3d15 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -100,7 +100,8 @@ static unsigned int any_cert_of_class; #ifdef HAVE_W32_SYSTEM -/* We load some functions dynamically. Provide typedefs for tehse +#include +/* We load some functions dynamically. Provide typedefs for these * functions. */ typedef HCERTSTORE (WINAPI *CERTOPENSYSTEMSTORE) (HCRYPTPROV hProv, LPCSTR szSubsystemProtocol); diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c index 0edbc0442..270717215 100644 --- a/dirmngr/dns-stuff.c +++ b/dirmngr/dns-stuff.c @@ -34,6 +34,7 @@ # define WIN32_LEAN_AND_MEAN # ifdef HAVE_WINSOCK2_H # include +# include # endif # include # include From 04cbc3074aa98660b513a80f623a7e9f0702c7c9 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 15 Feb 2024 15:38:34 +0900 Subject: [PATCH 360/869] dirmngr: Fix proxy with TLS. * dirmngr/http.c (proxy_get_token, run_proxy_connect): Always available regardless of USE_TLS. (run_proxy_connect): Use log_debug_string. (send_request): Remove USE_TLS. -- Since the commit of 1009e4e5f71347a1fe194e59a9d88c8034a67016 Building with TLS library is mandatory. GnuPG-bug-id: 6997 Signed-off-by: NIIBE Yutaka --- dirmngr/http.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/dirmngr/http.c b/dirmngr/http.c index a6892479e..084f65ed8 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2362,7 +2362,6 @@ run_gnutls_handshake (http_t hd, const char *server) * NULL, decode the string and use this as input from teh server. On * success the final output token is stored at PROXY->OUTTOKEN and * OUTTOKLEN. IF the authentication succeeded OUTTOKLEN is zero. */ -#ifdef USE_TLS static gpg_error_t proxy_get_token (proxy_info_t proxy, const char *inputstring) { @@ -2530,11 +2529,9 @@ proxy_get_token (proxy_info_t proxy, const char *inputstring) #endif /*!HAVE_W32_SYSTEM*/ } -#endif /*USE_TLS*/ /* Use the CONNECT method to proxy our TLS stream. */ -#ifdef USE_TLS static gpg_error_t run_proxy_connect (http_t hd, proxy_info_t proxy, const char *httphost, const char *server, @@ -2586,7 +2583,7 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, hd->keep_alive = !auth_basic; /* We may need to send more requests. */ if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) - log_debug_with_string (request, "http.c:proxy:request:"); + log_debug_string (request, "http.c:proxy:request:"); if (!hd->fp_write) { @@ -2743,7 +2740,6 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, xfree (tmpstr); return err; } -#endif /*USE_TLS*/ /* Make a request string using a standard proxy. On success the @@ -2903,7 +2899,6 @@ send_request (ctrl_t ctrl, goto leave; } -#if USE_TLS if (use_http_proxy && hd->uri->use_tls) { err = run_proxy_connect (hd, proxy, httphost, server, port); @@ -2915,7 +2910,6 @@ send_request (ctrl_t ctrl, * clear the flag to indicate this. */ use_http_proxy = 0; } -#endif /* USE_TLS */ #if HTTP_USE_NTBTLS err = run_ntbtls_handshake (hd); From 037067853609bc615b1e80cb4dede2fe302ac206 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 15 Feb 2024 14:52:35 +0100 Subject: [PATCH 361/869] speedo: Add config variable for the timestamp service. -- --- build-aux/speedo.mk | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index d69556472..8946c764c 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -51,10 +51,13 @@ # # This is greped by the Makefile. # RELEASE_ARCHIVE=foo@somehost:tarball-archive # -# # The key used to sign the released sources. +# # The key used to sign the GnuPG sources. # # This is greped by the Makefile. # RELEASE_SIGNKEY=6DAA6E64A76D2840571B4902528897B826403ADA # +# # The key used to sign the VERSION files of some MSI installers. +# VERSION_SIGNKEY=02F38DFF731FF97CB039A1DA549E695E905BA208 +# # # For signing Windows binaries we need to employ a Windows machine. # # We connect to this machine via ssh and take the connection # # parameters via .ssh/config. For example a VM could be specified @@ -74,6 +77,9 @@ # # This is greped by the Makefile. # AUTHENTICODE_TOOL="C:\Program Files (x86)\Windows Kits\10\bin\signtool.exe" # +# # The URL for the timestamping service +# AUTHENTICODE_TSURL=http://rfc3161timestamp.globalsign.com/advanced +# # # To use osslsigncode the follwing entries are required and # # an empty string must be given for AUTHENTICODE_SIGNHOST. # # They are greped by the Makefile. @@ -242,6 +248,7 @@ $(1) = $$(shell grep '^[[:blank:]]*$(1)[[:blank:]]*=' $$$$HOME/.gnupg-autogen.rc endef $(eval $(call READ_AUTOGEN_template,AUTHENTICODE_SIGNHOST)) $(eval $(call READ_AUTOGEN_template,AUTHENTICODE_TOOL)) +$(eval $(call READ_AUTOGEN_template,AUTHENTICODE_TSURL)) $(eval $(call READ_AUTOGEN_template,AUTHENTICODE_KEY)) $(eval $(call READ_AUTOGEN_template,AUTHENTICODE_CERTS)) $(eval $(call READ_AUTOGEN_template,OSSLSIGNCODE)) @@ -1350,7 +1357,7 @@ define AUTHENTICODE_sign scp $(1) "$(AUTHENTICODE_SIGNHOST):a.exe" ;\ ssh "$(AUTHENTICODE_SIGNHOST)" '$(AUTHENTICODE_TOOL)' sign \ /a /n '"g10 Code GmbH"' \ - /tr 'http://rfc3161timestamp.globalsign.com/advanced' /td sha256 \ + /tr '$(AUTHENTICODE_TSURL)' /td sha256 \ /fd sha256 /du https://gnupg.org a.exe ;\ scp "$(AUTHENTICODE_SIGNHOST):a.exe" $(2);\ echo "speedo: signed file is '$(2)'" ;\ @@ -1361,13 +1368,13 @@ define AUTHENTICODE_sign -pkcs11module $(SCUTEMODULE) \ -certs $(AUTHENTICODE_CERTS) \ -h sha256 -n GnuPG -i https://gnupg.org \ - -ts http://rfc3161timestamp.globalsign.com/advanced \ + -ts $(AUTHENTICODE_TSURL) \ -in $(1) -out $(2).tmp ; mv $(2).tmp $(2) ; \ elif [ -e "$(AUTHENTICODE_KEY)" ]; then \ echo "speedo: Signing using key $(AUTHENTICODE_KEY)";\ osslsigncode sign -certs $(AUTHENTICODE_CERTS) \ -pkcs12 $(AUTHENTICODE_KEY) -askpass \ - -ts "http://timestamp.globalsign.com/scripts/timstamp.dll" \ + -ts "$(AUTHENTICODE_TSURL)" \ -h sha256 -n GnuPG -i https://gnupg.org \ -in $(1) -out $(2) ;\ else \ From 848546b05ab0ff6abd47724ecfab73bf32dd4c01 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 16 Feb 2024 11:31:37 +0900 Subject: [PATCH 362/869] dirmngr: Fix the regression of use of proxy for TLS connection. * dirmngr/http.c (run_proxy_connect): Don't set keep_alive, since it causes resource leak of FP_WRITE. Don't try to read response body to fix the hang. -- GnuPG-bug-id: 6997 Signed-off-by: NIIBE Yutaka --- dirmngr/http.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/dirmngr/http.c b/dirmngr/http.c index 084f65ed8..ac7e13241 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2553,6 +2553,7 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, * RFC-4559 - SPNEGO-based Kerberos and NTLM HTTP Authentication */ auth_basic = !!proxy->uri->auth; + hd->keep_alive = 0; /* For basic authentication we need to send just one request. */ if (auth_basic @@ -2574,13 +2575,12 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, httphost ? httphost : server, port, authhdr ? authhdr : "", - auth_basic? "" : "Connection: keep-alive\r\n"); + hd->keep_alive? "Connection: keep-alive\r\n" : ""); if (!request) { err = gpg_error_from_syserror (); goto leave; } - hd->keep_alive = !auth_basic; /* We may need to send more requests. */ if (opt_debug || (hd->flags & HTTP_FLAG_LOG_RESP)) log_debug_string (request, "http.c:proxy:request:"); @@ -2607,16 +2607,6 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, if (err) goto leave; - { - unsigned long count = 0; - - while (es_getc (hd->fp_read) != EOF) - count++; - if (opt_debug) - log_debug ("http.c:proxy_connect: skipped %lu bytes of response-body\n", - count); - } - /* Reset state. */ es_clearerr (hd->fp_read); ((cookie_t)(hd->read_cookie))->up_to_empty_line = 1; From 2810b934647edd483996bee1f5f9256a162b2705 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 16 Feb 2024 16:24:26 +0900 Subject: [PATCH 363/869] dirmngr: Fix keep-alive flag handling. * dirmngr/http.c (run_proxy_connect): Set KEEP_ALIVE if not Basic Authentication. Fix resource leak of FP_WRITE. -- GnuPG-bug-id: 6997 Signed-off-by: NIIBE Yutaka --- dirmngr/http.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dirmngr/http.c b/dirmngr/http.c index ac7e13241..e4c719348 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -2553,7 +2553,7 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, * RFC-4559 - SPNEGO-based Kerberos and NTLM HTTP Authentication */ auth_basic = !!proxy->uri->auth; - hd->keep_alive = 0; + hd->keep_alive = !auth_basic; /* We may need to send more requests. */ /* For basic authentication we need to send just one request. */ if (auth_basic @@ -2717,6 +2717,14 @@ run_proxy_connect (http_t hd, proxy_info_t proxy, } leave: + if (hd->keep_alive) + { + es_fclose (hd->fp_write); + hd->fp_write = NULL; + /* The close has released the cookie and thus we better set it + * to NULL. */ + hd->write_cookie = NULL; + } /* Restore flags, destroy stream, reset state. */ hd->flags = saved_flags; es_fclose (hd->fp_read); From ad4bc3e04d0b4225d69595efebebebdf24e03fa9 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Feb 2024 09:15:25 +0100 Subject: [PATCH 364/869] scd:p15: Take derive usage into account for decryption. * scd/app-p15.c (set_usage_string): Map usageflags.derive also to 'e'. (do_auth): Allow usageflags.sign_recover. (do_decipher): Allow usageflags.derive. (do_with_keygrip): Take usageflags.derive into account. (do_gettatr): Ditto. (do_decipher): Take a missing AODF for authentication not needed. -- This is required for D-Trust ECC cards. The AODF thing is unrelated but seems to be a good idea. GnuPG-bug-id: 7000 --- scd/app-p15.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 2bb90beaa..347683f57 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -305,7 +305,7 @@ struct prkdf_object_s keyaccess_flags_t accessflags; /* Extended key usage flags. Only used if .valid is set. This - * information is computed from an associated certificate15. */ + * information is computed from an associated certificate. */ struct { unsigned int valid:1; unsigned int sign:1; @@ -4214,7 +4214,8 @@ set_usage_string (char usage[5], prkdf_object_t prkdf) && (!prkdf->extusage.valid || prkdf->extusage.sign)) usage[usagelen++] = 'c'; if ((prkdf->usageflags.decrypt - || prkdf->usageflags.unwrap) + || prkdf->usageflags.unwrap + || prkdf->usageflags.derive) && (!prkdf->extusage.valid || prkdf->extusage.encr)) usage[usagelen++] = 'e'; if ((prkdf->usageflags.sign @@ -4683,7 +4684,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) if ((name[1] == 'A' && (prkdf->usageflags.sign || prkdf->usageflags.sign_recover)) || (name[1] == 'E' && (prkdf->usageflags.decrypt - || prkdf->usageflags.unwrap)) + || prkdf->usageflags.unwrap + || prkdf->usageflags.derive)) || (name[1] == 'S' && (prkdf->usageflags.sign || prkdf->usageflags.sign_recover))) break; @@ -5927,7 +5929,8 @@ do_auth (app_t app, ctrl_t ctrl, const char *keyidstr, err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf); if (err) return err; - if (!(prkdf->usageflags.sign || prkdf->gpgusage.auth)) + if (!(prkdf->usageflags.sign || prkdf->usageflags.sign_recover + || prkdf->gpgusage.auth)) { log_error ("p15: key %s may not be used for authentication\n", keyidstr); return gpg_error (GPG_ERR_WRONG_KEY_USAGE); @@ -5970,6 +5973,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, return err; if (!(prkdf->usageflags.decrypt || prkdf->usageflags.unwrap + || prkdf->usageflags.derive || prkdf->gpgusage.encr )) { log_error ("p15: key %s may not be used for decryption\n", keyidstr); @@ -5979,17 +5983,18 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, /* Find the authentication object to this private key object. */ if (!prkdf->authid) { - log_error ("p15: no authentication object defined for %s\n", keyidstr); - /* fixme: we might want to go ahead and do without PIN - verification. */ - return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); + log_info ("p15: no authentication object defined for %s\n", keyidstr); + aodf = NULL; + } + else + { + for (aodf = app->app_local->auth_object_info; aodf; aodf = aodf->next) + if (aodf->objidlen == prkdf->authidlen + && !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen)) + break; + if (!aodf) + log_info ("p15: no authentication for %s needed\n", keyidstr); } - for (aodf = app->app_local->auth_object_info; aodf; aodf = aodf->next) - if (aodf->objidlen == prkdf->authidlen - && !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen)) - break; - if (!aodf) - log_info ("p15: no authentication for %s needed\n", keyidstr); /* We need some more info about the key - get the keygrip to * populate these fields. */ @@ -6274,7 +6279,8 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, } else if (capability == GCRY_PK_USAGE_ENCR) { - if (!(prkdf->usageflags.decrypt || prkdf->usageflags.unwrap)) + if (!(prkdf->usageflags.decrypt || prkdf->usageflags.unwrap + || prkdf->usageflags.derive)) continue; } else if (capability == GCRY_PK_USAGE_AUTH) From 3341017ff12599ff627b37fbe3c516df937c7989 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 19 Feb 2024 16:50:22 +0100 Subject: [PATCH 365/869] scd:p15: Handle duplicate certificate ids. * scd/app-p15.c (struct app_local_s): Add field cdf_dup_counter. (objid_in_cdflist_p): New. (read_p15_info): Clear the counter. (read_ef_cdf): Detect and fix duplicate IDs. -- GnuPG-bug-id: 7001 Reported-by: Mario Haustein --- scd/app-p15.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 347683f57..df7a74355 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -520,6 +520,9 @@ struct app_local_s /* Information on all useful certificates. */ cdf_object_t useful_certificate_info; + /* Counter to make object ids of certificates unique. */ + unsigned int cdf_dup_counter; + /* Information on all public keys. */ prkdf_object_t public_key_info; @@ -2419,6 +2422,22 @@ read_ef_pukdf (app_t app, unsigned short fid, pukdf_object_t *result) } +/* Return true id CDFLIST has the given object id. */ +static int +objid_in_cdflist_p (cdf_object_t cdflist, + const unsigned char *objid, size_t objidlen) +{ + cdf_object_t cdf; + + if (!objid || !objidlen) + return 0; + for (cdf = cdflist; cdf; cdf = cdf->next) + if (cdf->objidlen == objidlen && !memcmp (cdf->objid, objid, objidlen)) + return 1; + return 0; +} + + /* Read and parse the Certificate Directory Files identified by FID. On success a newlist of CDF object gets stored at RESULT and the caller is then responsible of releasing this list. On error a @@ -2464,6 +2483,7 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result) unsigned long ul; const unsigned char *objid; size_t objidlen; + int objidextralen; err = parse_ber_header (&p, &n, &class, &tag, &constructed, &ndef, &objlen, &hdrlen); @@ -2588,8 +2608,19 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result) label = NULL; } - cdf->objidlen = objidlen; - cdf->objid = xtrymalloc (objidlen); + /* Card's have been found in the wild which do not have unique + * IDs for their certificate objects. If we detect this we + * append a counter to the ID. */ + objidextralen = + (objid_in_cdflist_p (cdflist, objid, objidlen) + || objid_in_cdflist_p (app->app_local->certificate_info, + objid, objidlen) + || objid_in_cdflist_p (app->app_local->trusted_certificate_info, + objid, objidlen) + || objid_in_cdflist_p (app->app_local->useful_certificate_info, + objid, objidlen)); + cdf->objidlen = objidlen + objidextralen; + cdf->objid = xtrymalloc (objidlen + objidextralen); if (!cdf->objid) { err = gpg_error_from_syserror (); @@ -2597,6 +2628,16 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result) goto leave; } memcpy (cdf->objid, objid, objidlen); + if (objidextralen) + { + if (app->app_local->cdf_dup_counter == 255) + { + log_error ("p15: too many duplicate certificate ids\n"); + err = gpg_error (GPG_ERR_TOO_MANY); + goto parse_error; + } + cdf->objid[objidlen] = ++app->app_local->cdf_dup_counter; + } cdf->pathlen = objlen/2; for (i=0; i < cdf->pathlen; i++, pp += 2, nn -= 2) @@ -3664,6 +3705,7 @@ read_p15_info (app_t app) log_assert (!app->app_local->certificate_info); log_assert (!app->app_local->trusted_certificate_info); log_assert (!app->app_local->useful_certificate_info); + app->app_local->cdf_dup_counter = 0; err = read_ef_cdf (app, app->app_local->odf.certificates, 'c', &app->app_local->certificate_info); if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA) From 1e496cf2e5271b1bf07a6252d0fbc6ac8c947a0a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Feb 2024 10:29:25 +0100 Subject: [PATCH 366/869] scd:p15: Take derive usage into account for decryption (2). * scd/app-p15.c (do_getattr): Yet another palce to fix. -- GnuPG-bug-id: 7000 Co-authored-by: Mario Haustein --- scd/app-p15.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index df7a74355..cfe369a15 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -4936,7 +4936,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) } else { - if (prkdf->usageflags.decrypt || prkdf->usageflags.unwrap) + if (prkdf->usageflags.decrypt || prkdf->usageflags.unwrap + || prkdf->usageflags.derive) break; } } From 557f29d2c16e8d31729a20f56e2c18b0b0726414 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Mon, 19 Feb 2024 10:22:35 +0100 Subject: [PATCH 367/869] scd:p15: Add ECC support for D-Trust Card 4.1/4.4 * scd/app-p15.c (do_sign): Add MSE RESTORE parameters for D-Trust ECC cards. (do_decipher): Ditto. --- scd/app-p15.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index cfe369a15..43557e08b 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -5829,9 +5829,8 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo, { if (prkdf->is_ecc) { - /* Not implemented due to lacking test hardware. */ - log_info ("Note: ECC is not yet implemented for DTRUST 4 cards\n"); - err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + err = iso7816_manage_security_env (app_get_slot (app), + 0xf3, 0x21, NULL, 0); } else { @@ -6090,9 +6089,8 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr, { if (prkdf->is_ecc) { - /* Not implemented due to lacking test hardware. */ - log_info ("Note: ECC is not yet implemented for DTRUST 4 cards\n"); - err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + err = iso7816_manage_security_env (app_get_slot (app), + 0xF3, 0x39, NULL, 0); } else { From 3aa02027cdc3ce07f9884cd9c755cdc87133fad6 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Mon, 19 Feb 2024 10:22:08 +0100 Subject: [PATCH 368/869] scd:p15: Fix typo in a comment --- scd/app-p15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scd/app-p15.c b/scd/app-p15.c index 43557e08b..6af10b46b 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -4704,7 +4704,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) /* We return the ID of the first private key capable of the * requested action. If any gpgusage flag has been set for the - * card we consult the gpgusage flags and not the regualr usage + * card we consult the gpgusage flags and not the regular usage * flags. */ /* FIXME: This changed: Note that we do not yet return From 95bc592ab547cd88f912d15973fa854b46f2f4d1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Feb 2024 11:40:49 +0100 Subject: [PATCH 369/869] g13: Allow command line style "g13 mount foo". * g13/g13.c (main): Set flag ARGPARSE_FLAG_COMMAND. -- This requires gpgrt 1.48. Of course "g13 --mount foo" continues to work. --- g13/g13.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/g13/g13.c b/g13/g13.c index cb1880f80..4942e7893 100644 --- a/g13/g13.c +++ b/g13/g13.c @@ -457,6 +457,9 @@ main (int argc, char **argv) pargs.argv = &argv; pargs.flags |= (ARGPARSE_FLAG_RESET | ARGPARSE_FLAG_KEEP +#if GPGRT_VERSION_NUMBER >= 0x013000 /* >= 1.48 */ + | ARGPARSE_FLAG_COMMAND +#endif | ARGPARSE_FLAG_SYS | ARGPARSE_FLAG_USER); From a09157ccb2bdd9b9197e64eb9d60953c1d5c46ae Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 21 Feb 2024 14:06:37 +0100 Subject: [PATCH 370/869] wks: Allow command style args for gpg-wks-client. * tools/gpg-wks-client.c (wrong_args): Take two args. Change all callers. (main): Pass ARGPARSE_FLAG_COMMAND for recent gpgrt version. -- This requires gpgrt 1.48. Of course "gpg-wks-client --create ..." continues to work. --- doc/wks.texi | 2 ++ tools/gpg-wks-client.c | 30 +++++++++++++++++++----------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/doc/wks.texi b/doc/wks.texi index a8d0455e5..2870e52d8 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -136,6 +136,8 @@ The command @option{--print-wkd-url} prints the URLs used to fetch the key for the given user-ids from WKD. The meanwhile preferred format with sub-domains is used here. +All commands may also be given without the two leading dashes. + @mansect options @noindent @command{gpg-wks-client} understands these options: diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index fa0278ae0..edb31f38b 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -154,7 +154,7 @@ static char **blacklist_array; static size_t blacklist_array_len; -static void wrong_args (const char *text) GPGRT_ATTR_NORETURN; +static void wrong_args (const char *t1, const char *t2) GPGRT_ATTR_NORETURN; static void add_blacklist (const char *fname); static gpg_error_t proc_userid_from_stdin (gpg_error_t (*func)(const char *), const char *text); @@ -204,10 +204,15 @@ my_strusage( int level ) static void -wrong_args (const char *text) +wrong_args (const char *text, const char *text2) { - es_fprintf (es_stderr, _("usage: %s [options] %s\n"), - gpgrt_strusage (11), text); +#if GPGRT_VERSION_NUMBER >= 0x013000 /* >= 1.48 */ + /* Skip the leading dashes if build with command support. */ + if (text[0] == '-' && text[1] == '-' && text[2]) + text += 2; +#endif + es_fprintf (es_stderr, _("usage: %s %s [options] %s\n"), + gpgrt_strusage (11), text, text2); exit (2); } @@ -315,6 +320,9 @@ main (int argc, char **argv) pargs.argc = &argc; pargs.argv = &argv; pargs.flags = ARGPARSE_FLAG_KEEP; +#if GPGRT_VERSION_NUMBER >= 0x013000 /* >= 1.48 */ + pargs.flags |= ARGPARSE_FLAG_COMMAND; +#endif cmd = parse_arguments (&pargs, opts); gpgrt_argparse (NULL, &pargs, NULL); @@ -394,7 +402,7 @@ main (int argc, char **argv) else { if (argc != 1) - wrong_args ("--supported DOMAIN"); + wrong_args ("--supported", "DOMAIN"); err = command_supported (argv[0]); if (err && gpg_err_code (err) != GPG_ERR_FALSE) log_error ("checking support failed: %s\n", gpg_strerror (err)); @@ -403,7 +411,7 @@ main (int argc, char **argv) case aCreate: if (argc != 2) - wrong_args ("--create FINGERPRINT USER-ID"); + wrong_args ("--create", "FINGERPRINT USER-ID"); err = command_create (argv[0], argv[1]); if (err) log_error ("creating request failed: %s\n", gpg_strerror (err)); @@ -411,7 +419,7 @@ main (int argc, char **argv) case aReceive: if (argc) - wrong_args ("--receive < MIME-DATA"); + wrong_args ("--receive", "< MIME-DATA"); err = wks_receive (es_stdin, command_receive_cb, NULL); if (err) log_error ("processing mail failed: %s\n", gpg_strerror (err)); @@ -419,7 +427,7 @@ main (int argc, char **argv) case aRead: if (argc) - wrong_args ("--read < WKS-DATA"); + wrong_args ("--read", "< WKS-DATA"); err = read_confirmation_request (es_stdin); if (err) log_error ("processing mail failed: %s\n", gpg_strerror (err)); @@ -427,7 +435,7 @@ main (int argc, char **argv) case aCheck: if (argc != 1) - wrong_args ("--check USER-ID"); + wrong_args ("--check", "USER-ID"); err = command_check (argv[0]); break; @@ -444,12 +452,12 @@ main (int argc, char **argv) else if (argc == 2) err = wks_cmd_install_key (*argv, argv[1]); else - wrong_args ("--install-key [FILE|FINGERPRINT USER-ID]"); + wrong_args ("--install-key", "[FILE|FINGERPRINT USER-ID]"); break; case aRemoveKey: if (argc != 1) - wrong_args ("--remove-key USER-ID"); + wrong_args ("--remove-key", "USER-ID"); err = wks_cmd_remove_key (*argv); break; From 2372f6a4035cefd5ac1852e95dc50de89cc73af6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 21 Feb 2024 15:55:14 +0100 Subject: [PATCH 371/869] gpg: Fix gpg_mpi_write for the unused opaque case. * g10/build-packet.c (gpg_mpi_write): Take care of the fact that get_opaque already returns a bit-exact value. -- Fixes-commit: ab17f7b6c392782718f57eaea94fc18a0ff49389 Reported-by: Falko Strenzke --- g10/build-packet.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/g10/build-packet.c b/g10/build-packet.c index 67d4a6eef..19a13760a 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -306,7 +306,9 @@ gpg_mpi_write (iobuf_t out, gcry_mpi_t a, unsigned int *r_nwritten) p = gcry_mpi_get_opaque (a, &nbits); if (p) { - /* Strip leading zero bits. */ + /* First get nbits back to full bytes. */ + nbits = ((nbits + 7) / 8) * 8; + /* Then strip leading zero bits. */ for (; nbits >= 8 && !*p; p++, nbits -= 8) ; if (nbits >= 8 && !(*p & 0x80)) From 40227e42ea0f2f1cf9c9f506375446648df17e8d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 22 Feb 2024 17:04:15 +0100 Subject: [PATCH 372/869] doc: Document the "grp" record in colon listings. -- --- doc/DETAILS | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/DETAILS b/doc/DETAILS index fd95e511c..a04269ede 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -167,11 +167,12 @@ described here. The value is quoted like a C string to avoid control characters (the colon is quoted =\x3a=). For a "pub" record this field is - not used on --fixed-list-mode. A UAT record puts the attribute + not used on --fixed-list-mode. A "uat" record puts the attribute subpacket count here, a space, and then the total attribute subpacket size. In gpgsm the issuer name comes here. The FPR and FP2 records store the fingerprints here. The fingerprint of a - revocation key is stored here. + revocation key is also stored here. A "grp" records puts the + keygrip here. *** Field 11 - Signature class @@ -185,6 +186,9 @@ described here. "rev" and "rvs" may be followed by a comma and a 2 digit hexnumber with the revocation reason. + In a "grp" record the second keygrip for combined algorithms is + given here. + *** Field 12 - Key capabilities The defined capabilities are: @@ -243,7 +247,8 @@ described here. *** Field 17 - Curve name For pub, sub, sec, ssb, crt, and crs records this field is used - for the ECC curve name. + for the ECC curve name. For combined algorithms the first and the + second algorithm name, delimited by a '+', are put here. *** Field 18 - Compliance flags From adf4db6e20931ed70ea9f8541f522192d6fd2014 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sun, 25 Feb 2024 15:55:14 +0100 Subject: [PATCH 373/869] agent: Allow GET_PASSPHRASE in restricted mode. * agent/command.c (cmd_get_passphrase): Allow use in restricted mode but ignore the cacheid. -- The use case is symmetric encryption via the extra-socket. To avoid that the gpg running on the server has access to the cache we set the cache id to NULL so that the cache is not used at all. --- agent/command.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/agent/command.c b/agent/command.c index 20ae08e9f..575456cc5 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1988,9 +1988,6 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) struct pin_entry_info_s *pi2 = NULL; int is_generated; - if (ctrl->restricted) - return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); - opt_data = has_option (line, "--data"); opt_check = has_option (line, "--check"); opt_no_ask = has_option (line, "--no-ask"); @@ -2039,7 +2036,9 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) if (!desc) return set_error (GPG_ERR_ASS_PARAMETER, "no description given"); - if (!strcmp (cacheid, "X")) + /* The only limitation in restricted mode is that we don't consider + * the cache. */ + if (ctrl->restricted || !strcmp (cacheid, "X")) cacheid = NULL; if (!strcmp (errtext, "X")) errtext = NULL; @@ -2121,7 +2120,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) entry_errtext = NULL; is_generated = !!(pi->status & PINENTRY_STATUS_PASSWORD_GENERATED); - /* We don't allow an empty passpharse in this mode. */ + /* We don't allow an empty passphrase in this mode. */ if (!is_generated && check_passphrase_constraints (ctrl, pi->pin, pi->constraints_flags, From 962058f704867082d6d00f6467a79c78e41169ca Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 27 Feb 2024 10:35:46 +0100 Subject: [PATCH 374/869] Allow tilde expansion for the foo-program options. * agent/gpg-agent.c (parse_rereadable_options): Use make_filename_try for opt.pinentry_program. Change definition accordingly. * g10/gpg.c (main): Use make_filename for agent_program, dirmngr_program, and keyboxd_program. Change definition accordingly. * sm/gpgsm.c (main): Ditto. * tools/gpg-card.c (parse_arguments): Ditto. * tools/gpg-connect-agent.c (main): Ditto. * tools/gpg-wks-client.c (parse_arguments): Likewise. Do it also for option --output. (process_confirmation_request): Print a note for a successful sent. -- GnuPG-bug-id: 7017 --- agent/agent.h | 4 ++-- agent/gpg-agent.c | 6 +++++- g10/gpg.c | 15 ++++++++++++--- g10/options.h | 6 +++--- sm/gpgsm.c | 16 +++++++++++++--- sm/gpgsm.h | 6 +++--- tools/gpg-card.c | 12 +++++++++--- tools/gpg-card.h | 6 +++--- tools/gpg-connect-agent.c | 18 ++++++++++++------ tools/gpg-wks-client.c | 8 +++++--- tools/gpg-wks.h | 6 +++--- 11 files changed, 70 insertions(+), 33 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index f0b2a334e..06bc1e046 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -86,8 +86,8 @@ struct /* Enable pinentry debugging (--debug 1024 should also be used). */ int debug_pinentry; - /* Filename of the program to start as pinentry. */ - const char *pinentry_program; + /* Filename of the program to start as pinentry (malloced). */ + char *pinentry_program; /* Filename of the program to handle daemon tasks. */ const char *daemon_program[DAEMON_MAX_TYPE]; diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index a5448ac38..5305098d2 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -864,6 +864,7 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) opt.debug = 0; opt.no_grab = 1; opt.debug_pinentry = 0; + xfree (opt.pinentry_program); opt.pinentry_program = NULL; opt.pinentry_touch_file = NULL; xfree (opt.pinentry_invisible_char); @@ -924,7 +925,10 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) case oNoGrab: opt.no_grab |= 1; break; case oGrab: opt.no_grab |= 2; break; - case oPinentryProgram: opt.pinentry_program = pargs->r.ret_str; break; + case oPinentryProgram: + xfree (opt.pinentry_program); + opt.pinentry_program = make_filename_try (pargs->r.ret_str, NULL); + break; case oPinentryTouchFile: opt.pinentry_touch_file = pargs->r.ret_str; break; case oPinentryInvisibleChar: xfree (opt.pinentry_invisible_char); diff --git a/g10/gpg.c b/g10/gpg.c index 1d0b9d09e..80cb2f38b 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -3592,9 +3592,18 @@ main (int argc, char **argv) case oPersonalCompressPreferences: pers_compress_list=pargs.r.ret_str; break; - case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; - case oKeyboxdProgram: opt.keyboxd_program = pargs.r.ret_str; break; - case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; + case oAgentProgram: + xfree (opt.agent_program); + opt.agent_program = make_filename (pargs.r.ret_str, NULL); + break; + case oKeyboxdProgram: + xfree (opt.keyboxd_program); + opt.keyboxd_program = make_filename (pargs.r.ret_str, NULL); + break; + case oDirmngrProgram: + xfree (opt.dirmngr_program); + opt.dirmngr_program = make_filename (pargs.r.ret_str, NULL); + break; case oDisableDirmngr: opt.disable_dirmngr = 1; break; case oWeakDigest: additional_weak_digest(pargs.r.ret_str); diff --git a/g10/options.h b/g10/options.h index 1e1110334..07516aab1 100644 --- a/g10/options.h +++ b/g10/options.h @@ -126,9 +126,9 @@ struct int marginals_needed; int completes_needed; int max_cert_depth; - const char *agent_program; - const char *keyboxd_program; - const char *dirmngr_program; + char *agent_program; + char *keyboxd_program; + char *dirmngr_program; int disable_dirmngr; const char *def_new_key_algo; diff --git a/sm/gpgsm.c b/sm/gpgsm.c index b3d48abce..3948372e4 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1335,8 +1335,19 @@ main ( int argc, char **argv) case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; case oChUid: break; /* Command line only (see above). */ - case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; - case oKeyboxdProgram: opt.keyboxd_program = pargs.r.ret_str; break; + + case oAgentProgram: + xfree (opt.agent_program); + opt.agent_program = make_filename (pargs.r.ret_str, NULL); + break; + case oKeyboxdProgram: + xfree (opt.keyboxd_program); + opt.keyboxd_program = make_filename (pargs.r.ret_str, NULL); + break; + case oDirmngrProgram: + xfree (opt.dirmngr_program); + opt.dirmngr_program = make_filename (pargs.r.ret_str, NULL); + break; case oDisplay: set_opt_session_env ("DISPLAY", pargs.r.ret_str); @@ -1354,7 +1365,6 @@ main ( int argc, char **argv) case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break; case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break; - case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; case oDisableDirmngr: opt.disable_dirmngr = 1; break; case oPreferSystemDirmngr: /* Obsolete */; break; case oProtectToolProgram: diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 684251fda..faa03a9f4 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -60,16 +60,16 @@ struct int use_keyboxd; /* Use the external keyboxd as storage backend. */ const char *config_filename; /* Name of the used config file. */ - const char *agent_program; + char *agent_program; - const char *keyboxd_program; + char *keyboxd_program; session_env_t session_env; char *lc_ctype; char *lc_messages; int autostart; - const char *dirmngr_program; + char *dirmngr_program; int disable_dirmngr; /* Do not do any dirmngr calls. */ const char *protect_tool_program; char *outfile; /* name of output file */ diff --git a/tools/gpg-card.c b/tools/gpg-card.c index b34b42698..22b95d0d7 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -220,9 +220,15 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) } break; - case oGpgProgram: opt.gpg_program = pargs->r.ret_str; break; - case oGpgsmProgram: opt.gpgsm_program = pargs->r.ret_str; break; - case oAgentProgram: opt.agent_program = pargs->r.ret_str; break; + case oGpgProgram: + opt.gpg_program = make_filename (pargs->r.ret_str, NULL); + break; + case oGpgsmProgram: + opt.gpgsm_program = make_filename (pargs->r.ret_str, NULL); + break; + case oAgentProgram: + opt.agent_program = make_filename (pargs->r.ret_str, NULL); + break; case oStatusFD: gnupg_set_status_fd (translate_sys2libc_fd_int (pargs->r.ret_int, 1)); diff --git a/tools/gpg-card.h b/tools/gpg-card.h index 5b49ef31e..8d7975ba9 100644 --- a/tools/gpg-card.h +++ b/tools/gpg-card.h @@ -34,9 +34,9 @@ struct unsigned int debug; int quiet; int with_colons; - const char *gpg_program; - const char *gpgsm_program; - const char *agent_program; + char *gpg_program; + char *gpgsm_program; + char *agent_program; int autostart; int no_key_lookup; /* Assume --no-key-lookup for "list". */ diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index eb897287c..cf4e64e2b 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -126,9 +126,9 @@ struct int quiet; /* Be extra quiet. */ int autostart; /* Start the server if not running. */ const char *homedir; /* Configuration directory name */ - const char *agent_program; /* Value of --agent-program. */ - const char *dirmngr_program; /* Value of --dirmngr-program. */ - const char *keyboxd_program; /* Value of --keyboxd-program. */ + char *agent_program; /* Value of --agent-program. */ + char *dirmngr_program; /* Value of --dirmngr-program. */ + char *keyboxd_program; /* Value of --keyboxd-program. */ int hex; /* Print data lines in hex format. */ int decode; /* Decode received data lines. */ int use_dirmngr; /* Use the dirmngr and not gpg-agent. */ @@ -1224,9 +1224,15 @@ main (int argc, char **argv) case oVerbose: opt.verbose++; break; case oNoVerbose: opt.verbose = 0; break; case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; - case oAgentProgram: opt.agent_program = pargs.r.ret_str; break; - case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; - case oKeyboxdProgram: opt.keyboxd_program = pargs.r.ret_str; break; + case oAgentProgram: + opt.agent_program = make_filename (pargs.r.ret_str, NULL); + break; + case oDirmngrProgram: + opt.dirmngr_program = make_filename (pargs.r.ret_str, NULL); + break; + case oKeyboxdProgram: + opt.keyboxd_program = make_filename (pargs.r.ret_str, NULL); + break; case oNoAutostart: opt.autostart = 0; break; case oNoHistory: opt.no_history = 1; break; case oHex: opt.hex = 1; break; diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index edb31f38b..d3d1b522a 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -240,16 +240,16 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) break; case oGpgProgram: - opt.gpg_program = pargs->r.ret_str; + opt.gpg_program = make_filename (pargs->r.ret_str, NULL); break; case oDirectory: - opt.directory = pargs->r.ret_str; + opt.directory = make_filename (pargs->r.ret_str, NULL); break; case oSend: opt.use_sendmail = 1; break; case oOutput: - opt.output = pargs->r.ret_str; + opt.output = make_filename (pargs->r.ret_str, NULL); break; case oFakeSubmissionAddr: fake_submission_addr = pargs->r.ret_str; @@ -1787,6 +1787,8 @@ process_confirmation_request (estream_t msg, const char *mainfpr) log_info ("no encryption key found - sending response in the clear\n"); err = send_confirmation_response (sender, address, nonce, 0, NULL); } + if (!err) + log_info ("response sent to '%s' for '%s'\n", sender, address); leave: nvc_release (nvc); diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h index 93039c1e8..4a33c5bec 100644 --- a/tools/gpg-wks.h +++ b/tools/gpg-wks.h @@ -40,9 +40,9 @@ struct int with_colons; int no_autostart; int add_revocs; - const char *output; - const char *gpg_program; - const char *directory; + char *output; + char *gpg_program; + char *directory; const char *default_from; strlist_t extra_headers; } opt; From dcab895e4cdc829f97276d2a2647594fb86cdba2 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 27 Feb 2024 11:33:21 +0100 Subject: [PATCH 375/869] gpg: Emit status lines for errors in the compression layer. * g10/compress-bz2.c: Replace all log_fatal by log_error, write_status_error, and g10_exit. (do_uncompress): Ditto. -- This gives gpgme a better way to detect corrupted data in the compression layer. GnuPG-bug-id: 6977 --- g10/compress-bz2.c | 26 +++++++++++++++++++++----- g10/compress.c | 28 ++++++++++++++++++---------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/g10/compress-bz2.c b/g10/compress-bz2.c index 2c3b86f8f..162dee96e 100644 --- a/g10/compress-bz2.c +++ b/g10/compress-bz2.c @@ -53,7 +53,11 @@ init_compress( compress_filter_context_t *zfx, bz_stream *bzs ) } if((rc=BZ2_bzCompressInit(bzs,level,0,0))!=BZ_OK) - log_fatal("bz2lib problem: %d\n",rc); + { + log_error ("bz2lib problem: %d\n",rc); + write_status_error ("bzip2.init", gpg_error (GPG_ERR_INTERNAL)); + g10_exit (2); + } zfx->outbufsize = 8192; zfx->outbuf = xmalloc( zfx->outbufsize ); @@ -80,7 +84,11 @@ do_compress(compress_filter_context_t *zfx, bz_stream *bzs, int flush, IOBUF a) if( zrc == BZ_STREAM_END && flush == BZ_FINISH ) ; else if( zrc != BZ_RUN_OK && zrc != BZ_FINISH_OK ) - log_fatal("bz2lib deflate problem: rc=%d\n", zrc ); + { + log_error ("bz2lib deflate problem: rc=%d\n", zrc ); + write_status_error ("bzip2.deflate", gpg_error (GPG_ERR_INTERNAL)); + g10_exit (2); + } n = zfx->outbufsize - bzs->avail_out; if( DBG_FILTER ) @@ -91,7 +99,7 @@ do_compress(compress_filter_context_t *zfx, bz_stream *bzs, int flush, IOBUF a) if( (rc=iobuf_write( a, zfx->outbuf, n )) ) { - log_debug("bzCompress: iobuf_write failed\n"); + log_error ("bzCompress: iobuf_write failed\n"); return rc; } } @@ -106,7 +114,11 @@ init_uncompress( compress_filter_context_t *zfx, bz_stream *bzs ) int rc; if((rc=BZ2_bzDecompressInit(bzs,0,opt.bz2_decompress_lowmem))!=BZ_OK) - log_fatal("bz2lib problem: %d\n",rc); + { + log_error ("bz2lib problem: %d\n",rc); + write_status_error ("bzip2.init.un", gpg_error (GPG_ERR_INTERNAL)); + g10_exit (2); + } zfx->inbufsize = 2048; zfx->inbuf = xmalloc( zfx->inbufsize ); @@ -159,7 +171,11 @@ do_uncompress( compress_filter_context_t *zfx, bz_stream *bzs, if( zrc == BZ_STREAM_END ) rc = -1; /* eof */ else if( zrc != BZ_OK && zrc != BZ_PARAM_ERROR ) - log_fatal("bz2lib inflate problem: rc=%d\n", zrc ); + { + log_error ("bz2lib inflate problem: rc=%d\n", zrc ); + write_status_error ("bzip2.inflate", gpg_error (GPG_ERR_BAD_DATA)); + g10_exit (2); + } else if (zrc == BZ_OK && eofseen && !bzs->avail_in && bzs->avail_out > 0) { diff --git a/g10/compress.c b/g10/compress.c index 9e094460f..e787b2918 100644 --- a/g10/compress.c +++ b/g10/compress.c @@ -73,10 +73,12 @@ init_compress( compress_filter_context_t *zfx, z_stream *zs ) -13, 8, Z_DEFAULT_STRATEGY) : deflateInit( zs, level ) ) != Z_OK ) { - log_fatal("zlib problem: %s\n", zs->msg? zs->msg : + log_error ("zlib problem: %s\n", zs->msg? zs->msg : rc == Z_MEM_ERROR ? "out of core" : rc == Z_VERSION_ERROR ? "invalid lib version" : "unknown error" ); + write_status_error ("zlib.init", gpg_error (GPG_ERR_INTERNAL)); + g10_exit (2); } zfx->outbufsize = 8192; @@ -104,9 +106,11 @@ do_compress( compress_filter_context_t *zfx, z_stream *zs, int flush, IOBUF a ) ; else if( zrc != Z_OK ) { if( zs->msg ) - log_fatal("zlib deflate problem: %s\n", zs->msg ); + log_error ("zlib deflate problem: %s\n", zs->msg ); else - log_fatal("zlib deflate problem: rc=%d\n", zrc ); + log_error ("zlib deflate problem: rc=%d\n", zrc ); + write_status_error ("zlib.deflate", gpg_error (GPG_ERR_INTERNAL)); + g10_exit (2); } n = zfx->outbufsize - zs->avail_out; if( DBG_FILTER ) @@ -116,7 +120,7 @@ do_compress( compress_filter_context_t *zfx, z_stream *zs, int flush, IOBUF a ) (unsigned)n, zrc ); if( (rc=iobuf_write( a, zfx->outbuf, n )) ) { - log_debug("deflate: iobuf_write failed\n"); + log_error ("deflate: iobuf_write failed\n"); return rc; } } while( zs->avail_in || (flush == Z_FINISH && zrc != Z_STREAM_END) ); @@ -140,10 +144,12 @@ init_uncompress( compress_filter_context_t *zfx, z_stream *zs ) */ if( (rc = zfx->algo == 1? inflateInit2( zs, -15) : inflateInit( zs )) != Z_OK ) { - log_fatal("zlib problem: %s\n", zs->msg? zs->msg : - rc == Z_MEM_ERROR ? "out of core" : - rc == Z_VERSION_ERROR ? "invalid lib version" : - "unknown error" ); + log_error ("zlib problem: %s\n", zs->msg? zs->msg : + rc == Z_MEM_ERROR ? "out of core" : + rc == Z_VERSION_ERROR ? "invalid lib version" : + "unknown error" ); + write_status_error ("zlib.init.un", gpg_error (GPG_ERR_INTERNAL)); + g10_exit (2); } zfx->inbufsize = 2048; @@ -198,9 +204,11 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs, rc = -1; /* eof */ else if( zrc != Z_OK && zrc != Z_BUF_ERROR ) { if( zs->msg ) - log_fatal("zlib inflate problem: %s\n", zs->msg ); + log_error ("zlib inflate problem: %s\n", zs->msg ); else - log_fatal("zlib inflate problem: rc=%d\n", zrc ); + log_error ("zlib inflate problem: rc=%d\n", zrc ); + write_status_error ("zlib.inflate", gpg_error (GPG_ERR_BAD_DATA)); + g10_exit (2); } } while (zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR && !leave); From c27e5be50b334726dc2b6a4d12e013582c19de6b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 29 Feb 2024 10:21:33 +0100 Subject: [PATCH 376/869] build: Make getswdb.sh usable outside the GniPG tree. -- --- build-aux/getswdb.sh | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/build-aux/getswdb.sh b/build-aux/getswdb.sh index 7d4b31eef..6ec931c25 100755 --- a/build-aux/getswdb.sh +++ b/build-aux/getswdb.sh @@ -34,6 +34,7 @@ Options: --skip-download Assume download has already been done. --skip-verify Do not check signatures --skip-selfcheck Do not check GnuPG version + (default if not used in the GnuPG tree) --find-sha1sum Print the name of the sha1sum utility --find-sha256sum Print the name of the sha256sum utility --help Print this help. @@ -114,16 +115,37 @@ if [ ${find_sha256sum} = yes ]; then fi +if [ $skip_verify = no ]; then + if [ ! -f "$distsigkey" ]; then + distsigkey="/usr/local/share/gnupg/distsigkey.gpg" + if [ ! -f "$distsigkey" ]; then + distsigkey="/usr/share/gnupg/distsigkey.gpg" + if [ ! -f "$distsigkey" ]; then + echo "no keyring with release keys found!" >&2 + exit 1 + fi + fi + echo "using release keys from $distsigkey" >&2 + skip_selfcheck=yes + fi +fi + + # Get GnuPG version from VERSION file. For a GIT checkout this means # that ./autogen.sh must have been run first. For a regular tarball # VERSION is always available. -if [ ! -f "$srcdir/../VERSION" ]; then +if [ $skip_selfcheck = no ]; then + if [ ! -f "$srcdir/../VERSION" ]; then echo "VERSION file missing - run autogen.sh first." >&2 exit 1 + fi + version=$(cat "$srcdir/../VERSION") +else + version="0.0.0" fi -version=$(cat "$srcdir/../VERSION") version_num=$(echo "$version" | cvtver) + if [ $skip_verify = no ]; then if ! $GPGV --version >/dev/null 2>/dev/null ; then echo "command \"gpgv\" is not installed" >&2 From 233bf39323ef48b362488175bb655c4020ce2d39 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 29 Feb 2024 15:35:27 +0100 Subject: [PATCH 377/869] build: Extend getswdb.sh to allow a verified download -- --- build-aux/getswdb.sh | 96 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/build-aux/getswdb.sh b/build-aux/getswdb.sh index 6ec931c25..0b97f0de5 100755 --- a/build-aux/getswdb.sh +++ b/build-aux/getswdb.sh @@ -28,9 +28,12 @@ cvtver () { usage() { cat <&2 ;; + *) + packages="$packages $1" + ;; esac shift done + # Mac OSX has only a shasum and not sha1sum if [ ${find_sha1sum} = yes ]; then for i in sha1sum shasum ; do @@ -186,10 +204,10 @@ else fi fi if [ $skip_verify = no ]; then - if ! $GPGV --keyring "$distsigkey" swdb.lst.sig swdb.lst; then + if ! $GPGV --keyring "$distsigkey" swdb.lst.sig swdb.lst 2>/dev/null; then echo "list of software versions is not valid!" >&2 exit 1 - fi + fi fi # @@ -210,3 +228,73 @@ if [ $skip_selfcheck = no ]; then exit 1 fi fi + + +# Download a package and check its signature. +download_pkg () { + local url="$1" + local file="${url##*/}" + + if ! $WGET -q -O - "$url" >"${file}.tmp" ; then + echo "download of $file failed." >&2 + [ -f "${file}.tmp" ] && rm "${file}.tmp" + return 1 + fi + if [ $skip_verify = no ]; then + if ! $WGET -q -O - "${url}.sig" >"${file}.tmpsig" ; then + echo "download of $file.sig failed." >&2 + [ -f "${file}.tmpsig" ] && rm "${file}.tmpsig" + return 1 + fi + if ! $GPGV -q --keyring "$distsigkey" \ + "${file}.tmpsig" "${file}.tmp" 2>/dev/null; then + echo "signature of $file is not valid!" >&2 + return 1 + fi + mv "${file}.tmpsig" "${file}.sig" + else + [ -f "${file}.sig" ] && rm "${file}.sig" + fi + mv "${file}.tmp" "${file}" + return 0 +} + + + +baseurl=$(awk '$1=="gpgorg_base" {print $2; exit 0}' swdb.lst) +for p in $packages; do + pver=$(awk '$1=="'"$p"'_ver" {print $2}' swdb.lst) + if [ -z "$pver" ]; then + echo "package '$p' not found" >&2 + die=yes + else + pdir=$(awk '$1=="'"$p"'_dir" {print $2":"$3":"$4}' swdb.lst) + if [ -n "$pdir" ]; then + psuf=$(echo "$pdir" | cut -d: -f3) + pname=$(echo "$pdir" | cut -d: -f2) + pdir=$(echo "$pdir" | cut -d: -f1) + else + psuf= + pdir="$p" + pname="$p" + fi + if [ -z "$psuf" ]; then + psuf=$(awk 'BEGIN {suf="bz2"}; + $1=="'"$p"'_sha1_gz" {suf="gz"; exit 0}; + $1=="'"$p"'_sha1_xz" {suf"xz"; exit 0}; + END {print suf}' swdb.lst) + fi + pfullname="$pname-$pver.tar.$psuf" + if [ $info_mode = yes ]; then + echo "$baseurl/$pdir/$pfullname" + else + echo "downloading $pfullname" + download_pkg "$baseurl/$pdir/$pfullname" || die=yes + fi + fi +done +if [ $die = yes ]; then + echo "errors found!" >&2 + exit 1 +fi +exit 0 From 74e4dd3668b3a737eb7929da5f5de2f12f6ca9b8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 4 Mar 2024 14:22:42 +0100 Subject: [PATCH 378/869] gpg: Prepare for a new export option export-realclean. * g10/options.h (EXPORT_REALCLEAN): New. Also re-assign other values to keep them more in sync with the corresponding import values. * g10/export.c (parse_export_options): Add "export-realclean". (do_export_stream): Call clean_all_uids directly with the options arg. * g10/import.c (import_one_real): Change for direct use of options in clean_all_uids. * g10/key-clean.c (is_trusted_key_sig): New. Stub for now. (clean_sigs_from_uid): Re-purpose self_only to a general options arg. Implement EXPORT_REALCLEAN code path. (clean_one_uid): Re-purpose self_only to a general options arg. (clean_all_uids): Ditto. * g10/keyedit.c (keyedit_menu): Use EXPORT_MINIMAL instead of a simple flag. (menu_clean): Re-purpose self_only to a general options arg. * g10/keyid.c (fpr20_from_pk): Factor code out to .... (fpr20_from_fpr): new. Remove useless case for ARRAY being NULL. * g10/tdbio.c (tdbio_search_trust_byfpr): Add arg fprlen and use fpr20_from_fpr if needed. (tdbio_search_trust_bypk): Pass 20 for the fingerprint length. -- Note that this code has no function yet. Another patch will follow to extract the trusted-keys flag from the trustdb. --- g10/export.c | 9 +++++---- g10/import.c | 9 ++++++--- g10/key-clean.c | 41 ++++++++++++++++++++++++++++++++--------- g10/key-clean.h | 5 +++-- g10/keydb.h | 1 + g10/keyedit.c | 16 +++++++++------- g10/keyid.c | 40 +++++++++++++++++++++++++++------------- g10/options.h | 5 +++-- g10/tdbdump.c | 6 +++++- g10/tdbio.c | 16 ++++++++++++---- g10/tdbio.h | 3 ++- 11 files changed, 105 insertions(+), 46 deletions(-) diff --git a/g10/export.c b/g10/export.c index b3ad69718..224847e0f 100644 --- a/g10/export.c +++ b/g10/export.c @@ -129,6 +129,8 @@ parse_export_options(char *str,unsigned int *options,int noisy) N_("export revocation keys marked as \"sensitive\"")}, {"export-clean",EXPORT_CLEAN,NULL, N_("remove unusable parts from key during export")}, + {"export-realclean",EXPORT_MINIMAL|EXPORT_REALCLEAN|EXPORT_CLEAN,NULL, + NULL}, {"export-minimal",EXPORT_MINIMAL|EXPORT_CLEAN,NULL, N_("remove as much as possible from key during export")}, @@ -166,7 +168,7 @@ parse_export_options(char *str,unsigned int *options,int noisy) { *options |= (EXPORT_LOCAL_SIGS | EXPORT_ATTRIBUTES | EXPORT_SENSITIVE_REVKEYS); - *options &= ~(EXPORT_CLEAN | EXPORT_MINIMAL + *options &= ~(EXPORT_CLEAN | EXPORT_MINIMAL | EXPORT_REALCLEAN | EXPORT_DANE_FORMAT); } @@ -643,7 +645,7 @@ canon_pk_algo (enum gcry_pk_algos algo) } -/* Take an s-expression wit the public and private key and change the +/* Take an s-expression with the public and private key and change the * parameter array in PK to include the secret parameters. */ static gpg_error_t secret_key_to_mode1003 (gcry_sexp_t s_key, PKT_public_key *pk) @@ -2366,8 +2368,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, if ((options & EXPORT_CLEAN)) { merge_keys_and_selfsig (ctrl, keyblock); - clean_all_uids (ctrl, keyblock, opt.verbose, - (options&EXPORT_MINIMAL), NULL, NULL); + clean_all_uids (ctrl, keyblock, opt.verbose, options, NULL, NULL); clean_all_subkeys (ctrl, keyblock, opt.verbose, (options&EXPORT_MINIMAL)? KEY_CLEAN_ALL /**/ : KEY_CLEAN_AUTHENCR, diff --git a/g10/import.c b/g10/import.c index 8f874a7d1..ff8847cb6 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2081,7 +2081,9 @@ import_one_real (ctrl_t ctrl, { merge_keys_and_selfsig (ctrl, keyblock); clean_all_uids (ctrl, keyblock, - opt.verbose, (options&IMPORT_MINIMAL), NULL, NULL); + opt.verbose, + (options&IMPORT_MINIMAL)? EXPORT_MINIMAL : 0, + NULL, NULL); clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE, NULL, NULL); } @@ -2233,7 +2235,8 @@ import_one_real (ctrl_t ctrl, if ((options & IMPORT_CLEAN)) { merge_keys_and_selfsig (ctrl, keyblock); - clean_all_uids (ctrl, keyblock, opt.verbose, (options&IMPORT_MINIMAL), + clean_all_uids (ctrl, keyblock, opt.verbose, + (options&IMPORT_MINIMAL)? EXPORT_MINIMAL : 0, &n_uids_cleaned,&n_sigs_cleaned); clean_all_subkeys (ctrl, keyblock, opt.verbose, KEY_CLEAN_NONE, NULL, NULL); @@ -2331,7 +2334,7 @@ import_one_real (ctrl_t ctrl, { merge_keys_and_selfsig (ctrl, keyblock_orig); clean_all_uids (ctrl, keyblock_orig, opt.verbose, - (options&IMPORT_MINIMAL), + (options&IMPORT_MINIMAL)? EXPORT_MINIMAL : 0, &n_uids_cleaned,&n_sigs_cleaned); clean_all_subkeys (ctrl, keyblock_orig, opt.verbose, KEY_CLEAN_NONE, NULL, NULL); diff --git a/g10/key-clean.c b/g10/key-clean.c index c8a6efe50..ca8ca40d9 100644 --- a/g10/key-clean.c +++ b/g10/key-clean.c @@ -91,6 +91,7 @@ mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, continue; } node->flag |= 1<next) @@ -215,9 +216,22 @@ mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, } +/* Return true if the signature at NODE has is from a key specified by + * the --trusted-key option and is exportable. */ +static int +is_trusted_key_sig (kbnode_t node) +{ + if (!node->pkt->pkt.signature->flags.exportable) + return 0; + /* Not yet implemented. */ + return 0; +} + + +/* Note: OPTIONS are from the EXPORT_* set. */ static int clean_sigs_from_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, - int noisy, int self_only) + int noisy, unsigned int options) { int deleted = 0; kbnode_t node; @@ -256,8 +270,15 @@ clean_sigs_from_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, { int keep; - keep = self_only? (node->pkt->pkt.signature->keyid[0] == keyid[0] - && node->pkt->pkt.signature->keyid[1] == keyid[1]) : 1; + if ((options & EXPORT_REALCLEAN)) + keep = ((node->pkt->pkt.signature->keyid[0] == keyid[0] + && node->pkt->pkt.signature->keyid[1] == keyid[1]) + || is_trusted_key_sig (node)); + else if ((options & EXPORT_MINIMAL)) + keep = (node->pkt->pkt.signature->keyid[0] == keyid[0] + && node->pkt->pkt.signature->keyid[1] == keyid[1]); + else + keep = 1; /* Keep usable uid sigs ... */ if ((node->flag & (1<pkt->pkt.user_id->flags.compacted) *sigs_cleaned += clean_sigs_from_uid (ctrl, keyblock, uidnode, - noisy, self_only); + noisy, options); } /* NB: This function marks the deleted nodes only and the caller is * responsible to skip or remove them. Needs to be called after a - * merge_keys_and_selfsig(). */ + * merge_keys_and_selfsig. Note: OPTIONS are from the EXPORT_* set. */ void -clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only, +clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, unsigned int options, int *uids_cleaned, int *sigs_cleaned) { kbnode_t node; @@ -405,7 +428,7 @@ clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only, node = node->next) { if (node->pkt->pkttype == PKT_USER_ID) - clean_one_uid (ctrl, keyblock, node, noisy, self_only, + clean_one_uid (ctrl, keyblock, node, noisy, options, uids_cleaned, sigs_cleaned); } diff --git a/g10/key-clean.h b/g10/key-clean.h index c4f164928..b2825b0c5 100644 --- a/g10/key-clean.h +++ b/g10/key-clean.h @@ -40,9 +40,10 @@ void mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, u32 curtime, u32 *next_expire); void clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, - int noisy, int self_only, + int noisy, unsigned int options, int *uids_cleaned, int *sigs_cleaned); -void clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only, +void clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, + int noisy, unsigned int options, int *uids_cleaned,int *sigs_cleaned); void clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy, int clean_level, diff --git a/g10/keydb.h b/g10/keydb.h index 798c24da3..62a99295d 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -573,6 +573,7 @@ const char *colon_expirestr_from_sig (PKT_signature *sig); byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len ); byte *v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len); void fpr20_from_pk (PKT_public_key *pk, byte array[20]); +void fpr20_from_fpr (const byte *fpr, unsigned int fprlen, byte array[20]); char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen); char *v5hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen); char *format_hexfingerprint (const char *fingerprint, diff --git a/g10/keyedit.c b/g10/keyedit.c index e56e6d10b..7523a1a62 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -70,7 +70,7 @@ static int menu_adduid (ctrl_t ctrl, kbnode_t keyblock, int photo, const char *photo_name, const char *uidstr); static void menu_deluid (KBNODE pub_keyblock); static int menu_delsig (ctrl_t ctrl, kbnode_t pub_keyblock); -static int menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only); +static int menu_clean (ctrl_t ctrl, kbnode_t keyblock, unsigned int options); static void menu_delkey (KBNODE pub_keyblock); static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive); static int menu_addadsk (ctrl_t ctrl, kbnode_t pub_keyblock, @@ -2258,7 +2258,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, break; case cmdMINIMIZE: - if (menu_clean (ctrl, keyblock, 1)) + if (menu_clean (ctrl, keyblock, EXPORT_MINIMAL)) redisplay = modified = 1; break; @@ -4543,11 +4543,13 @@ menu_delsig (ctrl_t ctrl, kbnode_t pub_keyblock) } +/* Note: OPTIONS are from the EXPORT_* set. */ static int -menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only) +menu_clean (ctrl_t ctrl, kbnode_t keyblock, unsigned int options) { KBNODE uidnode; - int modified = 0, select_all = !count_selected_uids (keyblock); + int modified = 0; + int select_all = !count_selected_uids (keyblock); for (uidnode = keyblock->next; uidnode && uidnode->pkt->pkttype != PKT_PUBLIC_SUBKEY; @@ -4561,8 +4563,8 @@ menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only) uidnode->pkt->pkt.user_id->len, 0); - clean_one_uid (ctrl, keyblock, uidnode, opt.verbose, self_only, &uids, - &sigs); + clean_one_uid (ctrl, keyblock, uidnode, opt.verbose, options, + &uids, &sigs); if (uids) { const char *reason; @@ -4587,7 +4589,7 @@ menu_clean (ctrl_t ctrl, kbnode_t keyblock, int self_only) } else { - tty_printf (self_only == 1 ? + tty_printf ((options & EXPORT_MINIMAL)? _("User ID \"%s\": already minimized\n") : _("User ID \"%s\": already clean\n"), user); } diff --git a/g10/keyid.c b/g10/keyid.c index ce977de0b..fab1e3a36 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -1050,6 +1050,32 @@ v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len) } +/* + * This is the core of fpr20_from_pk which directly takes a + * fingerprint and its length instead of the public key. See below + * for details. + */ +void +fpr20_from_fpr (const byte *fpr, unsigned int fprlen, byte array[20]) +{ + if (fprlen >= 32) /* v5 fingerprint (or larger) */ + { + memcpy (array + 0, fpr + 20, 4); + memcpy (array + 4, fpr + 24, 4); + memcpy (array + 8, fpr + 28, 4); + memcpy (array + 12, fpr + 0, 4); /* kid[0] */ + memcpy (array + 16, fpr + 4, 4); /* kid[1] */ + } + else if (fprlen == 20) /* v4 fingerprint */ + memcpy (array, fpr, 20); + else /* v3 or too short: fill up with zeroes. */ + { + memset (array, 0, 20); + memcpy (array, fpr, fprlen); + } +} + + /* * Get FPR20 for the given PK/SK into ARRAY. * @@ -1066,19 +1092,7 @@ fpr20_from_pk (PKT_public_key *pk, byte array[20]) if (!pk->fprlen) compute_fingerprint (pk); - if (!array) - array = xmalloc (pk->fprlen); - - if (pk->fprlen == 32) /* v5 fingerprint */ - { - memcpy (array + 0, pk->fpr + 20, 4); - memcpy (array + 4, pk->fpr + 24, 4); - memcpy (array + 8, pk->fpr + 28, 4); - memcpy (array + 12, pk->fpr + 0, 4); /* kid[0] */ - memcpy (array + 16, pk->fpr + 4, 4); /* kid[1] */ - } - else /* v4 fingerprint */ - memcpy (array, pk->fpr, 20); + fpr20_from_fpr (pk->fpr, pk->fprlen, array); } diff --git a/g10/options.h b/g10/options.h index 07516aab1..458180c7a 100644 --- a/g10/options.h +++ b/g10/options.h @@ -416,12 +416,13 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define EXPORT_ATTRIBUTES (1<<1) #define EXPORT_SENSITIVE_REVKEYS (1<<2) #define EXPORT_RESET_SUBKEY_PASSWD (1<<3) -#define EXPORT_MINIMAL (1<<4) -#define EXPORT_CLEAN (1<<5) +#define EXPORT_MINIMAL (1<<5) +#define EXPORT_CLEAN (1<<6) #define EXPORT_DANE_FORMAT (1<<7) #define EXPORT_BACKUP (1<<10) #define EXPORT_REVOCS (1<<11) #define EXPORT_MODE1003 (1<<12) +#define EXPORT_REALCLEAN (1<<13) #define LIST_SHOW_PHOTOS (1<<0) #define LIST_SHOW_POLICY_URLS (1<<1) diff --git a/g10/tdbdump.c b/g10/tdbdump.c index 2a02ad108..058ab5cf6 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -193,7 +193,11 @@ import_ownertrust (ctrl_t ctrl, const char *fname ) while (fprlen < MAX_FINGERPRINT_LEN) fpr[fprlen++] = 0; - rc = tdbio_search_trust_byfpr (ctrl, fpr, &rec); + /* FIXME: The intention is to save the special fpr20 as used + * in the trustdb here. However, the above conversions seems + * not to be aware of this. Or why does it allow up to + * MAX_FINGERPRINT_LEN ? */ + rc = tdbio_search_trust_byfpr (ctrl, fpr, 20, &rec); if( !rc ) { /* found: update */ if (rec.r.trust.ownertrust != otrust) { diff --git a/g10/tdbio.c b/g10/tdbio.c index 1b68f772f..7ee62fca0 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -1864,13 +1864,21 @@ cmp_trec_fpr ( const void *fpr, const TRUSTREC *rec ) * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code. */ gpg_error_t -tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fingerprint, TRUSTREC *rec) +tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fpr, unsigned int fprlen, + TRUSTREC *rec) { int rc; + byte fingerprint[20]; + + if (fprlen != 20) + { + fpr20_from_fpr (fpr, fprlen, fingerprint); + fpr = fingerprint; + } /* Locate the trust record using the hash table */ - rc = lookup_hashtable (get_trusthashrec (ctrl), fingerprint, 20, - cmp_trec_fpr, fingerprint, rec ); + rc = lookup_hashtable (get_trusthashrec (ctrl), fpr, 20, + cmp_trec_fpr, fpr, rec); return rc; } @@ -1887,7 +1895,7 @@ tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec) byte fingerprint[20]; fpr20_from_pk (pk, fingerprint); - return tdbio_search_trust_byfpr (ctrl, fingerprint, rec); + return tdbio_search_trust_byfpr (ctrl, fingerprint, 20, rec); } diff --git a/g10/tdbio.h b/g10/tdbio.h index 9452d76c9..7cf630121 100644 --- a/g10/tdbio.h +++ b/g10/tdbio.h @@ -111,7 +111,8 @@ int tdbio_end_transaction(void); int tdbio_cancel_transaction(void); int tdbio_delete_record (ctrl_t ctrl, ulong recnum); ulong tdbio_new_recnum (ctrl_t ctrl); -gpg_error_t tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fingerprint, +gpg_error_t tdbio_search_trust_byfpr (ctrl_t ctrl, + const byte *fpr, unsigned int fprlen, TRUSTREC *rec); gpg_error_t tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec); From 36a3550bffd233b1cf7b94ecd15c986ec18e1494 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 4 Mar 2024 14:28:48 +0100 Subject: [PATCH 379/869] wks: Add option --realclean to gpg-wks-client. * tools/gpg-wks-client.c (oRealClean): New. (opts): Add "realclean". (parse_arguments): Implement. (main): Take a copy of the module name to fix bad assignment from a former patch. * tools/gpg-wks-server.c (main): Ditto. * tools/gpg-wks.h (opt): Add field realclean. * tools/wks-util.c (wks_get_key): Call gpg with export-realclean depending on the new option. -- The default for gpg-wks-client is to install keys with all valid key signatures. The new option will eventually allow to install the keys only with key signatures done by trusted-keys. Also the export-option is in gpg, it requires one more gpg patch to make it actually work. --- tools/gpg-wks-client.c | 10 ++++++++-- tools/gpg-wks-server.c | 2 +- tools/gpg-wks.h | 1 + tools/wks-util.c | 3 ++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index d3d1b522a..c172fcc77 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -78,6 +78,7 @@ enum cmd_and_opt_values oNoAutostart, oAddRevocs, oNoAddRevocs, + oRealClean, oDummy }; @@ -121,8 +122,9 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_s (oBlacklist, "blacklist", "@"), ARGPARSE_s_s (oDirectory, "directory", "@"), - ARGPARSE_s_n (oAddRevocs, "add-revocs", "add revocation certificates"), + ARGPARSE_s_n (oAddRevocs, "add-revocs", "@"), ARGPARSE_s_n (oNoAddRevocs, "no-add-revocs", "do not add revocation certificates"), + ARGPARSE_s_n (oRealClean, "realclean", "remove most key signatures"), ARGPARSE_s_s (oFakeSubmissionAddr, "fake-submission-addr", "@"), @@ -273,6 +275,10 @@ parse_arguments (gpgrt_argparse_t *pargs, gpgrt_opt_t *popts) opt.add_revocs = 0; break; + case oRealClean: + opt.realclean = 1; + break; + case aSupported: case aCreate: case aReceive: @@ -358,7 +364,7 @@ main (int argc, char **argv) /* Set defaults for non given options. */ if (!opt.gpg_program) - opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG); + opt.gpg_program = xstrdup (gnupg_module_name (GNUPG_MODULE_NAME_GPG)); if (!opt.directory) opt.directory = "openpgpkey"; diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index d3406bd79..31de67618 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -308,7 +308,7 @@ main (int argc, char **argv) /* Set defaults for non given options. */ if (!opt.gpg_program) - opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG); + opt.gpg_program = xstrdup (gnupg_module_name (GNUPG_MODULE_NAME_GPG)); if (!opt.directory) opt.directory = "/var/lib/gnupg/wks"; diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h index 4a33c5bec..0601d48fe 100644 --- a/tools/gpg-wks.h +++ b/tools/gpg-wks.h @@ -40,6 +40,7 @@ struct int with_colons; int no_autostart; int add_revocs; + int realclean; char *output; char *gpg_program; char *directory; diff --git a/tools/wks-util.c b/tools/wks-util.c index ee1305b00..640116ce8 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -246,7 +246,8 @@ wks_get_key (estream_t *r_key, const char *fingerprint, const char *addrspec, ccparray_put (&ccp, "--always-trust"); if (!binary) ccparray_put (&ccp, "--armor"); - ccparray_put (&ccp, "--export-options=export-clean"); + ccparray_put (&ccp, opt.realclean? "--export-options=export-realclean" + /* */ : "--export-options=export-clean"); ccparray_put (&ccp, "--export-filter"); ccparray_put (&ccp, filterexp); ccparray_put (&ccp, "--export"); From 345794cfe671c66f32fb63bb37bd41b19517359f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 4 Mar 2024 14:56:16 +0100 Subject: [PATCH 380/869] gpg: Fix mixed invocation with --trusted-keys and --no-options. * g10/trustdb.c: Move a function and some definitions around. (user_utk_list): Rename to trusted_key_list. Change all users. (any_trusted_key_seen): New. (tdb_register_trusted_key): Set it here. Handle the new value "none". (verify_own_keys): Do not delete a trusted key from the trustdb if a trusted-key option was not used. -- GnuPG-bug-id: 7025 --- doc/gpg.texi | 4 +- g10/trustdb.c | 110 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 69 insertions(+), 45 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 26e0ebdcd..1d1c38cd9 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1776,7 +1776,9 @@ useful if you don't want to keep your secret keys (or one of them) online but still want to be able to check the validity of a given recipient's or signator's key. If the given key is not locally available but an LDAP keyserver is configured the missing key is -imported from that server. +imported from that server. The value "none" is explicitly allowed to +distinguish between the use of any trusted-key option and no use of +this option at all (e.g. due to the @option{--no-options} option). @item --add-desig-revoker [sensitive:]@var{fingerprint} @opindex add-desig-revoker diff --git a/g10/trustdb.c b/g10/trustdb.c index e846abe82..3f30ef3d4 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -39,8 +39,52 @@ #include "tofu.h" #include "key-clean.h" + + +typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */ + +/* + * Structure to keep track of keys, this is used as an array where the + * item right after the last one has a keyblock set to NULL. Maybe we + * can drop this thing and replace it by key_item + */ +struct key_array +{ + KBNODE keyblock; +}; + + +/* Control information for the trust DB. */ +static struct +{ + int init; + int level; + char *dbname; + int no_trustdb; +} trustdb_args; + + +/* Some globals. */ +static struct key_item *utk_list; /* all ultimately trusted keys */ + +/* A list used to temporary store trusted keys and a flag indicated + * whether any --trusted-key option has been seen. */ +static struct key_item *trusted_key_list; +static int any_trusted_key_seen; + +/* Flag whether a trustdb chekc is pending. */ +static int pending_check_trustdb; + + + static void write_record (ctrl_t ctrl, TRUSTREC *rec); -static void do_sync(void); +static void do_sync (void); +static int validate_keys (ctrl_t ctrl, int interactive); + + +/********************************************** + ************* some helpers ******************* + **********************************************/ @@ -54,7 +98,7 @@ keyid_from_fpr20 (ctrl_t ctrl, const byte *fpr, u32 *keyid) keyid = dummy_keyid; /* Problem: We do only use fingerprints in the trustdb but - * we need the keyID here to indetify the key; we can only + * we need the keyID here to identify the key; we can only * use that ugly hack to distinguish between 16 and 20 * bytes fpr - it does not work always so we better change * the whole validation code to only work with @@ -88,40 +132,6 @@ keyid_from_fpr20 (ctrl_t ctrl, const byte *fpr, u32 *keyid) return keyid[1]; } -typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */ - -/* - * Structure to keep track of keys, this is used as an array wherre - * the item right after the last one has a keyblock set to NULL. - * Maybe we can drop this thing and replace it by key_item - */ -struct key_array -{ - KBNODE keyblock; -}; - - -/* Control information for the trust DB. */ -static struct -{ - int init; - int level; - char *dbname; - int no_trustdb; -} trustdb_args; - -/* Some globals. */ -static struct key_item *user_utk_list; /* temp. used to store --trusted-keys */ -static struct key_item *utk_list; /* all ultimately trusted keys */ - -static int pending_check_trustdb; - -static int validate_keys (ctrl_t ctrl, int interactive); - - -/********************************************** - ************* some helpers ******************* - **********************************************/ static struct key_item * new_key_item (void) @@ -245,11 +255,19 @@ tdb_register_trusted_keyid (u32 *keyid) k = new_key_item (); k->kid[0] = keyid[0]; k->kid[1] = keyid[1]; - k->next = user_utk_list; - user_utk_list = k; + k->next = trusted_key_list; + trusted_key_list = k; } +/* This is called for the option --trusted-key to register these keys + * for later syncing them into the trustdb. The special value "none" + * may be used to indicate that there is a trusted-key option but no + * key shall be inserted for it. This "none" value is helpful to + * distinguish between changing the gpg.conf from a trusted-key to no + * trusted-key options at all. Simply not specify the option would + * not allow to distinguish this case from the --no-options case as + * used for certain calls of gpg for example by gpg-wks-client. */ void tdb_register_trusted_key (const char *string) { @@ -257,6 +275,9 @@ tdb_register_trusted_key (const char *string) KEYDB_SEARCH_DESC desc; u32 kid[2]; + any_trusted_key_seen = 1; + if (!strcmp (string, "none")) + return; err = classify_user_id (string, &desc, 1); if (!err) { @@ -378,11 +399,12 @@ verify_own_keys (ctrl_t ctrl) if (!add_utk (kid)) log_info (_("key %s occurs more than once in the trustdb\n"), keystr(kid)); - else if ((rec.r.trust.flags & 1)) + else if ((rec.r.trust.flags & 1) + && any_trusted_key_seen) { /* Record marked as inserted via --trusted-key. Is this * still the case? */ - for (k2 = user_utk_list; k2; k2 = k2->next) + for (k2 = trusted_key_list; k2; k2 = k2->next) if (k2->kid[0] == kid[0] && k2->kid[1] == kid[1]) break; if (!k2) /* No - clear the flag. */ @@ -406,7 +428,7 @@ verify_own_keys (ctrl_t ctrl) } /* Put any --trusted-key keys into the trustdb */ - for (k = user_utk_list; k; k = k->next) + for (k = trusted_key_list; k; k = k->next) { if ( add_utk (k->kid) ) { /* not yet in trustDB as ultimately trusted */ @@ -431,9 +453,9 @@ verify_own_keys (ctrl_t ctrl) } } - /* release the helper table table */ - release_key_items (user_utk_list); - user_utk_list = NULL; + /* Release the helper table. */ + release_key_items (trusted_key_list); + trusted_key_list = NULL; return; } From 37cc255e49427dfaaa9907fe789dc6e84484d532 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 6 Mar 2024 10:00:37 +0100 Subject: [PATCH 381/869] wks: Make gpg-wks-client --mirror work w/o args. * tools/gpg-wks-client.c (mirror_one_key): Test for no domain specified. -- The code did not really work if no domain was given. It worked but filtered out all keys so that no key was actually exported. --- g10/trustdb.c | 2 +- tools/gpg-wks-client.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/g10/trustdb.c b/g10/trustdb.c index 3f30ef3d4..6de9f6b66 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -72,7 +72,7 @@ static struct key_item *utk_list; /* all ultimately trusted keys */ static struct key_item *trusted_key_list; static int any_trusted_key_seen; -/* Flag whether a trustdb chekc is pending. */ +/* Flag whether a trustdb check is pending. */ static int pending_check_trustdb; diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index c172fcc77..f02484c94 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -2026,7 +2026,7 @@ mirror_one_key (estream_t key) continue; /* No mail box or already processed. */ if (uid->expired) continue; - if (!domain_matches_mbox (domain, uid->mbox)) + if (*domain && !domain_matches_mbox (domain, uid->mbox)) continue; /* We don't want this one. */ if (is_in_blacklist (uid->mbox)) continue; From 00b877ecda434e8876fa34b1283f25249bf59964 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 6 Mar 2024 11:54:33 +0100 Subject: [PATCH 382/869] doc: Typo fix in comment -- --- tools/gpg-wks-client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index f02484c94..ef11a4e3e 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -1919,7 +1919,7 @@ domain_matches_mbox (const char *domain, const char *mbox) * so that for a key with * uid: Joe Someone * uid: Joe - * only the news user id (and thus its self-signature) is used. + * only the newest user id (and thus its self-signature) is used. * UIDLIST is nodified to set all MBOX fields to NULL for a processed * user id. FPR is the fingerprint of the key. */ From 79d0e52b2d894f52ce8e575ac7671f4a87282e7f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 6 Mar 2024 15:49:51 +0100 Subject: [PATCH 383/869] gpg: Fix a possible segv due to an uninitialized gcrypt context. * g10/sign.c (sign_symencrypt_file): Initialize MD for the error case. -- Reported-by: Falko Strenzke Fixes-commit: 1ddd69935da629188dcf9215cd9e7a8f68b34a97 in the not yet released master branch. --- g10/sign.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/sign.c b/g10/sign.c index b6c4d2126..e00baf3e7 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1586,7 +1586,7 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) compress_filter_context_t zfx; md_filter_context_t mfx; md_thd_filter_context_t mfx2 = NULL; - gcry_md_hd_t md; + gcry_md_hd_t md = NULL; text_filter_context_t tfx; cipher_filter_context_t cfx; iobuf_t inp = NULL; From a1ea3b13e0c79cb301216727b17631fbf1b23e06 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 6 Mar 2024 11:54:33 +0100 Subject: [PATCH 384/869] scd: Let the CCID module auto detach the kernel driver. * scd/ccid-driver.c (ccid_open_usb_reader): Call libusb_set_auto_detach_kernel_driver. * scd/scdaemon.c (oCompatibilityFlags): New. (opts): Add option "compatibility-flags". (compatibility_flags): New. (main): Parse flags. * scd/scdaemon.h (opt): Add field compat_flags. (COMPAT_CCID_NO_AUTO_DETACH): New. --- scd/ccid-driver.c | 14 ++++++++++++++ scd/scdaemon.c | 19 +++++++++++++++++++ scd/scdaemon.h | 8 ++++++++ 3 files changed, 41 insertions(+) diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index ad1e16a12..7319ada41 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1779,6 +1779,20 @@ ccid_open_usb_reader (const char *spec_reader_name, #ifdef USE_NPTH npth_unprotect (); #endif + if (!(opt.compat_flags & COMPAT_CCID_NO_AUTO_DETACH)) + { + rc = libusb_set_auto_detach_kernel_driver (idev, 1); + if (rc) + { +#ifdef USE_NPTH + npth_protect (); +#endif + DEBUGOUT_1 ("note: set_auto_detach_kernel_driver failed: %d\n", rc); +#ifdef USE_NPTH + npth_unprotect (); +#endif + } + } rc = libusb_claim_interface (idev, ifc_no); if (rc) { diff --git a/scd/scdaemon.c b/scd/scdaemon.c index ed7fdc03a..1a8705b18 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -104,6 +104,7 @@ enum cmd_and_opt_values oDisableApplication, oApplicationPriority, oEnablePinpadVarlen, + oCompatibilityFlags, oListenBacklog }; @@ -172,6 +173,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oDisableApplication, "disable-application", "@"), ARGPARSE_s_s (oApplicationPriority, "application-priority", N_("|LIST|change the application priority to LIST")), + ARGPARSE_s_s (oCompatibilityFlags, "compatibility-flags", "@"), ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"), @@ -204,6 +206,14 @@ static struct debug_flags_s debug_flags [] = }; +/* The list of compatibility flags. */ +static struct compatibility_flags_s compatibility_flags [] = + { + { COMPAT_CCID_NO_AUTO_DETACH, "ccid-no-auto-detach" }, + { 0, NULL } + }; + + /* The card driver we use by default for PC/SC. */ #if defined(HAVE_W32_SYSTEM) || defined(__CYGWIN__) #define DEFAULT_PCSC_DRIVER "winscard.dll" @@ -632,6 +642,15 @@ main (int argc, char **argv ) case oEnablePinpadVarlen: opt.enable_pinpad_varlen = 1; break; + case oCompatibilityFlags: + if (parse_compatibility_flags (pargs.r.ret_str, &opt.compat_flags, + compatibility_flags)) + { + pargs.r_opt = ARGPARSE_INVALID_ARG; + pargs.err = ARGPARSE_PRINT_WARNING; + } + break; + case oListenBacklog: listen_backlog = pargs.r.ret_int; break; diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 7b82d1b21..16873c54b 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -67,6 +67,9 @@ struct want to use. */ unsigned long card_timeout; /* Disconnect after N seconds of inactivity. */ int debug_allow_pin_logging; /* Allow PINs in debug output. */ + + /* Compatibility flags (COMPAT_FLAG_xxxx). */ + unsigned int compat_flags; } opt; @@ -92,6 +95,11 @@ struct #define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE) #define DBG_READER (opt.debug & DBG_READER_VALUE) + +#define COMPAT_CCID_NO_AUTO_DETACH 1 + + + struct server_local_s; struct card_ctx_s; struct app_ctx_s; From 1682ca9f012a72e97ed20b9b33e100501b9b94cf Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 7 Mar 2024 13:29:56 +0100 Subject: [PATCH 385/869] scd: Add support for ACR-122U * scd/ccid-driver.h (VENDOR_ACR, ACR_122U): New. * scd/ccid-driver.c (ccid_open_usb_reader): Do not call libsub_set_interface_alt_setting for this reader. -- Co-authored-by: markus.montkowski@gnupg.com --- scd/ccid-driver.c | 6 +++++- scd/ccid-driver.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 7319ada41..39e45a0ab 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1805,7 +1805,10 @@ ccid_open_usb_reader (const char *spec_reader_name, } /* Submit SET_INTERFACE control transfer which can reset the device. */ - rc = libusb_set_interface_alt_setting (idev, ifc_no, set_no); + if ((*handle)->id_vendor == VENDOR_ACR && (*handle)->id_product == ACR_122U) + rc = 0; /* Not supported by this reader. */ + else + rc = libusb_set_interface_alt_setting (idev, ifc_no, set_no); if (rc) { #ifdef USE_NPTH @@ -1820,6 +1823,7 @@ ccid_open_usb_reader (const char *spec_reader_name, npth_protect (); #endif + /* Perform any vendor specific intialization. */ rc = ccid_vendor_specific_init (*handle); leave: diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h index 18cbc87f0..bac5fac07 100644 --- a/scd/ccid-driver.h +++ b/scd/ccid-driver.h @@ -70,6 +70,7 @@ enum { VENDOR_FSIJ = 0x234b, VENDOR_VASCO = 0x1a44, VENDOR_NXP = 0x1fc9, + VENDOR_ACR = 0x072f }; @@ -88,6 +89,7 @@ enum { #define VEGA_ALPHA 0x0008 #define CYBERJACK_GO 0x0504 #define CRYPTOUCAN 0x81e6 +#define ACR_122U 0x2200 /* NFC Reader */ #endif /*CCID_DRIVER_INCLUDE_USB_IDS*/ From 09431d1762bd04b14b28906028e9963b1b386fed Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 7 Mar 2024 13:29:56 +0100 Subject: [PATCH 386/869] scd: Improve code reability of ccid-driver.c * scd/ccid-driver.c (my_npth_unprotect, my_npth_protect): New. Replace all direct uses by these wrappers. --- scd/ccid-driver.c | 145 ++++++++++++++++------------------------------ 1 file changed, 49 insertions(+), 96 deletions(-) diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 39e45a0ab..0fcd5a3d8 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -298,6 +298,23 @@ static int send_escape_cmd (ccid_driver_t handle, const unsigned char *data, size_t resultmax, size_t *resultlen); +static void +my_npth_unprotect (void) +{ +#ifdef USE_NPTH + npth_unprotect (); +#endif +} + +static void +my_npth_protect (void) +{ +#ifdef USE_NPTH + npth_protect (); +#endif +} + + static int map_libusb_error (int usberr) { @@ -984,31 +1001,23 @@ get_escaped_usb_string (libusb_device_handle *idev, int idx, /* First get the list of supported languages and use the first one. If we do don't find it we try to use English. Note that this is all in a 2 bute Unicode encoding using little endian. */ -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); rc = libusb_control_transfer (idev, LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8), 0, buf, sizeof buf, 1000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); if (rc < 4) langid = 0x0409; /* English. */ else langid = (buf[3] << 8) | buf[2]; -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); rc = libusb_control_transfer (idev, LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) + idx, langid, buf, sizeof buf, 1000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); if (rc < 2 || buf[1] != LIBUSB_DT_STRING) return NULL; /* Error or not a string. */ len = buf[0]; @@ -1345,13 +1354,9 @@ ccid_vendor_specific_setup (ccid_driver_t handle) { if (handle->id_vendor == VENDOR_SCM && handle->id_product == SCM_SPR532) { -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); libusb_clear_halt (handle->idev, handle->ep_intr); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); } return 0; } @@ -1660,13 +1665,9 @@ ccid_usb_thread (void *arg) while (ccid_usb_thread_is_alive) { -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); libusb_handle_events_completed (ctx, NULL); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); } return NULL; @@ -1776,29 +1777,21 @@ ccid_open_usb_reader (const char *spec_reader_name, goto leave; } -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); if (!(opt.compat_flags & COMPAT_CCID_NO_AUTO_DETACH)) { rc = libusb_set_auto_detach_kernel_driver (idev, 1); if (rc) { -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); DEBUGOUT_1 ("note: set_auto_detach_kernel_driver failed: %d\n", rc); -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); } } rc = libusb_claim_interface (idev, ifc_no); if (rc) { -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc); rc = map_libusb_error (rc); goto leave; @@ -1811,17 +1804,13 @@ ccid_open_usb_reader (const char *spec_reader_name, rc = libusb_set_interface_alt_setting (idev, ifc_no, set_no); if (rc) { -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); DEBUGOUT_1 ("usb_set_interface_alt_setting failed: %d\n", rc); rc = map_libusb_error (rc); goto leave; } -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); /* Perform any vendor specific intialization. */ rc = ccid_vendor_specific_init (*handle); @@ -1957,13 +1946,9 @@ do_close_reader (ccid_driver_t handle) while (!handle->powered_off) { DEBUGOUT ("libusb_handle_events_completed\n"); -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); libusb_handle_events_completed (NULL, &handle->powered_off); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); } } @@ -2094,15 +2079,11 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen, } } -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_out, msg, msglen, &transferred, 5000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); if (rc == 0 && transferred == msglen) return 0; @@ -2142,14 +2123,10 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, memset (buffer, 0, length); retry: -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in, buffer, length, &msglen, bwi*timeout); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); if (rc) { DEBUGOUT_1 ("usb_bulk_read error: %s\n", libusb_error_name (rc)); @@ -2298,9 +2275,7 @@ abort_cmd (ccid_driver_t handle, int seqno, int init) /* Send the abort command to the control pipe. Note that we don't need to keep track of sent abort commands because there should never be another thread using the same slot concurrently. */ -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); rc = libusb_control_transfer (handle->idev, 0x21,/* bmRequestType: host-to-device, class specific, to interface. */ @@ -2309,9 +2284,7 @@ abort_cmd (ccid_driver_t handle, int seqno, int init) handle->ifc_no, dummybuf, 0, 1000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); if (rc) { DEBUGOUT_1 ("usb_control_msg error: %s\n", libusb_error_name (rc)); @@ -2337,15 +2310,11 @@ abort_cmd (ccid_driver_t handle, int seqno, int init) msglen = 10; set_msg_len (msg, 0); -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_out, msg, msglen, &transferred, init? 100: 5000 /* ms timeout */); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); if (rc == 0 && transferred == msglen) rc = 0; else if (rc) @@ -2355,15 +2324,11 @@ abort_cmd (ccid_driver_t handle, int seqno, int init) if (rc) return map_libusb_error (rc); -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in, msg, sizeof msg, &msglen, init? 100: 5000 /*ms timeout*/); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); if (rc) { DEBUGOUT_1 ("usb_bulk_read error in abort_cmd: %s\n", @@ -2577,14 +2542,10 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits, int on_wire) if (!retries) { DEBUGOUT ("USB: CALLING USB_CLEAR_HALT\n"); -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); libusb_clear_halt (handle->idev, handle->ep_bulk_in); libusb_clear_halt (handle->idev, handle->ep_bulk_out); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); } else DEBUGOUT ("USB: RETRYING bulk_in AGAIN\n"); @@ -3353,13 +3314,9 @@ ccid_transceive (ccid_driver_t handle, if (tpdulen < 4) { -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); libusb_clear_halt (handle->idev, handle->ep_bulk_in); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); return CCID_DRIVER_ERR_ABORTED; } @@ -3811,13 +3768,9 @@ ccid_transceive_secure (ccid_driver_t handle, if (tpdulen < 4) { -#ifdef USE_NPTH - npth_unprotect (); -#endif + my_npth_unprotect (); libusb_clear_halt (handle->idev, handle->ep_bulk_in); -#ifdef USE_NPTH - npth_protect (); -#endif + my_npth_protect (); return CCID_DRIVER_ERR_ABORTED; } if (debug_level > 1) From 3ffcd533d4222653212d9a45d96aa86ec3e82911 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 7 Mar 2024 13:57:57 +0100 Subject: [PATCH 387/869] po: Fix a fuzzy in the German, Polish and Japanese translation -- --- po/de.po | 13 ++++++------- po/ja.po | 12 ++++++------ po/pl.po | 26 ++++++++++++++++---------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/po/de.po b/po/de.po index d4bf929ee..22ac2fcc0 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.4.1\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2024-01-24 14:05+0100\n" +"PO-Revision-Date: 2024-03-07 13:56+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German\n" "Language: de\n" @@ -2142,9 +2142,6 @@ msgstr "Ausgabe mit ASCII-Hülle versehen" msgid "|FILE|write output to FILE" msgstr "|DATEI|Ausgabe auf DATEI schreiben" -msgid "use canonical text mode" -msgstr "Textmodus benutzen" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|Kompressionsstufe auf N setzen (0=keine)" @@ -6801,8 +6798,8 @@ msgstr "Zugriff auf Admin-Befehle ist nicht eingerichtet\n" msgid "||Please enter the PIN" msgstr "||Bitte die PIN eingeben" -msgid "||Please enter the Reset Code for the card" -msgstr "Bitte geben Sie den Rückstellcode für diese Karte ein" +msgid "|R|Please enter the Reset Code for the card" +msgstr "|R|Bitte geben Sie den Rückstellcode für diese Karte ein" #, c-format msgid "Reset Code is too short; minimum length is %d\n" @@ -9116,6 +9113,9 @@ msgstr "Verwaltungskommandos für Yubikeys" msgid "manage the command history" msgstr "Verwaltung der Kommandohistorie" +#~ msgid "use canonical text mode" +#~ msgstr "Textmodus benutzen" + #~ msgid "continuing verification anyway due to option %s\n" #~ msgstr "Die Prüfung wird aufgrund der Option %s weiter durchgeführt\n" @@ -9298,7 +9298,6 @@ msgstr "Verwaltung der Kommandohistorie" #~ msgid "ldapserver missing" #~ msgstr "LDAP Server fehlt" -#, fuzzy #~ msgid "Suggest a random passphrase." #~ msgstr "Ein zufälliges Passwort vorschlagen" diff --git a/po/ja.po b/po/ja.po index ab6a8dda4..cc14e47bb 100644 --- a/po/ja.po +++ b/po/ja.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg 2.4.3\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2024-01-25 09:06+0900\n" +"PO-Revision-Date: 2024-03-07 13:59+0100\n" "Last-Translator: NIIBE Yutaka \n" "Language-Team: none\n" "Language: ja\n" @@ -2086,9 +2086,6 @@ msgstr "ASCII形式の外装を作成" msgid "|FILE|write output to FILE" msgstr "|FILE|出力をFILEに書き出す" -msgid "use canonical text mode" -msgstr "正準テキスト・モードを使用" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|圧縮レベルをNに設定 (0は非圧縮)" @@ -6484,8 +6481,8 @@ msgstr "管理コマンドへのアクセスが設定されていません\n" msgid "||Please enter the PIN" msgstr "||PINを入力してください" -msgid "||Please enter the Reset Code for the card" -msgstr "||カードのリセット・コードを入力してください" +msgid "|R|Please enter the Reset Code for the card" +msgstr "|R|カードのリセット・コードを入力してください" #, c-format msgid "Reset Code is too short; minimum length is %d\n" @@ -8738,6 +8735,9 @@ msgstr "Yubikey管理コマンド" msgid "manage the command history" msgstr "コマンド履歴を管理する" +#~ msgid "use canonical text mode" +#~ msgstr "正準テキスト・モードを使用" + #~ msgid "continuing verification anyway due to option %s\n" #~ msgstr "オプション %sのため、検証を続けます\n" diff --git a/po/pl.po b/po/pl.po index 1606612ef..a423f520c 100644 --- a/po/pl.po +++ b/po/pl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.4.4\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2024-01-28 15:45+0100\n" +"PO-Revision-Date: 2024-03-07 14:00+0100\n" "Last-Translator: Jakub Bogusz \n" "Language-Team: Polish \n" "Language: pl\n" @@ -1326,7 +1326,9 @@ msgstr "brak działającego dirmngr w tej sesji\n" #, c-format msgid "keyserver option \"honor-keyserver-url\" may not be used in Tor mode\n" -msgstr "opcja serwera kluczy „honor-keyserver-url” nie może być używana w trybie Tor\n" +msgstr "" +"opcja serwera kluczy „honor-keyserver-url” nie może być używana w trybie " +"Tor\n" msgid "WKD uses a cached result" msgstr "WKD używa zapamiętanego wyniku" @@ -2089,9 +2091,6 @@ msgstr "opakowanie ASCII pliku wynikowego" msgid "|FILE|write output to FILE" msgstr "|PLIK|zapis wyjścia do PLIKU" -msgid "use canonical text mode" -msgstr "kanoniczny format tekstowy" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|ustawienie poziomu kompresji N (0 - bez)" @@ -5324,7 +5323,8 @@ msgstr "klucz „%s” nie pasuje do żadnego identyfikatora użytkownika\n" #, c-format msgid "option %s given but no matching User ID found\n" -msgstr "podano opcję %s, ale nie znaleziono pasującego identyfikatora użytkownika\n" +msgstr "" +"podano opcję %s, ale nie znaleziono pasującego identyfikatora użytkownika\n" #, c-format msgid "WARNING: This key has been revoked by its designated revoker!\n" @@ -6496,7 +6496,8 @@ msgstr "nie można otworzyć fd %d: %s\n" #, c-format msgid "WARNING: encrypting without integrity protection is dangerous\n" -msgstr "OSTRZEŻENIE: szyfrowanie bez ochrony przed manipulacją jest niebezpieczne\n" +msgstr "" +"OSTRZEŻENIE: szyfrowanie bez ochrony przed manipulacją jest niebezpieczne\n" #, c-format msgid "Hint: Do not use option %s\n" @@ -6742,8 +6743,8 @@ msgstr "dostęp do poleceń administratora nie został skonfigurowany\n" msgid "||Please enter the PIN" msgstr "||Proszę wpisać PIN" -msgid "||Please enter the Reset Code for the card" -msgstr "||Proszę wprowadzić kod resetujący dla karty" +msgid "|R|Please enter the Reset Code for the card" +msgstr "|R|Proszę wprowadzić kod resetujący dla karty" #, c-format msgid "Reset Code is too short; minimum length is %d\n" @@ -8972,7 +8973,9 @@ msgstr "Wykryto kartę %s nr %s\n" #, c-format msgid "User Interaction Flag is set to \"%s\" - can't change\n" -msgstr "Flaga interakcji użytkownika (UIF) jest ustawiona na „%s” - nie można zmienić\n" +msgstr "" +"Flaga interakcji użytkownika (UIF) jest ustawiona na „%s” - nie można " +"zmienić\n" #, c-format msgid "" @@ -9015,3 +9018,6 @@ msgstr "polecenia zarządzające kluczami Yubikey" msgid "manage the command history" msgstr "zarządzanie historią poleceń" + +#~ msgid "use canonical text mode" +#~ msgstr "kanoniczny format tekstowy" From 348de4a8291a04ddeac349528af6730baf07d1c0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 7 Mar 2024 14:01:59 +0100 Subject: [PATCH 388/869] po: msgmerge -- --- po/ca.po | 8 ++++---- po/cs.po | 10 ++++++---- po/da.po | 10 ++++++---- po/el.po | 8 ++++---- po/eo.po | 8 ++++---- po/es.po | 10 ++++++---- po/et.po | 8 ++++---- po/fi.po | 8 ++++---- po/fr.po | 10 ++++++---- po/gl.po | 8 ++++---- po/hu.po | 8 ++++---- po/id.po | 8 ++++---- po/it.po | 10 ++++++---- po/nb.po | 10 ++++++---- po/pt.po | 10 ++++++---- po/ro.po | 8 ++++---- po/ru.po | 10 ++++++---- po/sk.po | 8 ++++---- po/sv.po | 10 ++++++---- po/tr.po | 10 ++++++---- po/uk.po | 10 ++++++---- po/zh_CN.po | 10 ++++++---- po/zh_TW.po | 10 ++++++---- 23 files changed, 118 insertions(+), 92 deletions(-) diff --git a/po/ca.po b/po/ca.po index b2c28e72f..b4f5b1424 100644 --- a/po/ca.po +++ b/po/ca.po @@ -2303,9 +2303,6 @@ msgstr "crea eixida amb armadura ascii" msgid "|FILE|write output to FILE" msgstr "|FITXER|carrega el mòdul d'extensió especificat" -msgid "use canonical text mode" -msgstr "usa el mode de text canònic" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "|N|nivell de compressió N (0 no comprimeix)" @@ -7132,7 +7129,7 @@ msgid "||Please enter the PIN" msgstr "canvia la contrasenya" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "Seleccioneu la raó de la revocació:\n" #, c-format @@ -9505,6 +9502,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "usa el mode de text canònic" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/cs.po b/po/cs.po index 8b6287734..91abc050a 100644 --- a/po/cs.po +++ b/po/cs.po @@ -2132,9 +2132,6 @@ msgstr "vytvořit výstup zapsaný v ASCII" msgid "|FILE|write output to FILE" msgstr "|SOUBOR|zapsat výstup do SOUBORU" -msgid "use canonical text mode" -msgstr "použít kanonický textový režim" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|nastavit úroveň komprese na N (0 – žádná)" @@ -6707,7 +6704,9 @@ msgstr "přístup k příkazům správce není nakonfigurován\n" msgid "||Please enter the PIN" msgstr "||Prosím, zadejte PIN" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Prosím, zadejte resetační kód karty" #, c-format @@ -8983,6 +8982,9 @@ msgstr "Příkazy pro správu Yubikey" msgid "manage the command history" msgstr "spravuje historii příkazů" +#~ msgid "use canonical text mode" +#~ msgstr "použít kanonický textový režim" + #~ msgid "selected AEAD algorithm is invalid\n" #~ msgstr "vybraný algoritmus AEAD je neplatný\n" diff --git a/po/da.po b/po/da.po index 602b28d75..9029f37ec 100644 --- a/po/da.po +++ b/po/da.po @@ -2334,9 +2334,6 @@ msgstr "opret ascii-pansrede uddata" msgid "|FILE|write output to FILE" msgstr "|FILE|skriv resultat til FIL" -msgid "use canonical text mode" -msgstr "brug kanonisk teksttilstand" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|sæt komprimeringsniveauet til N (0 deaktiverer)" @@ -7175,7 +7172,9 @@ msgstr "adgang til administratorkommandoer er ikke konfigureret\n" msgid "||Please enter the PIN" msgstr "||Indtast venligst PIN'en" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Indtast venligst nulstillingskoden for kortet" #, c-format @@ -9720,6 +9719,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "brug kanonisk teksttilstand" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/el.po b/po/el.po index 9417187b7..c2d740743 100644 --- a/po/el.po +++ b/po/el.po @@ -2232,9 +2232,6 @@ msgstr "δημιουργία ascii θωρακισμένης εξόδου" msgid "|FILE|write output to FILE" msgstr "|ΑΡΧΕΙΟ|φόρτωμα του αρθρώματος επέκτασης ΑΡΧΕΙΟ" -msgid "use canonical text mode" -msgstr "χρήση κανονικής κατάστασης κειμένου" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "|N|καθορισμός επιπέδου συμπίεσης N (0 απενεργοποιεί)" @@ -6997,7 +6994,7 @@ msgid "||Please enter the PIN" msgstr "αλλαγή της φράσης κλειδί" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "Παρακαλώ επιλέξτε την αιτία για την ανάκληση:\n" #, c-format @@ -9329,6 +9326,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "χρήση κανονικής κατάστασης κειμένου" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/eo.po b/po/eo.po index 3a9a4d130..16def7e84 100644 --- a/po/eo.po +++ b/po/eo.po @@ -2215,9 +2215,6 @@ msgstr "krei eligon en askia kiraso" msgid "|FILE|write output to FILE" msgstr "|DOSIERO|legi aldonan bibliotekon DOSIERO" -msgid "use canonical text mode" -msgstr "uzi tekstan reĝimon" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "|N|difini densig-nivelon N (0=nenia)" @@ -6906,7 +6903,7 @@ msgid "||Please enter the PIN" msgstr "ŝanĝi la pasfrazon" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "Kialo por revoko: " #, c-format @@ -9240,6 +9237,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "uzi tekstan reĝimon" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/es.po b/po/es.po index 7edbe88d7..16b13a7ff 100644 --- a/po/es.po +++ b/po/es.po @@ -2201,9 +2201,6 @@ msgstr "crea una salida ascii con armadura" msgid "|FILE|write output to FILE" msgstr "|FILE|volcar salida en FICHERO" -msgid "use canonical text mode" -msgstr "usa modo de texto canónico" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|nivel de compresión N (0 desactiva)" @@ -6848,7 +6845,9 @@ msgstr "el acceso a órdenes de administrador no está configurado\n" msgid "||Please enter the PIN" msgstr "||Por favor introduzca PIN" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Por favor introduzca Código de Reinicio de la tarjeta" #, c-format @@ -9166,6 +9165,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "usa modo de texto canónico" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/et.po b/po/et.po index 139ed412c..65019a83f 100644 --- a/po/et.po +++ b/po/et.po @@ -2223,9 +2223,6 @@ msgstr "loo ascii pakendis väljund" msgid "|FILE|write output to FILE" msgstr "|FAIL|lae laiendusmoodul FAIL" -msgid "use canonical text mode" -msgstr "kasuta kanoonilist tekstimoodi" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "|N|määra pakkimise tase N (0 blokeerib)" @@ -6917,7 +6914,7 @@ msgid "||Please enter the PIN" msgstr "muuda parooli" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "Palun valige tühistamise põhjus:\n" #, c-format @@ -9244,6 +9241,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "kasuta kanoonilist tekstimoodi" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/fi.po b/po/fi.po index 505f5c237..47388b28d 100644 --- a/po/fi.po +++ b/po/fi.po @@ -2240,9 +2240,6 @@ msgstr "tuota ascii-koodattu tuloste" msgid "|FILE|write output to FILE" msgstr "|TIEDOSTO|lataa laajennusmoduuli TIEDOSTO" -msgid "use canonical text mode" -msgstr "käytä tekstimuotoa" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "|N|aseta pakkausaste N (0 poistaa käytöstä)" @@ -6980,7 +6977,7 @@ msgid "||Please enter the PIN" msgstr "muuta salasanaa" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "Valitse mitätöinnin syy:\n" #, c-format @@ -9312,6 +9309,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "käytä tekstimuotoa" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/fr.po b/po/fr.po index 7baf95d2c..23f74aada 100644 --- a/po/fr.po +++ b/po/fr.po @@ -2260,9 +2260,6 @@ msgstr "créer une sortie ASCII avec armure" msgid "|FILE|write output to FILE" msgstr "|FICHIER|écrire la sortie dans le FICHIER" -msgid "use canonical text mode" -msgstr "utiliser le mode texte canonique" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|niveau de compression N (0 désactive)" @@ -7116,7 +7113,9 @@ msgstr "l'accès aux commandes d'administration n'est pas configuré\n" msgid "||Please enter the PIN" msgstr "||Veuillez entrer le code personnel" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Veuillez entrer le code de réinitialisation pour la carte" #, c-format @@ -9523,6 +9522,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "utiliser le mode texte canonique" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/gl.po b/po/gl.po index 5f408eabd..70cacffb3 100644 --- a/po/gl.po +++ b/po/gl.po @@ -2231,9 +2231,6 @@ msgstr "crear saída con armadura en ascii" msgid "|FILE|write output to FILE" msgstr "|FICHEIRO|carga-lo módulo de extensión FICHEIRO" -msgid "use canonical text mode" -msgstr "usar modo de texto canónico" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "|N|axusta-lo nivel de compresión a N (0 desactiva)" @@ -6981,7 +6978,7 @@ msgid "||Please enter the PIN" msgstr "cambia-lo contrasinal" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "Por favor, escolla o motivo da revocación:\n" #, c-format @@ -9324,6 +9321,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "usar modo de texto canónico" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/hu.po b/po/hu.po index 0955d468a..697b141cf 100644 --- a/po/hu.po +++ b/po/hu.po @@ -2223,9 +2223,6 @@ msgstr "ascii páncélozott kimenet létrehozása" msgid "|FILE|write output to FILE" msgstr "|fájl|bővítő modul betöltése" -msgid "use canonical text mode" -msgstr "kanonikus szöveges mód használata" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "|N|tömörítési szint beállítása N-re (0: tiltás)" @@ -6943,7 +6940,7 @@ msgid "||Please enter the PIN" msgstr "jelszóváltoztatás" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "Kérem, válassza ki a visszavonás okát:\n" #, c-format @@ -9271,6 +9268,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "kanonikus szöveges mód használata" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/id.po b/po/id.po index 5a22bb96d..b192b70d9 100644 --- a/po/id.po +++ b/po/id.po @@ -2227,9 +2227,6 @@ msgstr "ciptakan output ascii" msgid "|FILE|write output to FILE" msgstr "|FILE|muat modul ekstensi FILE" -msgid "use canonical text mode" -msgstr "gunakan mode teks kanonikal" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "|N|set tingkat kompresi N (0 tidak ada)" @@ -6942,7 +6939,7 @@ msgid "||Please enter the PIN" msgstr "ubah passphrase" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "Silakan pilih alasan untuk pembatalan:\n" #, c-format @@ -9270,6 +9267,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "gunakan mode teks kanonikal" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/it.po b/po/it.po index f3bcde883..39faf5469 100644 --- a/po/it.po +++ b/po/it.po @@ -2135,9 +2135,6 @@ msgstr "crea un output ascii con armatura" msgid "|FILE|write output to FILE" msgstr "|FILE|scrittura dell'output in FILE" -msgid "use canonical text mode" -msgstr "usa il modo testo canonico" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|Impostare il livello di compressione su N (0 disabilita)" @@ -6762,7 +6759,9 @@ msgstr "l'accesso ai comandi di amministrazione non è configurato\n" msgid "||Please enter the PIN" msgstr "||Inserisci il PIN" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Inserisci il Codice reset per la carta" #, c-format @@ -9078,6 +9077,9 @@ msgstr "Comandi di gestione Yubikey" msgid "manage the command history" msgstr "gestire la cronologia dei comandi" +#~ msgid "use canonical text mode" +#~ msgstr "usa il modo testo canonico" + #~ msgid "selected AEAD algorithm is invalid\n" #~ msgstr "l'algoritmo AEAD selezionato non è valido\n" diff --git a/po/nb.po b/po/nb.po index e79896ccb..98a6882a7 100644 --- a/po/nb.po +++ b/po/nb.po @@ -2171,9 +2171,6 @@ msgstr "lag ASCII-beskyttet utdata" msgid "|FILE|write output to FILE" msgstr "|FILE|skriv utdata til valgt FIL" -msgid "use canonical text mode" -msgstr "bruk kanonisk tekstmodus" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|endre komprimeringsnivå til N (0 for å slå av)" @@ -6770,7 +6767,9 @@ msgstr "tilgang til admin-kommandoer er ikke konfigurert\n" msgid "||Please enter the PIN" msgstr "||Skriv inn PIN-kode" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Skriv inn tilbakestillingskode for kortet" #, c-format @@ -9055,6 +9054,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "bruk kanonisk tekstmodus" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/pt.po b/po/pt.po index c0b052b2e..31f3fbec8 100644 --- a/po/pt.po +++ b/po/pt.po @@ -2157,9 +2157,6 @@ msgstr "criar saída blindada ASCII" msgid "|FILE|write output to FILE" msgstr "|FILE|escrever saída em FILE" -msgid "use canonical text mode" -msgstr "usar modo de texto canónico" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|definir nível de compressão para N (0 desabilita)" @@ -6726,7 +6723,9 @@ msgstr "o acesso aos comandos admin não está configurado\n" msgid "||Please enter the PIN" msgstr "||Introduza o PIN" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Introduza o Código de Reset do cartão" #, c-format @@ -8997,6 +8996,9 @@ msgstr "comandos de gerir uma Yubikey" msgid "manage the command history" msgstr "gerir o histórico de comandos" +#~ msgid "use canonical text mode" +#~ msgstr "usar modo de texto canónico" + #, c-format #~ msgid "waiting for process to terminate failed: ec=%d\n" #~ msgstr "falha ao esperar que o processo terminasse: ec=%d\n" diff --git a/po/ro.po b/po/ro.po index c7b55e2f1..39b43f663 100644 --- a/po/ro.po +++ b/po/ro.po @@ -2248,9 +2248,6 @@ msgstr "crează ieşire în armură ascii" msgid "|FILE|write output to FILE" msgstr "|FIŞIER|încarcă modulul extensie FIŞIER" -msgid "use canonical text mode" -msgstr "foloseşte modul text canonic" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "|N|setează nivel de compresie N (0 deactivează)" @@ -7056,7 +7053,7 @@ msgid "||Please enter the PIN" msgstr "||Vă rugăm introduceţi PIN%%0A[semnături făcute: %lu]" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Vă rugăm introduceţi PIN%%0A[semnături făcute: %lu]" #, fuzzy, c-format @@ -9415,6 +9412,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "foloseşte modul text canonic" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/ru.po b/po/ru.po index 47b9e3b56..b12d936b1 100644 --- a/po/ru.po +++ b/po/ru.po @@ -2158,9 +2158,6 @@ msgstr "вывод в текстовом формате" msgid "|FILE|write output to FILE" msgstr "|FILE|выводить данные в файл FILE" -msgid "use canonical text mode" -msgstr "использовать канонический текстовый режим" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|установить уровень сжатия N (0 - без сжатия)" @@ -6836,7 +6833,9 @@ msgstr "доступ к командам управления не настро msgid "||Please enter the PIN" msgstr "||Введите PIN" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Введите код сброса для карты" #, c-format @@ -9156,6 +9155,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "использовать канонический текстовый режим" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/sk.po b/po/sk.po index 638bc8955..6f31a693d 100644 --- a/po/sk.po +++ b/po/sk.po @@ -2231,9 +2231,6 @@ msgstr "vytvor výstup zakódovaný pomocou ASCII" msgid "|FILE|write output to FILE" msgstr "|SÚBOR|nahrať rozširujúci modul SÚBOR" -msgid "use canonical text mode" -msgstr "použiť kánonický textový mód" - #, fuzzy msgid "|N|set compress level to N (0 disables)" msgstr "" @@ -6969,7 +6966,7 @@ msgid "||Please enter the PIN" msgstr "zmeniť heslo" #, fuzzy -msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "Prosím výberte dôvod na revokáciu:\n" #, c-format @@ -9304,6 +9301,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "použiť kánonický textový mód" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/sv.po b/po/sv.po index 0e6951f81..b0e86cd32 100644 --- a/po/sv.po +++ b/po/sv.po @@ -2369,9 +2369,6 @@ msgstr "skapa utdata med ett ascii-skal" msgid "|FILE|write output to FILE" msgstr "|FIL|skriv utdata till FIL" -msgid "use canonical text mode" -msgstr "använd \"ursprunglig text\"-läget" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|ställ in komprimeringsnivån till N (0 för att inaktivera)" @@ -7294,7 +7291,9 @@ msgstr "åtkomst till administrationskommandon är inte konfigurerat\n" msgid "||Please enter the PIN" msgstr "||Ange PIN-koden" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Ange nollställningskoden för kortet" #, c-format @@ -9860,6 +9859,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "använd \"ursprunglig text\"-läget" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/tr.po b/po/tr.po index 95aa0aef5..f8a21ea2f 100644 --- a/po/tr.po +++ b/po/tr.po @@ -2101,9 +2101,6 @@ msgstr "ascii zırhlı çıktı oluştur" msgid "|FILE|write output to FILE" msgstr "|FILE|çıktıyı FILE'a yaz" -msgid "use canonical text mode" -msgstr "kurallı metin kipini kullan" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|sıkıştırma düzeyini N olarak ayarla (0 devre dışı bırakır)" @@ -6666,7 +6663,9 @@ msgstr "yönetici komutlarına erişim yapılandırılmamış\n" msgid "||Please enter the PIN" msgstr "||Lütfen PIN'i giriniz" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Lütfen kart için Sıfırlama Kodunu giriniz" #, c-format @@ -8918,3 +8917,6 @@ msgstr "Yubikey yönetim konsolu" msgid "manage the command history" msgstr "komut geçmişini yönet" + +#~ msgid "use canonical text mode" +#~ msgstr "kurallı metin kipini kullan" diff --git a/po/uk.po b/po/uk.po index 3f5bfedba..56c1939f5 100644 --- a/po/uk.po +++ b/po/uk.po @@ -2179,9 +2179,6 @@ msgstr "створити дані у форматі ASCII" msgid "|FILE|write output to FILE" msgstr "|FILE|записати дані до вказаного файла" -msgid "use canonical text mode" -msgstr "використовувати канонічний текстовий режим" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|встановити рівень стиснення (0 — вимкнути)" @@ -6937,7 +6934,9 @@ msgstr "доступ до адміністративних команд не н msgid "||Please enter the PIN" msgstr "||Вкажіть пінкод" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||Вкажіть код скидання коду картки" #, c-format @@ -9249,6 +9248,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "використовувати канонічний текстовий режим" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" diff --git a/po/zh_CN.po b/po/zh_CN.po index f48fdec84..a02d48f00 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -2075,9 +2075,6 @@ msgstr "创建 ASCII 字符封装的输出" msgid "|FILE|write output to FILE" msgstr "|FILE|写输出到 FILE" -msgid "use canonical text mode" -msgstr "使用规范的文本模式" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|设置压缩等级为 N (0 为禁用)" @@ -6435,7 +6432,9 @@ msgstr "未配置到管理员命令的访问\n" msgid "||Please enter the PIN" msgstr "||请输入 PIN" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||请输入卡片的重置码" #, c-format @@ -8675,6 +8674,9 @@ msgstr "Yubikey 管理命令" msgid "manage the command history" msgstr "管理命令历史记录" +#~ msgid "use canonical text mode" +#~ msgstr "使用规范的文本模式" + #~ msgid "continuing verification anyway due to option %s\n" #~ msgstr "由于 %s 选项,验证仍在继续中\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index aa5a1125e..8110f3d11 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -2189,9 +2189,6 @@ msgstr "建立以 ASCII 封裝過的輸出" msgid "|FILE|write output to FILE" msgstr "|檔案|將輸出寫入至指定檔案" -msgid "use canonical text mode" -msgstr "使用標準的文字模式" - msgid "|N|set compress level to N (0 disables)" msgstr "|N|設定壓縮等級為 N (0 表示不壓縮)" @@ -6778,7 +6775,9 @@ msgstr "管理者指令存取權限尚未組態\n" msgid "||Please enter the PIN" msgstr "||請輸入個人識別碼 (PIN)" -msgid "||Please enter the Reset Code for the card" +#, fuzzy +#| msgid "||Please enter the Reset Code for the card" +msgid "|R|Please enter the Reset Code for the card" msgstr "||請輸入卡片的重設碼" #, c-format @@ -9057,6 +9056,9 @@ msgstr "" msgid "manage the command history" msgstr "" +#~ msgid "use canonical text mode" +#~ msgstr "使用標準的文字模式" + #, fuzzy #~| msgid "selected digest algorithm is invalid\n" #~ msgid "selected AEAD algorithm is invalid\n" From cbff323b3b24c50f2bdef9b209c94516571c4df0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 7 Mar 2024 14:03:25 +0100 Subject: [PATCH 389/869] Release 2.4.5 --- NEWS | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f800e3dab..8647bcad6 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,44 @@ -Noteworthy changes in version 2.4.5 (unreleased) +Noteworthy changes in version 2.4.5 (2024-03-07) ------------------------------------------------ + * gpg,gpgv: New option --assert-pubkey-algo. [T6946] + + * gpg: Emit status lines for errors in the compression layer. + [T6977] + + * gpg: Fix invocation with --trusted-keys and --no-options. [T7025] + + * gpgsm: Allow for a longer salt in PKCS#12 files. [T6757] + + * gpgtar: Make --status-fd=2 work on Windows. [T6961] + + * scd: Support for the ACR-122U NFC reader. [rG1682ca9f01] + + * scd: Suport D-TRUST ECC cards. [T7000,T7001] + + * scd: Allow auto detaching of kernel drivers; can be disabled with + the new compatibility-flag ccid-no-auto-detach. [rGa1ea3b13e0] + + * scd: Allow setting a PIN length of 6 also with a reset code for + openpgp cards. [T6843] + + * agent: Allow GET_PASSPHRASE in restricted mode. [rGadf4db6e20] + + * dirmngr: Trust system's root CAs for checking CRL issuers. + [T6963] + + * dirmngr: Fix regression in 2.4.4 in fetching keys via hkps. + [T6997] + + * gpg-wks-client: Make option --mirror work properly w/o specifying + domains. [rG37cc255e49] + + * g13,gpg-wks-client: Allow command style options as in "g13 mount + foo". [rGa09157ccb2] + + * Allow tilde expansion for the foo-program options. [T7017] + + * Make the getswdb.sh tool usable outside the GnuPG tree. Release-info: https://dev.gnupg.org/T6960 From 609b1ec0c6ff485b42dfb72c7a5e21c7d6bfbb64 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 7 Mar 2024 15:10:47 +0100 Subject: [PATCH 390/869] Post release updates -- --- NEWS | 7 +++++++ configure.ac | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 8647bcad6..2182bd225 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +Noteworthy changes in version 2.4.6 (unreleased) +------------------------------------------------ + + + Release-info: https://dev.gnupg.org/T7030 + + Noteworthy changes in version 2.4.5 (2024-03-07) ------------------------------------------------ diff --git a/configure.ac b/configure.ac index ac4f08c12..db5f89947 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ min_automake_version="1.16.3" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [4]) -m4_define([mym4_micro], [5]) +m4_define([mym4_micro], [6]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release From 81536535f815187075b4bba8d2e43bdb0d0abd70 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 12 Mar 2024 16:04:19 +0100 Subject: [PATCH 391/869] card: Use xstrdup for module names. -- --- tools/gpg-card.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 8c9a26090..f24b74194 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -315,9 +315,9 @@ main (int argc, char **argv) /* Set defaults for non given options. */ if (!opt.gpg_program) - opt.gpg_program = gnupg_module_name (GNUPG_MODULE_NAME_GPG); + opt.gpg_program = xstrdup (gnupg_module_name (GNUPG_MODULE_NAME_GPG)); if (!opt.gpgsm_program) - opt.gpgsm_program = gnupg_module_name (GNUPG_MODULE_NAME_GPGSM); + opt.gpgsm_program = xstrdup (gnupg_module_name (GNUPG_MODULE_NAME_GPGSM)); /* Now build the list of commands. We guess the size of the array * by assuming each item is a complete command. Obviously this will From 14c1b73093e3fcbc43b04dfc520eb35d61241489 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 12 Mar 2024 18:01:24 +0100 Subject: [PATCH 392/869] gpg: new list-option show-x509-notations * g10/gpg.c (parse_list_options): Add new option. * g10/options.h (LIST_SHOW_X509_NOTATIONS): New. * g10/build-packet.c (search_sig_notations): New. * g10/keylist.c (print_x509_notations): New. (list_signature_print): Use macros for the sig classes. Call print_x509_notations. (list_keyblock_print): Call list_signature_print if x509 notation printing is enabled. --- doc/gpg.texi | 6 ++++ g10/build-packet.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ g10/gpg.c | 1 + g10/keylist.c | 69 +++++++++++++++++++++++++++++++++++++--------- g10/options.h | 1 + g10/packet.h | 7 +++-- 6 files changed, 134 insertions(+), 16 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index cb4506049..fb8d0f578 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1410,6 +1410,12 @@ give the opposite meaning. The options are: Show all, IETF standard, or user-defined signature notations in the @option{--check-signatures} listings. Defaults to no. + @item show-x509-notations + @opindex list-options:show-x509-notations + Print X.509 certificates embedded in key signatures as PEM data. + This is intended for debugging and the output format may change + without notice. + @item show-keyserver-urls @opindex list-options:show-keyserver-urls Show any preferred keyserver URL in the diff --git a/g10/build-packet.c b/g10/build-packet.c index 19a13760a..9927b7695 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -1748,6 +1748,72 @@ sig_to_notation(PKT_signature *sig) return list; } + +/* Return a list of notation data matching NAME. The caller needs to + * to free the list using free_notation. Other than sig_to_notation + * this function does not return the notation in human readable format + * but always returns the raw data. The human readable flag is set + * anyway set but .value is always NULL. */ +struct notation * +search_sig_notations (PKT_signature *sig, const char *name) +{ + const byte *p; + size_t len; + int seq = 0; + int crit; + notation_t list = NULL; + + while((p=enum_sig_subpkt (sig, 1, SIGSUBPKT_NOTATION, &len, &seq, &crit))) + { + int n1,n2; + struct notation *n=NULL; + + if (len < 8) + { + log_info (_("WARNING: invalid notation data found\n")); + continue; + } + + /* name length. */ + n1=(p[4]<<8)|p[5]; + /* value length. */ + n2=(p[6]<<8)|p[7]; + + if (8 + n1 + n2 != len) + { + log_info (_("WARNING: invalid notation data found\n")); + continue; + } + + if (!name) + ; /* Return everything. */ + else if (n1 != strlen (name) || memcmp (p+8, name, n1)) + continue; /* Not the requested name. */ + + + n = xmalloc_clear (sizeof *n); + n->name = xmalloc (n1+1); + + memcpy (n->name,p + 8, n1); + n->name[n1]='\0'; + + /* In any case append a Nul. */ + n->bdat = xmalloc (n2+1); + memcpy (n->bdat, p + 8 + n1, n2); + n->bdat[n2] = '\0'; + n->blen = n2; + n->flags.human = !!(p[0] & 0x80); + + n->flags.critical = crit; + + n->next = list; + list = n; + } + + return list; +} + + /* Release the resources associated with the *list* of notations. To release a single notation, make sure that notation->next is NULL. */ diff --git a/g10/gpg.c b/g10/gpg.c index bef3b6fbd..8e0c6479e 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2086,6 +2086,7 @@ parse_list_options(char *str) NULL}, {"show-user-notations",LIST_SHOW_USER_NOTATIONS,NULL, N_("show user-supplied notations during signature listings")}, + {"show-x509-notations",LIST_SHOW_X509_NOTATIONS,NULL, NULL }, {"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS,NULL, N_("show preferred keyserver URLs during signature listings")}, {"show-uid-validity",LIST_SHOW_UID_VALIDITY,NULL, diff --git a/g10/keylist.c b/g10/keylist.c index d0ebfc86f..20862b0f8 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1171,6 +1171,36 @@ dump_attribs (const PKT_user_id *uid, PKT_public_key *pk) } + +static void +print_x509_notations (struct notation *nots) +{ + gpg_error_t err; + gpgrt_b64state_t state; + + for (; nots; nots = nots->next) + { + state = gpgrt_b64enc_start (es_stdout, "CERTIFICATE"); + if (!state) + { + err = gpg_err_code_from_syserror (); + goto b64fail; + } + err = gpgrt_b64enc_write (state, nots->bdat, nots->blen); + if (err) + goto b64fail; + err = gpgrt_b64enc_finish (state); + if (err) + goto b64fail; + } + return; + + b64fail: + log_error ("error writing base64 encoded notation: %s\n", gpg_strerror (err)); + gpgrt_b64enc_finish (state); +} + + /* Order two signatures. We first order by keyid and then by creation * time. */ int @@ -1278,19 +1308,18 @@ list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node, sigrc = ' '; } - if (sig->sig_class == 0x20 || sig->sig_class == 0x28 - || sig->sig_class == 0x30) + if (IS_KEY_REV (sig) || IS_SUBKEY_REV (sig) || IS_UID_REV (sig)) { sigstr = "rev"; reason_code = get_revocation_reason (sig, &reason_text, &reason_comment, &reason_commentlen); } - else if ((sig->sig_class & ~3) == 0x10) + else if (IS_UID_SIG (sig)) sigstr = "sig"; - else if (sig->sig_class == 0x18) + else if (IS_SUBKEY_SIG (sig)) sigstr = "sig"; - else if (sig->sig_class == 0x1F) + else if (IS_KEY_SIG (sig)) sigstr = "sig"; else { @@ -1337,13 +1366,27 @@ list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node, show_policy_url (sig, 3, 0); if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS)) - show_notation (sig, 3, 0, - ((opt. - list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) - + - ((opt. - list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : - 0)); + show_notation (sig, 3, 0, + ((opt. + list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) + + + ((opt. + list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : + 0)); + + if (sig->flags.notation + && (opt.list_options & LIST_SHOW_X509_NOTATIONS)) + { + struct notation *nots; + + if ((IS_KEY_SIG (sig) || IS_SUBKEY_SIG (sig)) + && (nots = search_sig_notations (sig, + "x509certificate@pgp.com"))) + { + print_x509_notations (nots); + free_notation (nots); + } + } if (sig->flags.pref_ks && (opt.list_options & LIST_SHOW_KEYSERVER_URLS)) @@ -1599,7 +1642,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, if (opt.with_key_screening) print_pk_screening (pk2, 0); } - else if (opt.list_sigs + else if ((opt.list_sigs || (opt.list_options & LIST_SHOW_X509_NOTATIONS)) && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs) { kbnode_t n; diff --git a/g10/options.h b/g10/options.h index 476c30ad5..e4303a801 100644 --- a/g10/options.h +++ b/g10/options.h @@ -444,6 +444,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define LIST_SHOW_PREF (1<<14) #define LIST_SHOW_PREF_VERBOSE (1<<15) #define LIST_SHOW_UNUSABLE_SIGS (1<<16) +#define LIST_SHOW_X509_NOTATIONS (1<<17) #define VERIFY_SHOW_PHOTOS (1<<0) #define VERIFY_SHOW_POLICY_URLS (1<<1) diff --git a/g10/packet.h b/g10/packet.h index 76ec78017..a13d3cdc8 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -602,8 +602,8 @@ struct notation /* Sometimes we want to %-expand the value. In these cases, we save that transformed value here. */ char *altvalue; - /* If the notation is not human readable, then the value is stored - here. */ + /* If the notation is not human readable or the function does not + want to distinguish that, then the value is stored here. */ unsigned char *bdat; /* The amount of data stored in BDAT. @@ -877,7 +877,8 @@ struct notation *string_to_notation(const char *string,int is_utf8); struct notation *blob_to_notation(const char *name, const char *data, size_t len); struct notation *sig_to_notation(PKT_signature *sig); -void free_notation(struct notation *notation); +struct notation *search_sig_notations (PKT_signature *sig, const char *name); +void free_notation (struct notation *notation); /*-- free-packet.c --*/ void free_symkey_enc( PKT_symkey_enc *enc ); From c27534de955370dde2f516d217e4c1bb117d2697 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 13 Mar 2024 15:32:10 +0100 Subject: [PATCH 393/869] gpg-check-pattern: Consider an empty pattern file as valid * tools/gpg-check-pattern.c (read_file): Check length before calling fread. -- The problem with an empty file is that es_fread is called to read one element of length zero which seems to be undefined behaviour and results in ENOENT on my test box. --- tools/gpg-check-pattern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gpg-check-pattern.c b/tools/gpg-check-pattern.c index d7481fffb..2698431c9 100644 --- a/tools/gpg-check-pattern.c +++ b/tools/gpg-check-pattern.c @@ -285,7 +285,7 @@ read_file (const char *fname, size_t *r_length) buflen = st.st_size; buf = xmalloc (buflen+1); - if (es_fread (buf, buflen, 1, fp) != 1) + if (buflen && es_fread (buf, buflen, 1, fp) != 1) { log_error ("error reading '%s': %s\n", fname, strerror (errno)); es_fclose (fp); From f78501c54532fe091174b1b8a1c747fa4c4cda4f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 14 Mar 2024 20:58:01 +0100 Subject: [PATCH 394/869] gpg: new list-option store-x509-notations. * g10/options.h (LIST_STORE_X509_NOTATIONS): New. * g10/gpg.c (parse_list_options): Add "store-x509-notations". * g10/keylist.c (print_x509_notations): Add arg PK and code to write a file. (list_signature_print): Add arg lastpk and handle new option. (list_keyblock_print): Track last key or subkey and pass to list_signature_print. --- doc/gpg.texi | 6 ++++++ g10/gpg.c | 1 + g10/keylist.c | 54 +++++++++++++++++++++++++++++++++++++++++++-------- g10/options.h | 1 + 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index fb8d0f578..e3a6109c9 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1416,6 +1416,12 @@ give the opposite meaning. The options are: This is intended for debugging and the output format may change without notice. + @item store-x509-notations + @opindex list-options:store-x509-notations + Store X.509 certificates embedded in key signatures as PEM data + files. The filename consists the 4 byte key ID of the certificate, + a dash, the fingerprint of the key or subkey, and the suffix ".pem". + @item show-keyserver-urls @opindex list-options:show-keyserver-urls Show any preferred keyserver URL in the diff --git a/g10/gpg.c b/g10/gpg.c index 8e0c6479e..658b7c7c8 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2087,6 +2087,7 @@ parse_list_options(char *str) {"show-user-notations",LIST_SHOW_USER_NOTATIONS,NULL, N_("show user-supplied notations during signature listings")}, {"show-x509-notations",LIST_SHOW_X509_NOTATIONS,NULL, NULL }, + {"store-x509-notations",LIST_STORE_X509_NOTATIONS,NULL, NULL }, {"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS,NULL, N_("show preferred keyserver URLs during signature listings")}, {"show-uid-validity",LIST_SHOW_UID_VALIDITY,NULL, diff --git a/g10/keylist.c b/g10/keylist.c index 20862b0f8..3d43d9e63 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1172,15 +1172,36 @@ dump_attribs (const PKT_user_id *uid, PKT_public_key *pk) +/* If PK is given the output is written to a new file instead of + * stdout. */ static void -print_x509_notations (struct notation *nots) +print_x509_notations (struct notation *nots, PKT_public_key *pk) { gpg_error_t err; - gpgrt_b64state_t state; + gpgrt_b64state_t state = NULL; + char hexfpr[2*4 + 1 + 2*MAX_FINGERPRINT_LEN+4+1]; + char sha1[20]; + estream_t fp; for (; nots; nots = nots->next) { - state = gpgrt_b64enc_start (es_stdout, "CERTIFICATE"); + if (pk) + { + gcry_md_hash_buffer (GCRY_MD_SHA1, sha1, nots->bdat, nots->blen); + bin2hex (sha1+16, 4, hexfpr); + hexfpr[2*4] = '-'; + hexfingerprint (pk, hexfpr + 2*4+1, 2*MAX_FINGERPRINT_LEN); + strcat (hexfpr, ".pem"); + fp = es_fopen (hexfpr, "w"); + if (!fp) + { + err = gpg_err_code_from_syserror (); + goto b64fail; + } + } + else + fp = es_stdout; + state = gpgrt_b64enc_start (fp, "CERTIFICATE"); if (!state) { err = gpg_err_code_from_syserror (); @@ -1192,12 +1213,19 @@ print_x509_notations (struct notation *nots) err = gpgrt_b64enc_finish (state); if (err) goto b64fail; + if (fp != es_stdout) + { + es_fclose (fp); + fp = NULL; + } } return; b64fail: log_error ("error writing base64 encoded notation: %s\n", gpg_strerror (err)); gpgrt_b64enc_finish (state); + if (fp && fp != es_stdout) + gpgrt_fcancel (fp); } @@ -1250,7 +1278,7 @@ cmp_signodes (const void *av, const void *bv) * NODFLG_MARK_B to indicate self-signatures. */ static void list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node, - struct keylist_context *listctx) + struct keylist_context *listctx, PKT_public_key *lastpk) { /* (extra indentation to keep the diff history short) */ PKT_signature *sig = node->pkt->pkt.signature; @@ -1375,7 +1403,8 @@ list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node, 0)); if (sig->flags.notation - && (opt.list_options & LIST_SHOW_X509_NOTATIONS)) + && (opt.list_options + & (LIST_SHOW_X509_NOTATIONS|LIST_STORE_X509_NOTATIONS))) { struct notation *nots; @@ -1383,7 +1412,10 @@ list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node, && (nots = search_sig_notations (sig, "x509certificate@pgp.com"))) { - print_x509_notations (nots); + if ((opt.list_options & LIST_STORE_X509_NOTATIONS)) + print_x509_notations (nots, lastpk); + else + print_x509_notations (nots, NULL); free_notation (nots); } } @@ -1437,6 +1469,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, int rc; kbnode_t node; PKT_public_key *pk; + PKT_public_key *lastpk; u32 *mainkid; int skip_sigs = 0; char *hexgrip = NULL; @@ -1453,6 +1486,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, pk = node->pkt->pkt.public_key; mainkid = pk_keyid (pk); + lastpk = pk; if (secret || opt.with_keygrip) { @@ -1601,6 +1635,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, { PKT_public_key *pk2 = node->pkt->pkt.public_key; + lastpk = pk2; if ((pk2->flags.revoked || pk2->has_expired) && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS)) { @@ -1642,7 +1677,9 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, if (opt.with_key_screening) print_pk_screening (pk2, 0); } - else if ((opt.list_sigs || (opt.list_options & LIST_SHOW_X509_NOTATIONS)) + else if ((opt.list_sigs + || (opt.list_options + & (LIST_SHOW_X509_NOTATIONS|LIST_STORE_X509_NOTATIONS))) && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs) { kbnode_t n; @@ -1670,7 +1707,8 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, qsort (sigarray, sigcount, sizeof *sigarray, cmp_signodes); for (idx=0; idx < sigcount; idx++) - list_signature_print (ctrl, keyblock, sigarray[idx], listctx); + list_signature_print (ctrl, keyblock, sigarray[idx], listctx, + lastpk); xfree (sigarray); } } diff --git a/g10/options.h b/g10/options.h index e4303a801..ed8e122a3 100644 --- a/g10/options.h +++ b/g10/options.h @@ -445,6 +445,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define LIST_SHOW_PREF_VERBOSE (1<<15) #define LIST_SHOW_UNUSABLE_SIGS (1<<16) #define LIST_SHOW_X509_NOTATIONS (1<<17) +#define LIST_STORE_X509_NOTATIONS (1<<18) #define VERIFY_SHOW_PHOTOS (1<<0) #define VERIFY_SHOW_POLICY_URLS (1<<1) From 50e81ad38d2b5a5028fa6815da358c0496aa927e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 14 Mar 2024 21:41:15 +0100 Subject: [PATCH 395/869] gpg: Make sure a DECRYPTION_OKAY is never issued for a bad OCB tag. * g10/mainproc.c (proc_encrypted): Force a decryption failure if any error has been seen. * g10/decrypt-data.c (aead_checktag): Issue an ERROR line. -- GnuPG-bug-id: 7042 Note that gpg in any case returns a failure exit code but due to double forking GPGME would not see it. --- g10/decrypt-data.c | 1 + g10/mainproc.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 86e208d01..ea4d48955 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -205,6 +205,7 @@ aead_checktag (decode_filter_ctx_t dfx, int final, const void *tagbuf) { log_error ("gcry_cipher_checktag%s failed: %s\n", final? " (final)":"", gpg_strerror (err)); + write_status_error ("aead_checktag", err); return err; } if (DBG_FILTER) diff --git a/g10/mainproc.c b/g10/mainproc.c index 043b34f62..d2e00514f 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -781,9 +781,13 @@ proc_encrypted (CTX c, PACKET *pkt) compliance_de_vs |= 2; } - /* Trigger the deferred error. */ + /* Trigger the deferred error. The second condition makes sure that a + * log_error printed in the cry_cipher_checktag never gets ignored. */ if (!result && early_plaintext) result = gpg_error (GPG_ERR_BAD_DATA); + else if (!result && pkt->pkt.encrypted->aead_algo + && log_get_errorcount (0)) + result = gpg_error (GPG_ERR_BAD_SIGNATURE); if (result == -1) ; From 122803bf1ac9ee720d9fc214f5ae5c2a0ec22bf5 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 14 Mar 2024 21:41:15 +0100 Subject: [PATCH 396/869] gpg: Make sure a DECRYPTION_OKAY is never issued for a bad OCB tag. * g10/mainproc.c (proc_encrypted): Force a decryption failure if any error has been seen. * g10/decrypt-data.c (aead_checktag): Issue an ERROR line. -- GnuPG-bug-id: 7042 Note that gpg in any case returns a failure exit code but due to double forking GPGME would not see it. --- g10/decrypt-data.c | 1 + g10/mainproc.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c index 86e208d01..ea4d48955 100644 --- a/g10/decrypt-data.c +++ b/g10/decrypt-data.c @@ -205,6 +205,7 @@ aead_checktag (decode_filter_ctx_t dfx, int final, const void *tagbuf) { log_error ("gcry_cipher_checktag%s failed: %s\n", final? " (final)":"", gpg_strerror (err)); + write_status_error ("aead_checktag", err); return err; } if (DBG_FILTER) diff --git a/g10/mainproc.c b/g10/mainproc.c index 5f3f6df86..e722618ca 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -781,9 +781,13 @@ proc_encrypted (CTX c, PACKET *pkt) compliance_de_vs |= 2; } - /* Trigger the deferred error. */ + /* Trigger the deferred error. The second condition makes sure that a + * log_error printed in the cry_cipher_checktag never gets ignored. */ if (!result && early_plaintext) result = gpg_error (GPG_ERR_BAD_DATA); + else if (!result && pkt->pkt.encrypted->aead_algo + && log_get_errorcount (0)) + result = gpg_error (GPG_ERR_BAD_SIGNATURE); if (result == -1) ; From 759adb249310abff30e707c0800c9910de97a6dd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 18 Mar 2024 11:14:19 +0100 Subject: [PATCH 397/869] gpgconf: Check readability of some files with -X * tools/gpgconf.c (list_dirs): Rename arg from special to show_config_mode. Add "S.Uiserver" test and test existsing files for readability. --- tools/gpgconf.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 6a5add42b..0515aa807 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -260,10 +260,10 @@ gpgconf_write_status (int no, const char *format, ...) static void -list_dirs (estream_t fp, char **names, int special) +list_dirs (estream_t fp, char **names, int show_config_mode) { static struct { - const char *name; + const char *name; /* If NULL only a file check will be done. */ const char *(*fnc)(void); const char *extra; } list[] = { @@ -280,12 +280,13 @@ list_dirs (estream_t fp, char **names, int special) { "agent-extra-socket", gnupg_socketdir, GPG_AGENT_EXTRA_SOCK_NAME }, { "agent-browser-socket",gnupg_socketdir, GPG_AGENT_BROWSER_SOCK_NAME }, { "agent-socket", gnupg_socketdir, GPG_AGENT_SOCK_NAME }, + { NULL, gnupg_socketdir, "S.uiserver" }, { "homedir", gnupg_homedir, NULL } }; int idx, j; char *tmp; const char *s; - + gpg_error_t err; for (idx = 0; idx < DIM (list); idx++) { @@ -297,7 +298,10 @@ list_dirs (estream_t fp, char **names, int special) } else tmp = NULL; - if (!names) + + if (!list[idx].name) + ; + else if (!names) es_fprintf (fp, "%s:%s\n", list[idx].name, gc_percent_escape (s)); else { @@ -309,6 +313,23 @@ list_dirs (estream_t fp, char **names, int special) } } + /* In show config mode check that the socket files are accessible. */ + if (list[idx].extra && show_config_mode) + { + estream_t tmpfp; + + tmpfp = es_fopen (s, "rb"); + if (tmpfp) + es_fclose (tmpfp); /* All fine - we can read that file. */ + else if ((err=gpg_error_from_syserror ()) == GPG_ERR_ENOENT + || err == GPG_ERR_ENXIO) + ; /* No such file/ No such device or address - this is okay. */ + else + es_fprintf (fp, + "### Warning: error reading existing file '%s': %s\n", + s, gpg_strerror (err)); + } + xfree (tmp); } @@ -339,7 +360,7 @@ list_dirs (estream_t fp, char **names, int special) } es_fflush (fp); - if (special) + if (show_config_mode) es_fprintf (fp, "\n" "### Note: homedir taken from registry key %s%s\\%s:%s\n" "\n", @@ -357,7 +378,7 @@ list_dirs (estream_t fp, char **names, int special) { xfree (tmp); es_fflush (fp); - if (special) + if (show_config_mode) es_fprintf (fp, "\n" "### Note: registry %s without value in HKCU or HKLM\n" "\n", GNUPG_REGISTRY_DIR); @@ -367,7 +388,7 @@ list_dirs (estream_t fp, char **names, int special) } #else /*!HAVE_W32_SYSTEM*/ - (void)special; + (void)show_config_mode; #endif /*!HAVE_W32_SYSTEM*/ } @@ -1342,7 +1363,7 @@ show_versions (estream_t fp) /* Copy data from file SRC to DST. Returns 0 on success or an error * code on failure. If LISTP is not NULL, that strlist is updated - * with the variabale or registry key names detected. Flag bit 0 + * with the variable or registry key names detected. Flag bit 0 * indicates a registry entry. */ static gpg_error_t my_copy_file (estream_t src, estream_t dst, strlist_t *listp) From fb3fe38d2831c29865b6e95b9319625a33875334 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 21 Mar 2024 15:41:17 +0100 Subject: [PATCH 398/869] common: Use a common gpgconf.ctl parser for Unix and Windows. * common/homedir.c (gpgconf_ctl): new struct. (string_is_true): New. (parse_gpgconf_ctl): New. Based on the former code in unix_rootdir. (check_portable_app): Use parse_gpgconf_ctl and the new struct. (unix_rootdir): Ditto. -- This is a unification of the gpgconf.ctl mechanism. For backward compatibility we need to keep the empty (or actually only comments) method as used formerly under Windows. Iff one really wants a portable application the new portable keyword should be used, though. Noet that the Windows portable stuff has not been tested for quite some time. --- common/homedir.c | 451 ++++++++++++++++++++++++++--------------------- doc/tools.texi | 3 +- 2 files changed, 252 insertions(+), 202 deletions(-) diff --git a/common/homedir.c b/common/homedir.c index 6f99f3eab..d38c94a05 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -93,6 +93,21 @@ static char *the_gnupg_homedir; static byte non_default_homedir; +/* An object to store information taken from a gpgconf.ctl file. This + * is parsed early at startup time and never changed later. */ +static struct +{ + unsigned int checked:1; /* True if we have checked for a gpgconf.ctl. */ + unsigned int found:1; /* True if a gpgconf.ctl was found. */ + unsigned int empty:1; /* The file is empty except for comments. */ + unsigned int valid:1; /* The entries in gpgconf.ctl are valid. */ + unsigned int portable:1;/* Windows portable installation. */ + char *rootdir; /* rootdir or NULL */ + char *sysconfdir; /* sysconfdir or NULL */ + char *socketdir; /* socketdir or NULL */ +} gpgconf_ctl; + + #ifdef HAVE_W32_SYSTEM /* A flag used to indicate that a control file for gpgconf has been * detected. Under Windows the presence of this file indicates a @@ -427,6 +442,212 @@ default_homedir (void) } +/* Return true if S can be inteprtated as true. This is uised for + * keywords in gpgconf.ctl. Spaces must have been trimmed. */ +static int +string_is_true (const char *s) +{ + return (atoi (s) + || !ascii_strcasecmp (s, "yes") + || !ascii_strcasecmp (s, "true") + || !ascii_strcasecmp (s, "fact")); +} + +/* This function is used to parse the gpgconf.ctl file and set the + * information ito the gpgconf_ctl structure. This is called once + * with the full filename of gpgconf.ctl. There are two callers: One + * used on Windows and one on Unix. No error return but diagnostics + * are printed. */ +static void +parse_gpgconf_ctl (const char *fname) +{ + gpg_error_t err; + char *p; + char *line; + size_t linelen; + ssize_t length; + estream_t fp; + const char *name; + int anyitem = 0; + int ignoreall = 0; + char *rootdir = NULL; + char *sysconfdir = NULL; + char *socketdir = NULL; + + if (gpgconf_ctl.checked) + return; /* Just in case this is called a second time. */ + gpgconf_ctl.checked = 1; + gpgconf_ctl.found = 0; + gpgconf_ctl.valid = 0; + gpgconf_ctl.empty = 0; + + if (gnupg_access (fname, F_OK)) + return; /* No gpgconf.ctl file. */ + + /* log_info ("detected '%s'\n", buffer); */ + fp = es_fopen (fname, "r"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_info ("error opening '%s': %s\n", fname, gpg_strerror (err)); + return; + } + gpgconf_ctl.found = 1; + + line = NULL; + linelen = 0; + while ((length = es_read_line (fp, &line, &linelen, NULL)) > 0) + { + static const char *names[] = + { + "rootdir", + "sysconfdir", + "socketdir", + "portable", + ".enable" + }; + int i; + size_t n; + + /* Strip NL and CR, if present. */ + while (length > 0 + && (line[length - 1] == '\n' || line[length - 1] == '\r')) + line[--length] = 0; + trim_spaces (line); + if (*line == '#' || !*line) + continue; + anyitem = 1; + + /* Find the keyword. */ + name = NULL; + p = NULL; + for (i=0; i < DIM (names); i++) + { + n = strlen (names[i]); + if (!strncmp (line, names[i], n)) + { + while (line[n] == ' ' || line[n] == '\t') + n++; + if (line[n] == '=') + { + name = names[i]; + p = line + n + 1; + break; + } + } + } + if (!name) + continue; /* Keyword not known. */ + + trim_spaces (p); + p = substitute_envvars (p); + if (!p) + { + err = gpg_error_from_syserror (); + log_info ("error getting %s from gpgconf.ctl: %s\n", + name, gpg_strerror (err)); + } + else if (!strcmp (name, ".enable")) + { + if (string_is_true (p)) + ; /* Yes, this file shall be used. */ + else + ignoreall = 1; /* No, this file shall be ignored. */ + xfree (p); + } + else if (!strcmp (name, "sysconfdir")) + { + xfree (sysconfdir); + sysconfdir = p; + } + else if (!strcmp (name, "socketdir")) + { + xfree (socketdir); + socketdir = p; + } + else if (!strcmp (name, "rootdir")) + { + xfree (rootdir); + rootdir = p; + } + else if (!strcmp (name, "portable")) + { + gpgconf_ctl.portable = string_is_true (p); + xfree (p); + } + else /* Unknown keyword. */ + xfree (p); + } + if (es_ferror (fp)) + { + err = gpg_error_from_syserror (); + log_info ("error reading '%s': %s\n", fname, gpg_strerror (err)); + ignoreall = 1; /* Force all entries to invalid. */ + } + es_fclose (fp); + xfree (line); + + if (ignoreall) + ; /* Forced error. Note that .found is still set. */ + else if (rootdir && (!*rootdir || *rootdir != '/')) + { + log_info ("invalid %s '%s' specified in gpgconf.ctl\n", + "rootdir", rootdir); + } + else if (sysconfdir && (!*sysconfdir || *sysconfdir != '/')) + { + log_info ("invalid %s '%s' specified in gpgconf.ctl\n", + "sysconfdir", sysconfdir); + } + else if (socketdir && (!*socketdir || *socketdir != '/')) + { + log_info ("invalid %s '%s' specified in gpgconf.ctl\n", + "socketdir", socketdir); + } + else + { + if (rootdir) + { + while (*rootdir && rootdir[strlen (rootdir)-1] == '/') + rootdir[strlen (rootdir)-1] = 0; + gpgconf_ctl.rootdir = rootdir; + gpgrt_annotate_leaked_object (gpgconf_ctl.rootdir); + /* log_info ("want rootdir '%s'\n", dir); */ + } + if (sysconfdir) + { + while (*sysconfdir && sysconfdir[strlen (sysconfdir)-1] == '/') + sysconfdir[strlen (sysconfdir)-1] = 0; + gpgconf_ctl.sysconfdir = sysconfdir; + gpgrt_annotate_leaked_object (gpgconf_ctl.sysconfdir); + /* log_info ("want sysconfdir '%s'\n", sdir); */ + } + if (socketdir) + { + while (*socketdir && socketdir[strlen (socketdir)-1] == '/') + socketdir[strlen (socketdir)-1] = 0; + gpgconf_ctl.socketdir = socketdir; + gpgrt_annotate_leaked_object (gpgconf_ctl.socketdir); + /* log_info ("want socketdir '%s'\n", s2dir); */ + } + gpgconf_ctl.valid = 1; + } + + gpgconf_ctl.empty = !anyitem; + if (!gpgconf_ctl.valid) + { + /* Error reading some entries - clear them all. */ + xfree (rootdir); + xfree (sysconfdir); + xfree (socketdir); + gpgconf_ctl.rootdir = NULL; + gpgconf_ctl.sysconfdir = NULL; + gpgconf_ctl.socketdir = NULL; + } +} + + + #ifdef HAVE_W32_SYSTEM /* Check whether gpgconf is installed and if so read the gpgconf.ctl file. */ @@ -439,17 +660,20 @@ check_portable_app (const char *dir) if (!gnupg_access (fname, F_OK)) { strcpy (fname + strlen (fname) - 3, "ctl"); - if (!gnupg_access (fname, F_OK)) + parse_gpgconf_ctl (fname); + if ((gpgconf_ctl.found && gpgconf_ctl.empty) + || (gpgconf_ctl.valid && gpgconf_ctl.portable)) { - /* gpgconf.ctl file found. Record this fact. */ + unsigned int flags; + + /* Classic gpgconf.ctl file found. This is a portable + * application. Note that if there are any items in that + * file we don't consider this a portable application unless + * the (later added) ".portable" keyword has also been + * seen. */ w32_portable_app = 1; - { - unsigned int flags; - log_get_prefix (&flags); - log_set_prefix (NULL, (flags | GPGRT_LOG_NO_REGISTRY)); - } - /* FIXME: We should read the file to detect special flags - and print a warning if we don't understand them */ + log_get_prefix (&flags); + log_set_prefix (NULL, (flags | GPGRT_LOG_NO_REGISTRY)); } } xfree (fname); @@ -528,28 +752,14 @@ w32_rootdir (void) static const char * unix_rootdir (enum wantdir_values wantdir) { - static int checked; - static char *dir; /* for the rootdir */ - static char *sdir; /* for the sysconfdir */ - static char *s2dir; /* for the socketdir */ - - if (!checked) + if (!gpgconf_ctl.checked) { char *p; char *buffer; size_t bufsize = 256-1; int nread; gpg_error_t err; - char *line; - size_t linelen; - ssize_t length; - estream_t fp; - char *rootdir; - char *sysconfdir; - char *socketdir; const char *name; - int ignoreall = 0; - int okay; for (;;) { @@ -589,7 +799,7 @@ unix_rootdir (enum wantdir_values wantdir) if (!*buffer) { xfree (buffer); - checked = 1; + gpgconf_ctl.checked = 1; return NULL; /* Error - assume no gpgconf.ctl. */ } @@ -597,197 +807,36 @@ unix_rootdir (enum wantdir_values wantdir) if (!p) { xfree (buffer); - checked = 1; + gpgconf_ctl.checked = 1; return NULL; /* Erroneous /proc - assume no gpgconf.ctl. */ } *p = 0; /* BUFFER has the directory. */ - if ((p = strrchr (buffer, '/'))) - { - /* Strip one part and expect the file below a bin dir. */ - *p = 0; - p = xstrconcat (buffer, "/bin/gpgconf.ctl", NULL); - xfree (buffer); - buffer = p; - } - else /* !p */ + if (!(p = strrchr (buffer, '/'))) { /* Installed in the root which is not a good idea. Assume * no gpgconf.ctl. */ xfree (buffer); - checked = 1; + gpgconf_ctl.checked = 1; return NULL; } - if (gnupg_access (buffer, F_OK)) - { - /* No gpgconf.ctl file. */ - xfree (buffer); - checked = 1; - return NULL; - } - /* log_info ("detected '%s'\n", buffer); */ - fp = es_fopen (buffer, "r"); - if (!fp) - { - err = gpg_error_from_syserror (); - log_info ("error opening '%s': %s\n", buffer, gpg_strerror (err)); - xfree (buffer); - checked = 1; - return NULL; - } - - line = NULL; - linelen = 0; - rootdir = NULL; - sysconfdir = NULL; - socketdir = NULL; - while ((length = es_read_line (fp, &line, &linelen, NULL)) > 0) - { - static const char *names[] = - { - "rootdir", - "sysconfdir", - "socketdir", - ".enable" - }; - int i; - size_t n; - - /* Strip NL and CR, if present. */ - while (length > 0 - && (line[length - 1] == '\n' || line[length - 1] == '\r')) - line[--length] = 0; - trim_spaces (line); - /* Find the stamement. */ - name = NULL; - for (i=0; i < DIM (names); i++) - { - n = strlen (names[i]); - if (!strncmp (line, names[i], n)) - { - while (line[n] == ' ' || line[n] == '\t') - n++; - if (line[n] == '=') - { - name = names[i]; - p = line + n + 1; - break; - } - } - } - if (!name) - continue; /* Statement not known. */ - - trim_spaces (p); - p = substitute_envvars (p); - if (!p) - { - err = gpg_error_from_syserror (); - log_info ("error getting %s from gpgconf.ctl: %s\n", - name, gpg_strerror (err)); - } - else if (!strcmp (name, ".enable")) - { - if (atoi (p) - || !ascii_strcasecmp (p, "yes") - || !ascii_strcasecmp (p, "true") - || !ascii_strcasecmp (p, "fact")) - ; /* Yes, this file shall be used. */ - else - ignoreall = 1; /* No, this file shall be ignored. */ - xfree (p); - } - else if (!strcmp (name, "sysconfdir")) - { - xfree (sysconfdir); - sysconfdir = p; - } - else if (!strcmp (name, "socketdir")) - { - xfree (socketdir); - socketdir = p; - } - else - { - xfree (rootdir); - rootdir = p; - } - } - if (es_ferror (fp)) - { - err = gpg_error_from_syserror (); - log_info ("error reading '%s': %s\n", buffer, gpg_strerror (err)); - es_fclose (fp); - xfree (buffer); - xfree (line); - xfree (rootdir); - xfree (sysconfdir); - xfree (socketdir); - checked = 1; - return NULL; - } - es_fclose (fp); + /* Strip one part and expect the file below a bin dir. */ + *p = 0; + p = xstrconcat (buffer, "/bin/gpgconf.ctl", NULL); + xfree (buffer); + buffer = p; + parse_gpgconf_ctl (buffer); xfree (buffer); - xfree (line); - - okay = 0; - if (ignoreall) - ; - else if (!rootdir || !*rootdir || *rootdir != '/') - { - log_info ("invalid rootdir '%s' specified in gpgconf.ctl\n", rootdir); - } - else if (sysconfdir && (!*sysconfdir || *sysconfdir != '/')) - { - log_info ("invalid sysconfdir '%s' specified in gpgconf.ctl\n", - sysconfdir); - } - else if (socketdir && (!*socketdir || *socketdir != '/')) - { - log_info ("invalid socketdir '%s' specified in gpgconf.ctl\n", - socketdir); - } - else - { - okay = 1; - while (*rootdir && rootdir[strlen (rootdir)-1] == '/') - rootdir[strlen (rootdir)-1] = 0; - dir = rootdir; - gpgrt_annotate_leaked_object (dir); - /* log_info ("want rootdir '%s'\n", dir); */ - if (sysconfdir) - { - while (*sysconfdir && sysconfdir[strlen (sysconfdir)-1] == '/') - sysconfdir[strlen (sysconfdir)-1] = 0; - sdir = sysconfdir; - gpgrt_annotate_leaked_object (sdir); - /* log_info ("want sysconfdir '%s'\n", sdir); */ - } - if (socketdir) - { - while (*socketdir && socketdir[strlen (socketdir)-1] == '/') - socketdir[strlen (socketdir)-1] = 0; - s2dir = socketdir; - gpgrt_annotate_leaked_object (s2dir); - /* log_info ("want socketdir '%s'\n", s2dir); */ - } - } - - if (!okay) - { - xfree (rootdir); - xfree (sysconfdir); - xfree (socketdir); - dir = sdir = s2dir = NULL; - } - checked = 1; } + if (!gpgconf_ctl.valid) + return NULL; /* No valid entries in gpgconf.ctl */ + switch (wantdir) { - case WANTDIR_ROOT: return dir; - case WANTDIR_SYSCONF: return sdir; - case WANTDIR_SOCKET: return s2dir; + case WANTDIR_ROOT: return gpgconf_ctl.rootdir; + case WANTDIR_SYSCONF: return gpgconf_ctl.sysconfdir; + case WANTDIR_SOCKET: return gpgconf_ctl.socketdir; } return NULL; /* Not reached. */ diff --git a/doc/tools.texi b/doc/tools.texi index 26c4c5f3d..ae960bdc9 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -1151,7 +1151,8 @@ More fields may be added in future to the output. Under Windows this file is used to install GnuPG as a portable application. An empty file named @file{gpgconf.ctl} is expected in - the same directory as the tool @file{gpgconf.exe}. The root of the + the same directory as the tool @file{gpgconf.exe} or the file must + have a keyword @code{portable} with the value true. The root of the installation is then that directory; or, if @file{gpgconf.exe} has been installed directly below a directory named @file{bin}, its parent directory. You also need to make sure that the following directories From a0bfbdaaa2d91cda9c6dbf97462b6ac0a112af0e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 21 Mar 2024 17:41:10 +0100 Subject: [PATCH 399/869] Allow installation with a gpgconf.ctl changed homedir. * common/homedir.c (gpgconf_ctl): Add field "gnupg". (parse_gpgconf_ctl): Support keyword "gnupg". (my_gnupg_dirname): New. (my_fixed_default_homedir): New. (gnupg_registry_dir): New. (standard_homedir): Use my_gnupg_dirname and my_fixed_default_homedir. (default_homedir): Use gnupg_registry_dir and my_fixed_default_homedir. (_gnupg_socketdir_internal): Use my_gnupg_dirname. Increase size of prefixbuffer. (gnupg_sysconfdir): Use my_gnupg_dirname. * tools/gpgconf.c (list_dirs): Use gnupg_registry_dir. (show_other_registry_entries): Ditto. -- This will be useful to install versions of GnuPG VS-Desktop and GnuPG Desktop in addition to a standard GnuPG version. Only basic tests on Unix done; Windows testing is still outstanding. GnuPG-bug-id: 7040 --- common/homedir.c | 135 +++++++++++++++++++++++++++++++++++++++++------ common/util.h | 1 + doc/tools.texi | 7 +++ tools/gpgconf.c | 28 ++++++---- 4 files changed, 145 insertions(+), 26 deletions(-) diff --git a/common/homedir.c b/common/homedir.c index d38c94a05..deb6f3616 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -1,7 +1,7 @@ /* homedir.c - Setup the home directory. * Copyright (C) 2004, 2006, 2007, 2010 Free Software Foundation, Inc. * Copyright (C) 2013, 2016 Werner Koch - * Copyright (C) 2021 g10 Code GmbH + * Copyright (C) 2021, 2024 g10 Code GmbH * * This file is part of GnuPG. * @@ -102,6 +102,7 @@ static struct unsigned int empty:1; /* The file is empty except for comments. */ unsigned int valid:1; /* The entries in gpgconf.ctl are valid. */ unsigned int portable:1;/* Windows portable installation. */ + char *gnupg; /* The "gnupg" directory part. */ char *rootdir; /* rootdir or NULL */ char *sysconfdir; /* sysconfdir or NULL */ char *socketdir; /* socketdir or NULL */ @@ -134,6 +135,87 @@ static byte w32_bin_is_bin; static const char *w32_rootdir (void); #endif +/* Return the name of the gnupg dir. This is usually "gnupg". */ +static const char * +my_gnupg_dirname (void) +{ + if (gpgconf_ctl.valid && gpgconf_ctl.gnupg) + return gpgconf_ctl.gnupg; + return "gnupg"; +} + +/* Return the hardwired home directory which is not anymore so + * hardwired because it may now be modified using the gpgconf.ctl + * "gnupg" keyword. */ +static const char * +my_fixed_default_homedir (void) +{ + if (gpgconf_ctl.valid && gpgconf_ctl.gnupg) + { + static char *name; + char *p; + + if (!name) + { + name = xmalloc (strlen (GNUPG_DEFAULT_HOMEDIR) + + strlen (gpgconf_ctl.gnupg) + 1); + strcpy (name, GNUPG_DEFAULT_HOMEDIR); + p = strrchr (name, '/'); + if (p) + p++; + else + p = name; + if (*p == '.') + p++; /* Keep a leading dot. */ + strcpy (p, gpgconf_ctl.gnupg); + gpgrt_annotate_leaked_object (name); + } + return name; + } + return GNUPG_DEFAULT_HOMEDIR; +} + + + +/* Under Windows we need to modify the standard registry key with the + * "gnupg" keyword from a gpgconf.ctl. */ +#ifdef HAVE_W32_SYSTEM +const char * +gnupg_registry_dir (void) +{ + if (gpgconf_ctl.valid && gpgconf_ctl.gnupg) + { + static char *name; + char *p; + + if (!name) + { + name = xmalloc (strlen (GNUPG_REGISTRY_DIR) + + strlen (gpgconf_ctl.gnupg) + 1); + strcpy (name, GNUPG_REGISTRY_DIR); + p = strrchr (name, '\\'); + if (p) + p++; + else + p = name; + strcpy (p, gpgconf_ctl.gnupg); + if (!strncmp (p, "gnupg", 5)) + { + /* Registry keys are case-insensitive and we use a + * capitalized version of gnupg by default. So, if the + * new value starts with "gnupg" we apply the usual + * capitalization for this first part. */ + p[0] = 'G'; + p[3] = 'P'; + p[4] = 'G'; + } + gpgrt_annotate_leaked_object (name); + } + return name; + } + return GNUPG_REGISTRY_DIR; +} +#endif /*HAVE_W32_SYSTEM*/ /* This is a helper function to load and call a Windows function from @@ -339,7 +421,7 @@ standard_homedir (void) NULL, 0); if (path) { - dir = xstrconcat (path, "\\gnupg", NULL); + dir = xstrconcat (path, "\\", my_gnupg_dirname (), NULL); xfree (path); gpgrt_annotate_leaked_object (dir); @@ -350,12 +432,12 @@ standard_homedir (void) } else - dir = GNUPG_DEFAULT_HOMEDIR; + dir = my_fixed_default_homedir (); } } return dir; #else/*!HAVE_W32_SYSTEM*/ - return GNUPG_DEFAULT_HOMEDIR; + return my_fixed_default_homedir (); #endif /*!HAVE_W32_SYSTEM*/ } @@ -389,7 +471,7 @@ default_homedir (void) * warning if the homedir has been taken from the * registry. */ tmp = read_w32_registry_string (NULL, - GNUPG_REGISTRY_DIR, + gnupg_registry_dir (), "HomeDir"); if (tmp && !*tmp) { @@ -414,7 +496,7 @@ default_homedir (void) #endif /*HAVE_W32_SYSTEM*/ if (!dir || !*dir) - dir = GNUPG_DEFAULT_HOMEDIR; + dir = my_fixed_default_homedir (); else { char *p; @@ -470,6 +552,7 @@ parse_gpgconf_ctl (const char *fname) const char *name; int anyitem = 0; int ignoreall = 0; + char *gnupgval = NULL; char *rootdir = NULL; char *sysconfdir = NULL; char *socketdir = NULL; @@ -500,6 +583,7 @@ parse_gpgconf_ctl (const char *fname) { static const char *names[] = { + "gnupg", "rootdir", "sysconfdir", "socketdir", @@ -555,6 +639,11 @@ parse_gpgconf_ctl (const char *fname) ignoreall = 1; /* No, this file shall be ignored. */ xfree (p); } + else if (!strcmp (name, "gnupg")) + { + xfree (gnupgval); + gnupgval = p; + } else if (!strcmp (name, "sysconfdir")) { xfree (sysconfdir); @@ -589,6 +678,13 @@ parse_gpgconf_ctl (const char *fname) if (ignoreall) ; /* Forced error. Note that .found is still set. */ + else if (gnupgval && (!*gnupgval || strpbrk (gnupgval, "/\\"))) + { + /* We don't allow a slash or backslash in the value because our + * code assumes this is a single directory name. */ + log_info ("invalid %s '%s' specified in gpgconf.ctl\n", + "gnupg", gnupgval); + } else if (rootdir && (!*rootdir || *rootdir != '/')) { log_info ("invalid %s '%s' specified in gpgconf.ctl\n", @@ -606,6 +702,12 @@ parse_gpgconf_ctl (const char *fname) } else { + if (gnupgval) + { + gpgconf_ctl.gnupg = gnupgval; + gpgrt_annotate_leaked_object (gpgconf_ctl.gnupg); + /* log_info ("want gnupg '%s'\n", dir); */ + } if (rootdir) { while (*rootdir && rootdir[strlen (rootdir)-1] == '/') @@ -637,9 +739,11 @@ parse_gpgconf_ctl (const char *fname) if (!gpgconf_ctl.valid) { /* Error reading some entries - clear them all. */ + xfree (gnupgval); xfree (rootdir); xfree (sysconfdir); xfree (socketdir); + gpgconf_ctl.gnupg = NULL; gpgconf_ctl.rootdir = NULL; gpgconf_ctl.sysconfdir = NULL; gpgconf_ctl.socketdir = NULL; @@ -1031,7 +1135,7 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info) if (w32_portable_app) { - name = xstrconcat (w32_rootdir (), DIRSEP_S, "gnupg", NULL); + name = xstrconcat (w32_rootdir (), DIRSEP_S, my_gnupg_dirname (), NULL); } else { @@ -1042,7 +1146,7 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info) NULL, 0); if (path) { - name = xstrconcat (path, "\\gnupg", NULL); + name = xstrconcat (path, "\\", my_gnupg_dirname (), NULL); xfree (path); if (gnupg_access (name, F_OK)) gnupg_mkdir (name, "-rwx"); @@ -1150,10 +1254,11 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info) }; int i; struct stat sb; - char prefixbuffer[19 + 1 + 20 + 6 + 1]; + char prefixbuffer[256]; const char *prefix; const char *s; char *name = NULL; + const char *gnupgname = my_gnupg_dirname (); *r_info = 0; @@ -1192,12 +1297,13 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info) goto leave; } - if (strlen (prefix) + 7 >= sizeof prefixbuffer) + if (strlen (prefix) + strlen (gnupgname) + 2 >= sizeof prefixbuffer) { *r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */ goto leave; } - strcat (prefixbuffer, "/gnupg"); + strcat (prefixbuffer, "/"); + strcat (prefixbuffer, gnupgname); } /* Check whether the gnupg sub directory (or the specified diretory) @@ -1352,11 +1458,8 @@ gnupg_sysconfdir (void) if (!name) { - const char *s1, *s2; - s1 = w32_commondir (); - s2 = DIRSEP_S "etc" DIRSEP_S "gnupg"; - name = xmalloc (strlen (s1) + strlen (s2) + 1); - strcpy (stpcpy (name, s1), s2); + name = xstrconcat (w32_commondir (), DIRSEP_S, "etc", DIRSEP_S, + my_gnupg_dirname (), NULL); gpgrt_annotate_leaked_object (name); } return name; diff --git a/common/util.h b/common/util.h index e2d95b1af..851b392a5 100644 --- a/common/util.h +++ b/common/util.h @@ -244,6 +244,7 @@ void gnupg_set_homedir (const char *newdir); void gnupg_maybe_make_homedir (const char *fname, int quiet); const char *gnupg_homedir (void); int gnupg_default_homedir_p (void); +const char *gnupg_registry_dir (void); const char *gnupg_daemon_rootdir (void); const char *gnupg_socketdir (void); const char *gnupg_sysconfdir (void); diff --git a/doc/tools.texi b/doc/tools.texi index ae960bdc9..9ce0e6bb8 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -1159,6 +1159,13 @@ More fields may be added in future to the output. exist and are writable: @file{ROOT/home} for the GnuPG home and @file{ROOT@value{LOCALCACHEDIR}} for internal cache files. + On both platforms the keyword @code{gnupg} can be used to change the + standard home directory. For example a value of "gnupg-vsd" will + change the default home directory on unix from @file{~/.gnupg} to + @file{~/.gnupg-vsd}. The socket directory is changed accordingly + unless the @code{socketdir} keyword has been used. On Windows the + Registry keys are modified as well. + @item /etc/gnupg/gpgconf.conf @cindex gpgconf.conf diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 22569a870..a24c60f92 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -315,7 +315,7 @@ list_dirs (estream_t fp, char **names, int special) #ifdef HAVE_W32_SYSTEM tmp = read_w32_registry_string (NULL, - GNUPG_REGISTRY_DIR, + gnupg_registry_dir (), "HomeDir"); if (tmp) { @@ -324,14 +324,14 @@ list_dirs (estream_t fp, char **names, int special) xfree (tmp); if ((tmp = read_w32_registry_string ("HKEY_CURRENT_USER", - GNUPG_REGISTRY_DIR, + gnupg_registry_dir (), "HomeDir"))) { xfree (tmp); hkcu = 1; } if ((tmp = read_w32_registry_string ("HKEY_LOCAL_MACHINE", - GNUPG_REGISTRY_DIR, + gnupg_registry_dir (), "HomeDir"))) { xfree (tmp); @@ -344,15 +344,15 @@ list_dirs (estream_t fp, char **names, int special) "### Note: homedir taken from registry key %s%s\\%s:%s\n" "\n", hkcu?"HKCU":"", hklm?"HKLM":"", - GNUPG_REGISTRY_DIR, "HomeDir"); + gnupg_registry_dir (), "HomeDir"); else log_info ("Warning: homedir taken from registry key (%s:%s) in%s%s\n", - GNUPG_REGISTRY_DIR, "HomeDir", + gnupg_registry_dir (), "HomeDir", hkcu?" HKCU":"", hklm?" HKLM":""); } else if ((tmp = read_w32_registry_string (NULL, - GNUPG_REGISTRY_DIR, + gnupg_registry_dir (), NULL))) { xfree (tmp); @@ -360,10 +360,10 @@ list_dirs (estream_t fp, char **names, int special) if (special) es_fprintf (fp, "\n" "### Note: registry %s without value in HKCU or HKLM\n" - "\n", GNUPG_REGISTRY_DIR); + "\n", gnupg_registry_dir ()); else log_info ("Warning: registry key (%s) without value in HKCU or HKLM\n", - GNUPG_REGISTRY_DIR); + gnupg_registry_dir ()); } #else /*!HAVE_W32_SYSTEM*/ @@ -1456,13 +1456,14 @@ show_other_registry_entries (estream_t outfp) static struct { int group; const char *name; + unsigned int prependregkey:1; } names[] = { { 1, "HKLM\\Software\\Gpg4win:Install Directory" }, { 1, "HKLM\\Software\\Gpg4win:Desktop-Version" }, { 1, "HKLM\\Software\\Gpg4win:VS-Desktop-Version" }, - { 1, "\\" GNUPG_REGISTRY_DIR ":HomeDir" }, - { 1, "\\" GNUPG_REGISTRY_DIR ":DefaultLogFile" }, + { 1, ":HomeDir", 1 }, + { 1, ":DefaultLogFile", 1 }, { 2, "\\Software\\Microsoft\\Office\\Outlook\\Addins\\GNU.GpgOL" ":LoadBehavior" }, { 2, "HKCU\\Software\\Microsoft\\Office\\16.0\\Outlook\\Options\\Mail:" @@ -1508,6 +1509,13 @@ show_other_registry_entries (estream_t outfp) names[idx].name, NULL); name = namebuf; } + else if (names[idx].prependregkey) + { + xfree (namebuf); + namebuf = xstrconcat ("\\", gnupg_registry_dir (), + names[idx].name, NULL); + name = namebuf; + } value = read_w32_reg_string (name, &from_hklm); if (!value) From cec1fde1bc7e9ab4fcfeba84b3c75a3aa51d2136 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 26 Mar 2024 14:57:52 +0100 Subject: [PATCH 400/869] scd: Add new OpenPGP vendor -- --- scd/app-openpgp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 1f5d64e6a..45f90a5b0 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -310,6 +310,7 @@ get_manufacturer (unsigned int no) case 0x000D: return "Dangerous Things"; case 0x000E: return "Excelsecu"; case 0x000F: return "Nitrokey"; + case 0x0010: return "NeoPGP"; case 0x002A: return "Magrathea"; case 0x0042: return "GnuPG e.V."; From f9919bcc48831fcb7aa01cd6ce9d8028a6485e99 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 26 Mar 2024 15:46:56 +0100 Subject: [PATCH 401/869] gpg,gpgsm: New option --disable-fd-translation. * common/sysutils.c (no_translate_sys2libc_fd) [W32]: New global. (disable_translate_sys2libc_fd): New. (translate_sys2libc_fd): Make static and cobuild only for Windows. (translate_sys2libc_fd_int): Use no_translate_sys2libc_fd flag. * g10/gpg.c, sm/gpgsm.c (oDisableFdTranslation): New const. (opts): Add option "disable-fd-translation". (main): Set option. -- GnuPG-bug-id: 7060 --- common/sysutils.c | 24 +++++++++++++++++------- common/sysutils.h | 3 ++- doc/gpg.texi | 6 ++++++ doc/gpgsm.texi | 12 ++++++++++++ g10/gpg.c | 8 +++++++- sm/gpgsm.c | 6 ++++++ 6 files changed, 50 insertions(+), 9 deletions(-) diff --git a/common/sysutils.c b/common/sysutils.c index 6c7d616b9..780af58bd 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -113,6 +113,8 @@ static int allow_special_filenames; #ifdef HAVE_W32_SYSTEM /* State of gnupg_inhibit_set_foregound_window. */ static int inhibit_set_foregound_window; +/* Disable the use of _open_osfhandle. */ +static int no_translate_sys2libc_fd; #endif @@ -351,6 +353,16 @@ enable_special_filenames (void) } +/* Disable the use use of _open_osfhandle on Windows. */ +void +disable_translate_sys2libc_fd (void) +{ +#ifdef HAVE_W32_SYSTEM + no_translate_sys2libc_fd = 1; +#endif +} + + /* Return a string which is used as a kind of process ID. */ const byte * get_session_marker (size_t *rlen) @@ -537,10 +549,10 @@ gnupg_usleep (unsigned int usecs) different from the libc file descriptors (like open). This function translates system file handles to libc file handles. FOR_WRITE gives the direction of the handle. */ -int +#if defined(HAVE_W32_SYSTEM) +static int translate_sys2libc_fd (gnupg_fd_t fd, int for_write) { -#if defined(HAVE_W32_SYSTEM) int x; if (fd == GNUPG_INVALID_FD) @@ -552,11 +564,9 @@ translate_sys2libc_fd (gnupg_fd_t fd, int for_write) if (x == -1) log_error ("failed to translate osfhandle %p\n", (void *) fd); return x; -#else /*!HAVE_W32_SYSTEM */ - (void)for_write; - return fd; -#endif } +#endif /*!HAVE_W32_SYSTEM */ + /* This is the same as translate_sys2libc_fd but takes an integer which is assumed to be such an system handle. */ @@ -564,7 +574,7 @@ int translate_sys2libc_fd_int (int fd, int for_write) { #ifdef HAVE_W32_SYSTEM - if (fd <= 2) + if (fd <= 2 || no_translate_sys2libc_fd) return fd; /* Do not do this for stdin, stdout, and stderr. */ return translate_sys2libc_fd ((void*)(intptr_t)fd, for_write); diff --git a/common/sysutils.h b/common/sysutils.h index dac2d9244..9a90d1018 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -75,12 +75,13 @@ void trap_unaligned (void); int disable_core_dumps (void); int enable_core_dumps (void); void enable_special_filenames (void); +void disable_translate_sys2libc_fd (void); + const unsigned char *get_session_marker (size_t *rlen); unsigned int get_uint_nonce (void); /*int check_permissions (const char *path,int extension,int checkonly);*/ void gnupg_sleep (unsigned int seconds); void gnupg_usleep (unsigned int usecs); -int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); int translate_sys2libc_fd_int (int fd, int for_write); gpg_error_t gnupg_parse_fdstr (const char *fdstr, es_syshd_t *r_syshd); int check_special_filename (const char *fname, int for_write, int notranslate); diff --git a/doc/gpg.texi b/doc/gpg.texi index e3a6109c9..2ddc16342 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -3856,6 +3856,12 @@ 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 --disable-fd-translation +@opindex disable-fd-translation +This option changes the behaviour for all following options to expect +libc file descriptors instead of HANDLE values on the command line. +The option has an effect only on Windows. + @item --no-expensive-trust-checks @opindex no-expensive-trust-checks Experimental use only. diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 71cfa1e8a..1316318a6 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -770,6 +770,18 @@ list of flag names and are OR-ed together. The special flag "none" clears the list and allows one to start over with an empty list. To get a list of available flags the sole word "help" can be used. +@item --enable-special-filenames +@opindex enable-special-filenames +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 --disable-fd-translation +@opindex disable-fd-translation +This option changes the behaviour for all following options to expect +libc file descriptors instead of HANDLE values on the command line. +The option has an effect only on Windows. + @item --debug-level @var{level} @opindex debug-level Select the debug level for investigating problems. @var{level} may be diff --git a/g10/gpg.c b/g10/gpg.c index 658b7c7c8..2afcd91ad 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -354,6 +354,7 @@ enum cmd_and_opt_values oAllowSecretKeyImport, oAllowOldCipherAlgos, oEnableSpecialFilenames, + oDisableFdTranslation, oNoLiteral, oSetFilesize, oHonorHttpProxy, @@ -880,7 +881,6 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oAllowOldCipherAlgos, "allow-old-cipher-algos", "@"), ARGPARSE_s_s (oWeakDigest, "weak-digest","@"), ARGPARSE_s_s (oVerifyOptions, "verify-options", "@"), - ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"), ARGPARSE_s_n (oNoRandomSeedFile, "no-random-seed-file", "@"), ARGPARSE_s_n (oNoSigCache, "no-sig-cache", "@"), ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"), @@ -912,6 +912,8 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"), ARGPARSE_s_s (oPinentryMode, "pinentry-mode", "@"), ARGPARSE_s_n (oForceSignKey, "force-sign-key", "@"), + ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"), + ARGPARSE_s_n (oDisableFdTranslation, "disable-fd-translation", "@"), ARGPARSE_header (NULL, N_("Other options")), @@ -3563,6 +3565,10 @@ main (int argc, char **argv) enable_special_filenames (); break; + case oDisableFdTranslation: + disable_translate_sys2libc_fd (); + break; + case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break; case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break; case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break; diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 7c866d0b8..b1a5f09b5 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -117,6 +117,7 @@ enum cmd_and_opt_values { oLogTime, oEnableSpecialFilenames, + oDisableFdTranslation, oAgentProgram, oDisplay, @@ -428,6 +429,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oAnswerNo, "no", N_("assume no on most questions")), ARGPARSE_s_i (oStatusFD, "status-fd", N_("|FD|write status info to this FD")), ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"), + ARGPARSE_s_n (oDisableFdTranslation, "disable-fd-translation", "@"), ARGPARSE_s_i (oPassphraseFD, "passphrase-fd", "@"), ARGPARSE_s_s (oPinentryMode, "pinentry-mode", "@"), @@ -1461,6 +1463,10 @@ main ( int argc, char **argv) enable_special_filenames (); break; + case oDisableFdTranslation: + disable_translate_sys2libc_fd (); + break; + case oValidationModel: parse_validation_model (pargs.r.ret_str); break; case oKeyServer: From 984a0c6982cc7beb42300f18b53301c67c6ec49c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 27 Mar 2024 10:25:13 +0900 Subject: [PATCH 402/869] scd:openpgp: Fix data_objects specification for F9 and FA. * scd/app-openpgp.c (data_objects): These are constructed objects. -- GnuPG-bug-id: 7058 Signed-off-by: NIIBE Yutaka --- scd/app-openpgp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 45f90a5b0..26ac91ea2 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -119,8 +119,8 @@ static struct { { 0x00D6, 0, 0x6E, 1, 0, 0, 0, 0, "UIF for Signature"}, { 0x00D7, 0, 0x6E, 1, 0, 0, 0, 0, "UIF for Decryption"}, { 0x00D8, 0, 0x6E, 1, 0, 0, 0, 0, "UIF for Authentication"}, - { 0x00F9, 0, 0, 1, 0, 0, 0, 0, "KDF data object"}, - { 0x00FA, 0, 0, 1, 0, 0, 0, 2, "Algorithm Information"}, + { 0x00F9, 1, 0, 1, 0, 0, 0, 0, "KDF data object"}, + { 0x00FA, 1, 0, 1, 0, 0, 0, 2, "Algorithm Information"}, { 0 } }; From 571a768ac62c8be8597748d27faf54167476c2e5 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 27 Mar 2024 12:12:52 +0100 Subject: [PATCH 403/869] gpgsm: Allow to add extensions at the --gen-key prompt. * sm/certreqgen-ui.c (gpgsm_gencertreq_tty): Add a prompt for extensions. -- An example for an extension would be extKeyUsage for authentication: 2.5.29.37 n 301406082B0601050507030206082B06010505070301 --- sm/certreqgen-ui.c | 5 +++++ sm/certreqgen.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c index 6ea481529..267c4f4b5 100644 --- a/sm/certreqgen-ui.c +++ b/sm/certreqgen-ui.c @@ -388,6 +388,11 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) tty_printf (_(" (optional; end with an empty line):\n")); ask_mb_lines (&mb_uri, "Name-URI: "); + /* Extensions */ + tty_printf (_("Enter extensions")); + tty_printf (_(" (optional; end with an empty line):\n")); + ask_mb_lines (&mb_uri, "Extension: "); + /* Want a self-signed certificate? */ selfsigned = tty_get_answer_is_yes diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 75343385d..435333298 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -49,6 +49,11 @@ Signing-Key: 68A638998DFABAC510EA645CE34F9686B2EDF7EA %commit + Commnn extensions: + ExtKeyUsage: clientAuth (suggested) serverAuth (suggested) + -> 2.5.29.37 n 301406082B0601050507030206082B06010505070301 + + */ From 1fa24e2841dda0b9f7661909077955b0eb96e560 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 29 Mar 2024 15:26:42 +0900 Subject: [PATCH 404/869] common: Add KMAC. * common/Makefile.am (common_sources): Add kmac.c. * common/kmac.c: New. * common/util.h (compute_kmac256): New. -- Signed-off-by: NIIBE Yutaka --- common/Makefile.am | 4 +- common/kmac.c | 132 +++++++++++++++++++++++++++++++++++++++++++++ common/util.h | 6 +++ 3 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 common/kmac.c diff --git a/common/Makefile.am b/common/Makefile.am index d27603f96..e4dcf8ad6 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -97,8 +97,8 @@ common_sources = \ openpgp-fpr.c \ comopt.c comopt.h \ compliance.c compliance.h \ - pkscreening.c pkscreening.h - + pkscreening.c pkscreening.h \ + kmac.c if HAVE_W32_SYSTEM common_sources += w32-reg.c w32-cmdline.c diff --git a/common/kmac.c b/common/kmac.c new file mode 100644 index 000000000..8e9a87204 --- /dev/null +++ b/common/kmac.c @@ -0,0 +1,132 @@ +/* kmac.c - Keccak based MAC + * Copyright (C) 2024 g10 Code GmbH. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute and/or modify this + * part of GnuPG under the terms of either + * + * - the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * or + * + * - the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * or both in parallel, as here. + * + * 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 copies of the GNU General Public License + * and the GNU Lesser General Public License along with this program; + * if not, see . + */ + +#include +#include +#include +#include +#include +#include "mischelp.h" + +#define KECCAK512_BLOCKSIZE 136 +gpg_error_t +compute_kmac256 (void *digest, size_t digestlen, + const void *key, size_t keylen, + const void *custom, size_t customlen, + gcry_buffer_t *data_iov, int data_iovlen) +{ + gpg_error_t err; + gcry_buffer_t iov[20]; + const unsigned char headPAD[2] = { 1, KECCAK512_BLOCKSIZE }; + unsigned char headK[3]; + const unsigned char pad[KECCAK512_BLOCKSIZE] = { 0 }; + unsigned char right_encode_L[3]; + unsigned int len; + int iovcnt; + + if (data_iovlen >= DIM(iov) - 6) + return gpg_error (GPG_ERR_TOO_LARGE); + + /* Check the validity conditions of NIST SP 800-185 */ + if (keylen >= 255 || customlen >= 255 || digestlen >= 255) + return gpg_error (GPG_ERR_TOO_LARGE); + + iovcnt = 0; + iov[iovcnt].data = "KMAC"; + iov[iovcnt].off = 0; + iov[iovcnt].len = 4; + iovcnt++; + + iov[iovcnt].data = (void *)custom; + iov[iovcnt].off = 0; + iov[iovcnt].len = customlen; + iovcnt++; + + iov[iovcnt].data = (void *)headPAD; + iov[iovcnt].off = 0; + iov[iovcnt].len = sizeof (headPAD); + iovcnt++; + + if (keylen < 32) + { + headK[0] = 1; + headK[1] = (keylen*8)&0xff; + iov[iovcnt].data = headK; + iov[iovcnt].off = 0; + iov[iovcnt].len = 2; + } + else + { + headK[0] = 2; + headK[1] = (keylen*8)>>8; + headK[2] = (keylen*8)&0xff; + iov[iovcnt].data = headK; + iov[iovcnt].off = 0; + iov[iovcnt].len = 3; + } + iovcnt++; + + iov[iovcnt].data = (void *)key; + iov[iovcnt].off = 0; + iov[iovcnt].len = keylen; + iovcnt++; + + len = iov[2].len + iov[3].len + iov[4].len; + len %= KECCAK512_BLOCKSIZE; + + iov[iovcnt].data = (unsigned char *)pad; + iov[iovcnt].off = 0; + iov[iovcnt].len = sizeof (pad) - len; + iovcnt++; + + memcpy (&iov[iovcnt], data_iov, data_iovlen * sizeof (gcry_buffer_t)); + iovcnt += data_iovlen; + + if (digestlen < 32) + { + right_encode_L[0] = (digestlen * 8) & 0xff; + right_encode_L[1] = 1; + } + else + { + right_encode_L[0] = (digestlen * 8) >> 8; + right_encode_L[1] = (digestlen * 8) & 0xff; + right_encode_L[2] = 2; + } + + iov[iovcnt].data = right_encode_L; + iov[iovcnt].off = 0; + iov[iovcnt].len = 3; + iovcnt++; + + err = gcry_md_hash_buffers_ext (GCRY_MD_CSHAKE256, 0, + digest, digestlen, iov, iovcnt); + return err; +} diff --git a/common/util.h b/common/util.h index 851b392a5..7948b5d82 100644 --- a/common/util.h +++ b/common/util.h @@ -299,6 +299,12 @@ char *gnupg_get_help_string (const char *key, int only_current_locale); /*-- localename.c --*/ const char *gnupg_messages_locale_name (void); +/*-- kmac.c --*/ +gpg_error_t compute_kmac256 (void *digest, size_t digestlen, + const void *key, size_t keylen, + const void *custom, size_t customlen, + gcry_buffer_t *data_iov, int data_iovlen); + /*-- miscellaneous.c --*/ /* This function is called at startup to tell libgcrypt to use our own From c69363e8c7b6bb11163c2820e6007f227b5ebb84 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 1 Apr 2024 14:38:51 +0900 Subject: [PATCH 405/869] agent: Add --another option for hybrid crypto. * agent/agent.h (struct server_control_s): Add have_keygrip1. * agent/command.c (reset_notify): Clear have_keygrip1 field. (cmd_havekey): Add --another option handling. -- Signed-off-by: NIIBE Yutaka --- agent/agent.h | 5 ++++- agent/command.c | 16 +++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 9a7b59db3..b3d3c0407 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -288,8 +288,11 @@ struct server_control_s unsigned int raw_value: 1; unsigned int is_pss: 1; /* DATA holds PSS formated data. */ } digest; + unsigned int have_keygrip: 1; + unsigned int have_keygrip1: 1; unsigned char keygrip[20]; - int have_keygrip; + unsigned char keygrip1[20]; /* Another keygrip for hybrid crypto. */ + /* A flag to enable a hack to send the PKAUTH command instead of the PKSIGN command to the scdaemon. */ diff --git a/agent/command.c b/agent/command.c index 575456cc5..5e74381ed 100644 --- a/agent/command.c +++ b/agent/command.c @@ -241,7 +241,7 @@ reset_notify (assuan_context_t ctx, char *line) (void) line; memset (ctrl->keygrip, 0, 20); - ctrl->have_keygrip = 0; + ctrl->have_keygrip = ctrl->have_keygrip1 = 0; ctrl->digest.valuelen = 0; xfree (ctrl->digest.data); ctrl->digest.data = NULL; @@ -796,8 +796,8 @@ cmd_havekey (assuan_context_t ctx, char *line) static const char hlp_sigkey[] = - "SIGKEY \n" - "SETKEY \n" + "SIGKEY [--another] \n" + "SETKEY [--another] \n" "\n" "Set the key used for a sign or decrypt operation."; static gpg_error_t @@ -805,11 +805,17 @@ cmd_sigkey (assuan_context_t ctx, char *line) { int rc; ctrl_t ctrl = assuan_get_pointer (ctx); + int opt_another; - rc = parse_keygrip (ctx, line, ctrl->keygrip); + opt_another = has_option (line, "--another"); + line = skip_options (line); + rc = parse_keygrip (ctx, line, opt_another? ctrl->keygrip1 : ctrl->keygrip); if (rc) return rc; - ctrl->have_keygrip = 1; + if (opt_another) + ctrl->have_keygrip1 = 1; + else + ctrl->have_keygrip = 1; return 0; } From fa33b18940453108440048345738456253b69b84 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 3 Apr 2024 09:43:25 +0200 Subject: [PATCH 406/869] common: Allow building with libgcrypt 1.10 for now. * common/kmac.c (compute_kmac256): Return an error for older gcrypt versions. -- Except for the new KEM module there is no hard requirement for libgcrypt 1.11 *yet*. --- common/kmac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/kmac.c b/common/kmac.c index 8e9a87204..69e18a2c3 100644 --- a/common/kmac.c +++ b/common/kmac.c @@ -42,6 +42,7 @@ compute_kmac256 (void *digest, size_t digestlen, const void *custom, size_t customlen, gcry_buffer_t *data_iov, int data_iovlen) { +#if GCRYPT_VERSION_NUMBER >= 0x010b00 gpg_error_t err; gcry_buffer_t iov[20]; const unsigned char headPAD[2] = { 1, KECCAK512_BLOCKSIZE }; @@ -129,4 +130,7 @@ compute_kmac256 (void *digest, size_t digestlen, err = gcry_md_hash_buffers_ext (GCRY_MD_CSHAKE256, 0, digest, digestlen, iov, iovcnt); return err; +#else + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +#endif } From 4b981e415fb921fa617658ac77bf819cb5a9f5e5 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 3 Apr 2024 09:51:57 +0200 Subject: [PATCH 407/869] tests: Add a sample PDF with a signature -- --- tests/cms/samplemsgs/pdf-signature-sample.pdf | Bin 0 -> 58529 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/cms/samplemsgs/pdf-signature-sample.pdf diff --git a/tests/cms/samplemsgs/pdf-signature-sample.pdf b/tests/cms/samplemsgs/pdf-signature-sample.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0ed04b57745f398187ac5fb8b79417894dde73ad GIT binary patch literal 58529 zcmeFZbzGEP*ET#f(j8KRGzc@p(B0i2qJZQO(jC$*A)TVMgo309lG4%$QlcP@AV^3E z%r~IdeP8$EJnzl*d%r(l;K$6sdCr{sIM-h5IM!NwvuMdFa6@?baacyiyQXmXfncDM z`F$KQF&vN@%+cE22FNb}0si{J0V&wpyTe?8AO(9fcbFW^!pRbbBO!s~=I#nJbHMSQ zDN0dydk-dx*ghv0sUU=WC@x~+xJDF__R8vLZJ&sQMZjfq++`-kWZ3bAdqjIS6~l|F zAJhJa6YmzqeEF9jxuhz=(ED%4;y$q);w|vGQ42dxnroNW?Maed{hlgQAHThKhp(?7 zGOC7*VJNIp*@_Q3#ws>AWll3US8V_AF*J>p1S;`Frasm#(Nbo<(Y$`tgHPfiIJWqq zDjgfKOc}Fo2=zc&*rxozBJu4Tp_3C8ZFNhmp%kq}Lv89c2l%CLUoi2ImKzbCwE;4( zQPuAm7 zDAcFA76}NbP&H~Vv#pmcA-u(gt7Dj8)JG?VaiXgIO>jImkUsx5m6aUMdn#Q%GOx`U zOnzJzep*dsK0g+eg2%}mfrX>~X&&I84!UMCnT)%%8-ZVEKP3olM>3P;9eSy+a_Km6 zpW^Hv%6d?l_YxP}Y3WPLNp`u!7vi6AisjZuP_*#x20c{E`y z{iTWt>XJ6~(l;w31bMSWdsUlfih6b!C$VYqXREDSFG88p2m8rRxVc> zCiO6)s0*b&KQsR{MqWu!4gKc^hHsMhBGfx ziK&+PvbXL9F|_Y#M7wGmCw|6vK%YH-!{tzHcV_xh%)IUc0E}`+c9E6Owuf7D@xzlN zk)7Enle~>RMX?BlGKK>@_8r>ZaE&~IY}qXtYb{Kxz&vW^V9f+~bK0r5ov|g?qlEN` ziD~XUFnKWE|D4mc0nnoRir8+LdN#Vqx*HUDayXbQE2=GwFQ*XOkhdA!>q(lK=WVewJm<$MM8GdMKl4>9`c-x*ww+Ed_XGlPxk2H;D3x?~egSii-; zbmms=GtZHLnYntl#a7uCOK)!?m18+iz$AZ@=MjTf;dtFLQNE|b-fbf+Os!MED>69Xh3}loy#V)K9YVtvuTT;rG z2Rc7B#gXR1B}T6!(<8fy+E=iwy^GDkoo49eb%Uz1?qn(xcJ8N3(es#8qhY=PKb<38 zSkh`=Mcy&=#~qcGh0Is@r8GRQI+OxxWerP*_3>;vv(KSJN?S()i~EnV=+H{oI;CuW z7@*i$_{KP@Mc{z3pHbvtN*KzKYT3R}1df(q0ms&SUpEEIR@P&?o5ImV$mC22wqh+^ zORQesZM&}^ZgCX;`X^~K+JK}f4|iOpy&-6!Cyr8-w%1%Tp-2;>6x)Yb{O}%y!b=`1 zIZM#p2Z?wuPe*VSmKD&A<{V>jsLla$~VUYLCsoVl<^D` z>(D5VAj;ngs~g8k3ahIo>a>e1tYLjirDCCV{p{V^M7Q#y%3V8aZp?59b&BN8xP^>~ z9NGr2jBPu|h4a8RQ z$Dvs(oEbXTUB!6P!xCbaoJk7Ws;-e+@VzYv<6?)oYCnT5I7cv}wMZ8Qfd)8t>>nP^ zE~1Ow8Pr16bm7w81gch5E-t8FQE0t(sFXKxkqgs;rpW}?EYc2;wjyIDKE_03v3r~m8n)%Ux+l8l;-P-h_RL{=Zv_;IhAnX zFy!hC3_jp#dOxs~S7){*#4GREFpg$0tV>X!f=}=mf zLbk)V*QjTbw2ktyXi&uAGPYKw)jagWkA50LbAg&^vVeQZMi_hBru8+>?N-*&1 za*^ZYQ>~lQX>i2`*&&5Ule~;{vDXGQ+pi72ad@z)n2;1XRpmUa8rE@sI>0!@f^MMM z|9DSh1)FE!eWPEj+atGhm<*2h#231A00V10^iOPg!GB^4fnGfZLZOpT!CRLG1^u@{ zLH{r)>i=p`aJVE84u=!EXDz@{FforA@bC`s@$gO=BEb0jqk;DOT8ESb*RMOh{*u~1 zk<68V3ov>4iWA9*AV@|87P$Hp5g3C)^}$*I3$%Yt5GE*)Vc>7`gDTSn$^5`;*f%E2 z$0x@#ZxAykJBPyq0TI-2NmJ7jC#p26B|*zp*9Ko#3|ADu&brxCBv+1vg+c_celO-m zAP7D}hCY%=7W{b$H3W{@IK7!Pg<+0fPgGltt$)8bH^01Z^aneAJ8$@F$I7Z5bb*%{ z!5j+3Oy$B>T^(U{OMDCEg`}kek&xn(_x1#OR3u#b)DJV`l{17*h9>DAnnTQ#^Osay zn^<*uZ>-LMh(rL*lMG2-<8eLHCg_^4yLFjtsuZWbMC}Aa@N+s7O{g?&aca%7BF;Oh6xcvMsaF~c$EAL__unfnK)ej!c3(wTBBf+Z>iqmyIg zqpC1VX|Y9_i)yq zm4IjC;cpZ_jb|IbfmpB3Oj7lN5(%o}^-)D7G<|aPI`XjmootBhfBVvY>(Q#X4dt5pK8X6p@SmIZ)xi zLa_7=^AYv-#7m`dC!vHj@dx*vw!)*#M@ab_fg>ina{5^sSA3=1^&Q-Pv#O} zdMN*(dV}Uar(;|9=*IgzKm9#&IO-0th!F|0$T%)P@0DkR|5*EdR0smuYq&gkA-A1G zHAgn@8XUgLrD%+ld9Vw_h~XAb9UJ?E^Nr?6_`gcsaaHnUegI1IBJ$J8w;2 zm6iB`e@CTutP#Qq!cgQ0I((8?YTe9PP_Fn~T-N@4eZ4Ijlb+j9e|Riw;;?M#NcJVk zqnx`q=^2ZHY5C$&Gh8k~*f*tdn}a@#c-hodNq7>^h)24Qk0<85!<1+;UNy{+aoBv>M2!~9pDpT?tA7i<`TB?s#JCE{vL zQ8%SKk zyoF%*)5qx)k|VD^3RcBYMlyZ#eX$+qP}Q=+@!>4)_~bO8%h&6Ht#_j!;pr0b&t}FG z3}><^Ob;XUo|Vozte|W2WK#@jb~b=d;~g)Oj$TM~&6m*VywQH)cb~e`TxHN2QlK|a zNFi)M+oiE=3W+Lu*Z$?^3MUrG)wztO(^0Lw$sl6foMca!pNV))^B`aMO={}hvaWa8 zabNqyETwOL5%E@n(0sZr5OiDo(}JYBY_u;DB#}|ye~|F0OR922@VW>>h+HE}d|NX> zNLpR%nUYkIRmr#p9=UFRFCZj!X>^y}2fZ7QeSJ|UH1r*)46MYy_%hxdLp%8Dd8m12-~4jO z`W5#0i>B(i3HjQg?hWeOinniXr#^pkMz~Ygrg@5y@1K!_1XN^XS@0ilL+CiPO79mp zg#Ih^=`#Jn4X+UU(Au#uF^LWsROkR>SX7(A`G`=yDcMH0C<*S`VUU@SEyV=G0s)yx zfk86GiBj32Pqoi$#01-&J--_2;&_%&{LLb=+KSArorzmwKcf2 zeQQteJa`sYa{?-c&z2N>-90o}r9A=L{3O*1wC~5^ZU~$x@Q>18OUat-b4|yrO{-Ld z_A%SPrwtLD%F8_3u9SD%m1r-Zj(VB&fIwl-XpY*^=34~D-U525qOh)hXb5?oy8wNT zN^Q&g43iL-x$E3`LZa3mX!tZe@8R_qaDCsJDLY91 zRk%nP;!zNLcKT_kO!(lq^~X+4U#mb}sla(P_pthAY0;yJ1!EZ7WA?4nn~E&@eW~Wb z;CNGfO>ao~$e*Yo0Qw^-&ifBI5p1~mBHCc>1S(Zks?R(hXbDQK5OV|+bp`RaX_1R6r%%5z{ zw(g!5X?9PHoeiu9i+ucj9*j?~Yz!=k%w`$VyB9w$55~#JdzOcqSe{SxQ^0fWF8`Na zHZ+nP)OV9oo0`GB+W^|N41v@96SLs~*0sk0ra!eS)wVGD3YUVyY~D%}W5~&U)R04) z9ATGs+`wR2UMmtOCz&n@Gl=>@TD?m6=GxDkA%9}aT*6(>_=mKg$wXVErwL;${SK9| zCJQ3fkCnKJV|SA!oc8O^(Q!V9*&#s|nL^;dx}JnWC!oBye`y{jA{EFI=MrxnV7L7S z@ZpjX51S^>nKOniE{{K9E_-@Q@k<$HZClRt7Tutl5XSVD7@69<5b2xg#W5jgfnd|N zTn6x|WE*xNHPr@9kR@G4no|kN`%`>!)2!w^fEv_d&mMTchnN9T%)ca!D&A)F*5Jca61b z`W`xCoGF2f_<>fK%&dj9e7m6^A0pS8U_p>{kaHI#{A1JXI4#iA+N@`|!m7y1w>&-k zM8`jG*63d6DjxLU{pWX9pj%9ir4p20!v;osxlS*)MO`M$E7a_azYitz)kP4sj6?+7 z#Qp-P%>lG%24oMMi%%NvW$p%6(fa^&lDU>8^80e=R@>i@iYz3)wpL&oS_v@+I1c;} zVzs04uo}CAOJh}891NzFz7K1#Tha~ylv8*pBY_8r^nmh0t_+XI*sy8`n5^wPB_>yx z*-O!eLqeOt+yYUI74!#0`%BVc!O?7H(INHS@SBx^g@P{+^z-;ynl$pZe6jtMNRL?8 zZ%AlpKsu@7&5h)Q;=eN{fq0c|csq}k_m(2tbwA~?jPo|58rQd6i>sZ6+lOq3nB?~21DJl6m&0X~qa_J)b6EL}=4Rb}={axu*uY8eIz#o znPT}@G3LM5VvI+mFK!6d4kapA*w{UBymU>|_vAHCZVp_#%=TbM`;uj^HJsTTv!7v$ zf73egQ~uPpwR4o{{*&!^cA{%Tho-r(N`JN}05qX79sQvjbQW2!S!b*Fy~Lp?+HmHU zyjyW#OQ57)RYU8CBFrdz0?`wUJ%0+d?i6v{ceZq7Hd92JSo@fB-~H6qx}n)56&Ajj~#?RX&?baLz^7J1P_!mW4OKqSu29!Ui4d+>X%$pIk* z@Hd~E-|Vneh;gj43SxXwS=1PmZP(niOzYR?`BvZbVyYtUaZPh)ih~F2-cu8XX`YwE z>g}E|$M3t3o~K@8B+|w{2PN%b-25R_EA@eB0w=yyreb-JEb|&GZx@z3^IBy#qlNUN zLP-NpVjAYe3WWs@;)FKbjfgRN?xJeduS&tyww-dp9~SAKq}kb3NKNyY7f9JXm%0O; zA3QAi%p`I0gdzvc>ND|N&`t9uN%YRoeKKq37$$mt9jzEF?j}f}L?&*aSC`!3BULJB z(q!QaHHFw8Ssg^SNrm1(xD3&;e&un9q_z6n6v#G{6lWE`6F;j>h;;8Stik7j-^m=QT{;zJ_o#p!# zBd7N^Qcp7Uj~3~77$in0re4vn+~NI3Aw@BI2cG8ftB+tK{s8- zx;g}m+1;k*6dj!TDP{dkPyn`)+x2XKwpPu$%b;r@KK52DfA)(7wY>M{cPa;>G(uoa znO#K3&s$St?m8~fJhl&0LxLL;{lW{mda~bPs5Sa6B2evsZc=4@`GFDkgmPr?-OM%I za}-@#8;>rR)Vp`tXR^eC(ZTu6|t33zEGZr zHXUm*JvwYvQ*5ho66&DfOWj?#=OuxVgk$d~V)5671FsLYu;)NiutxZUO6Y)$T>FV1 zw20^{)V?{BXWiz}f=S&73eq;c%6^36N#yQI#OC3yMV4I{@7bcI^`LZeI=zFEim|(J!Y%8nXO2qd?{t!=Hh3R8cfQ#Qkk1$WR;8Ff3>CN0Fw22p zoJE7|6#AnAt3N(0)lH$d$MB9RN8h1eCoFkRZA##bJ^&C=D7J6bEAoV$zS7S;H9ZyH zEA`!;pf1yE_-^icPkp7PFHlDxuSACpHCCjd!39++G=X&=K#=K8hQy4JsEvP8GkOw# zkwqnvhm(N8>W&Em816MzG48=7mj%lz9aUU;QHbyiJ&R&xEs@6uQ!~50Xvx6y)2j8h zrEJ%3|BgFDA9g;B1oLv4zw?|@7kI$QHKsarbG@{;@HutPqgA?fR|#`j-vO?U^{g_8 zY%@UaB?Y@P7Ee^(H*DgM2|#;ozC_tMM%xzlCS#(4v;%_M@vDI)fsB35@=OVK?^p=l z31VO8*f0IC$6_%bZ1izs#l$%%37n-@n=7~>Br)(OAbiM##6K~aA@K`9FfP(oXi20| zZYXn|FY?3DPf>KS@7{?*%qqFsWGbg;f}=Dx=`u#vUR5d_Q+{0oJ1cb|3edu!8)cEq zqT`Qj=***acEP!?Y9CKf{Ja(|to+b?z=EtV?8lo9O!+{OT%xW73fkIEOC`WO8D2@! z(@}mAxR$NB2h8p`SzM-ml)ktLc#AOViRjno(63EC;RWc{M<@j&zLH1~LLvxw!GHCC{CCRX zG1PidW<+=%clM8_CQ@t7LC>nFMeghn{<{}I{XRW+{1+x6Pol53+Rk8F$=9l{{RGyt zVi6T?3!%ZO>z}A*bnnA5D!2FrztZ93jNxivx7wF``-MxkV+~7ZD<>BeXEQr7wsQ zQU`=(MGFnhze5WSXP|ZaU2{QuZ1NJx@Q~1d-hYsZOid8Ks62$5EWI7$laTR4>5WHS zuBg39!jX`hFQq4?j1oey)mX5kz|J<0CyWZiu^Xg`G{88ti}Ut{7SV(*G;r z%#7EQ?dyS)y#+hQdlHTTj~p2+CsaM;gY~Rms7~bkTrEz2P^wSK_Vj06tJV9seLKQ? zG;N(XP6gTl|;QAXt`qf0Z4z$Q@?R-Ig?imAiyXld|;fbGp^LqP%Iu^;n}D$%}f ztD#wVV?QSjw3u4VEiC3`IZ(Du&t#u^#^TBu6lEkVpF7F7h-G6`Pju4ea( z%!9`tpG##iwwvK~kmWLqg#p|D;OIKLX{w$V8%= zlj34PEq>VysqX*GL}nl>D*md%1$TG4`ZThG&rJa#a4Kfe3`@-9Soa&5@F1mgIKI?a z1RRiX+IAWg{CyQ=g%B^cl_uyNRbVI?^xWF?sH5$O@Zo8w+&PsIGju8uQOGNS!_hLA zTo0CTmQVpY#>zzJnwQ$>^t%8^bu6>;MaH_Xi@f58yi&j&!ML%1q^WNz*CD;t@hKl zM`r+dU_$-xz5-8S`BNmL{J$ie%|pL4BPp~LD+ss0DJCrlVf=0hL}W%V5Vf(V;|00- zx040G-||ZllX*m(Zf|`q#l1Bber9TA9mqPE?lVA~)2|L4A_<6HPaTunP*U~x_I_5) z`k>!d=EvPe%dh;ct^Q((+)nzm$>m2H=HE&yyamu*PZKdCoPV?mw1_(|)JkrfKIZ}Z z;DF|FH^+Aj`ISV2t#?QSHsYPSK7*d@yLs@POlHzw(-I`1OHw?#7Sm@-%1-`vI!U+Liy#?&wW{vRvzh^QN8U_)%t29YpgOSEl zqmu<31x%w8dMRxle@&C{r2H{G9{*y1HHIvY|KIJJ0S|5#b%uquM~KQWL7}VHmFGq-`-d>+aj9|Y_wkpWwiUigk|(;40mT*(j!G60VaL&! zLF7;OiAA2(@;xJq{6f>~vg6Vd*ipJJ^hjx}vp$+5(LH)6T1Dr!a;wli@C3VOA#-$U zPX35p<7awnvUMwI;^^2P=L0An3In^C2DtO~YrAdK@po(#q!+Yzzx1hKb9VHH+?n?n z;zX0sLVLbTFvRBOeZXcKgqchCHYEO(p@ji`^<909+vF)~`t|xFlt5_0`#+IDOx{1T z$q@d3;GO=%C6l84U%BM-jWh;LW6qY zczA(SRB*<`z=U3g&=^Zh(OpD$$N@YMm~2$>)F{{pzyNc`MKV$(WDX*9_3Uok1^+k2 z3pa5gs@}&Q#Ms~dtiNWNr(YSGn;a@sS`eE5*e3o%!9F&fC>eiT=!h~Z!%}!tlU%Y( zn?$5oH7y419SH*wU8PWCaLf&}6SI44!_)-gDjNH*dfA$?a6OsC@ z&Nl`sfWvcB!wpJ{!t+gGuC=r*ib@TP?H&R+A$K1Ra-By`x1zO96808Lc!Uy{GIHd+ zLZR2<(D1(=`*gx8UOU89StT#q^$~C8=(_i(yx0{B9Ifu!FS>SW<|H!{0EGwLzUxb- zWp6p!OQCtv&ND%;QH-Sd0Je5ETs!nDAknVKqKUIU&}8%>rO(5;_dIHbPM*-n{2|&; zCd-Z}GIk&f*>A_KMdb5=B5@NLyXx7@uiHeQkoi#{!3P=p61;UFPVVjNX`qu8MMdN;buW2mNbM8Uqr-1B&q zLDZX`nbs{QCn}QI z2BepeFOy=5i3I(SN8kUEdK9nb9uxp)b$E1p7WU?kv8^CKqMdDf$``ts6>0^AwEOaQ- z6Hc#?z=e$0@%@7evjBqP=w9+VgckVAi6Hu{i1>n){?&X)MdSQmo2xP;cNmV~?dKhE zLWY1-xc3p^&z=>@ft<&1aDerB#}R%Qbs+fMLdo>Bqb(>Ta0C;IHi&4*!uppQNPeSk zh-83BI2h{1rAbtO>)|NDUunO|IV(z0FJ3DaUiiql$eo@w8+&G^p8kTuMZHDM``ecSRA zAFD3N=dcyd3N;*@PP()6W_dGo17mURmCH`jYinu?X3ePOptTjs1kcLmU9TrNK~Kx* zy|0Dvxhu)U3x#3!%)1jgjF)&s-CFWMY9z_*zf{H8zxzIm zheGH!5~0M8loDP&K@9!t-s_C;>wyKd!2G(u2q7;P4r;>+QRcr&XH0Gvr8DsVsdR=K zijIb+Zyy}Nm3xGR4n>7PiE7ZQ5PSgZTo%Hl_b6H@7@-F{b^uX?K`wNQD3}jc5c<(G zckw(JfBrX%_tI4tKw<$%I3Yyf>ODTtzvATOFsrn{5UpRsgka!YXV0LLvHTbFRa3iQ zzHk2r^OZtW2>C{Ge^Gfv4`d+KIoz~Fk!AXV!JC<$x3?WdqU2j8B*aoNk37L6B3ZKs z_Z`Lu=S4`bNTP+(g<_0I?&329G5>^PNhK{vYN4b*XS)rg1O&R?N1|E~WzRo(!9VD* zHXi()9J+&wi8=Z~rq@VH5E9d_vV*0@Xai%Ek>bW6$H4uSFjKN6jw;A_fyfO#*m;W6 z7_7*1P_me~kt~_}B$7=}B9f=nsYZOBU9REAazVCBEN}MvWxu%sTJG+pyzG&zNC7I1 z682i-!qyq#DAX5hZD))4=nv2nTQLMU{Q+xZROq7Ui76rvF;Zu&9yjXS7JFEHuquCX zi{ohpWYw@GHkQyKR+50U01Ym{>2m!GiOI7zxjG~UfP^ysqs2ADRVp1?h^~A|biC~4 z3X0Bb%8>`}?{{`dm78L=YY^NZyX-no_@U8wq;-hm2k7}qgWhO~9ar2gP?Q4ob0(lY zmlXfFO<%RZv(1wI1Hb2={X$n7ndF^5Koa|@&00CTW?js*L=#I(U&K6yu zo_nq@%YlySnKwLNUD2`UAo^pnd!NU!->I;F(rlBMv%F*fgG|2y$9{ht0sQo=FmqHA zHFVz$6dSXUwK%MIT7XJ3Mv4w2ag&Fv6g0`B?AsY~WMQgsdK1 zfnP0aC6Ir*zL7=orlll!n0T_9!Jt0?xKRgn38OnWPtkhj%^~i&uL75D*Ihz_7ZTda z3%$C|G9JDVqhuH(qUd;HDs!HU`)5HK=K1Q{n;APR?MGSbgvPZk>fqHy|3JM>~y}T6)j##e?{Ul|Q>=CA2`i z#*Vo!6lwC)mleXS&GQdP52TJmezxHJoDsCo^F_zklA@L@H!RT)b3t?eK&Q3!L^>6# zzfFh-ZBxABQTD+I)rZi~_QT$3ON9wJbFTb3A+OZEei5!G7N=fo!aHJBkHnZXOW(b~ zxZi73x-tGzXQGdjEbn#Q_vusz2UF{ZwF9>5l7rG(iAdl>!gL|RSBH-uk>p17xkfBF zDKo0ol!w1|LrvztahLlD&GEvI>EE}_vuQ@8{bBK@wv64>fzeIiYlO+cUzeFYKc+86 zZua=~uB(0O-*g|3JbTE>GL8R0)045@vY*8SRL?ZscmJL6G_{kPrzod&b{AELAbwc_ z3VCB2E*-PxL!W&7y*BLfH_Q(63H~~&(ZJH3IL?xg-#^Mv(6y6r;7!c=Nx*mL+N@E$ zWwB*x-&8zqm)YUSF%$1Do7mhN%lah5qga3h79<20!h3ZA424WU5jm+!fVl-C5%)VQ z#q>v3>dt@7N?}GIvbO_L0|cGBQbveXBWG}w2sls-4(K5CDLK;WK41tsKZc`4H2hi! z;ue1kiJTWe!asTWu09%%ger{=DZB_eSd=B>E^6u!2#{_kGrm=*!^{gDeTV`T_vxHyiw{OyATAvRs6JU0n-1;u-~Clnc&8crp}b}4#JXBoix5v(ZL;nMo91I zh{Pt4kX(q+)meP%Fd``;g%`AtCKIV8;*}&8>@~spgtqM0qAK7V5C;PY9pBbq0lSAJ- zlzFl(tBDWCG!u$vxPM&u-X59D6h?JJ35bPDUOOUmIz!xKb_*LKmmozz!D*A{a#Y9U z-9gRRNhFObY*3OLzPkPMya#@yIp(mQ;KO0(gR+JXLsF3w3gOf(1O^mhNZP%H8Va%+r++Z@TyKOODuA80tf^0v}+ z9I_i;k0=wS0Y*3^w0W+XMJ~7&-3l3F58@C-IbzcWG0WmZ0)@n$60x$)|TH&pv!D$+h>`l~(pxPUb}&dL3Gr2poI1KNnOJQC|cLXdg+t`3?9f*)Nr!Allmt1YwyRU#H+Es=z#2JfL?mJ@*` zMY;J7)$y<5tK$=PqvuanT`4Fg{cxfE1E&Ym>ngbA2bM)1rRt@iB0r^xN&_2R?kB5) zcf685+f6713|24A#Rd2Ww5qhUG>_}-#z~~y6;r9#Zo>q);1+(z0vEvgU?KC{me1LvLdOVs$L_C9}Du%j*VJ1BKq9GDY1Z>m`p5= zHRv5+jNQ4JIV{%ejQy#a$a6~k!>mu@ch!s!gVSv(;#9t1z){QBz0KyqAZI!k67&^orH^?jk~s@j-wq#d`Y}Ra??VhL!JoV zeN?TelqnM>nuxAr@Ve{vz&FX7MJ%RtdmNj!q;1``vC(!e-$c$CvXjq`JE#}Qx+0pe zyJS+e3sn*MNj9?Y_Z0}D!(I_gi>i@UOFxOq1ivpU`(*s?wrqQEj4$gUpxG!7hR5#S zi-PxT*g$Qr{%IRyLK_Dw+9TBB>#-EiVIKp&P3!Pt2(IUQjM`aZ?NNrdLVWOz9fJ1A zCXZ0ub_|@6AcKs83tqir(KzA4#K`2Gl!!Clo(63;F^n)j&bU9_)_A$n;&(_adhS4lfg0|Ua|MyH~+)tjW2#24SKGxQpyq<6INxKORKFQ>5bWePw!1UyEWaM zQunUnj{cnoObpvOAkNv3_f+z#%f-l&B+ERxqSyd4gi_nw;4Y>cG1scvulE7s$o$wk zD*;@^VRwS@0}bH$!Z#p;ZB`B(?;m0MzC~T9=PC?XOYmMK`U#5Zja>KyRahjvgJ&In zb0%JDl})bV^LzaVB05iWZ1}<>f_?kZoPj}bQ{0dnS<<04_ZBLP z2vmzBGD&0T@|`IoYI_XBpO-$@pDT5WOmngR6J*4?vOk^QKUf&#F#@>&8NtsBv74-T zfGfsQ$@bs)?(nR%kNJ&VAr|*2P>y z4PTPUZ(~eiNRsW#z{(#BPcEM?oj?45534u&kYcDrcoeS^WLGXzCBo=z>Eu#kYlws=ZoGSgGR=}o3>`+j6XXjl*iKKUC{ z7BPb?%T^$GRsd5zvwxM^HdPJ{%MKjUQkj9cxaOWnAmhT_lR3m6zaF< z;^}IT(l}Clk~`jQ<5rlXa!{t0cP!8ou=-uzfiv~9t!~L_^u6azjUTq17=}4Ne>7Ut zSvK_7d`PcXHz9R9gf7Ukj2J}+^*QEPAl4E$*hEtAT1i!xA{1 zM0#F|If{h9O*E;xQ6%9ziiDzOM+yX@rC*|`m{f*0|9}kFb)CKL>&HYqbX*mG2&bSf z`x|CaT^pG4wAz8h7pD{1qxh10MOK96w&3@LGuNk;zh@2=_YLfmzd+fcF2<3~=G%8U z$&Y`e)VM~XSV7$o5`{k))$mDaYgb&pMHUKDG`cGSm-rq zS%@BLzNW2wlQ(7I#d!VALef2xPxMuW_nst9kRPdqMBB70(4BXKJZ~RuP0;&?QzpR%37U6ZB8S#2=N2NU7D_UBMa~Yq_Jh zd}<$%(J#b?;)VHo5mQpqx8)5^3c$xL`BF%e$TC%At}E6Oeh+i8x3X1yFhvL9(t5%1 zNPA$ALcS`u|JYY5k-L~Izt@&D>7#ifY2oz{Oh86m=~%l(1+Cx845QXz_X4IZ?tE1R zqbbdUH3IS@9=IMu(>nqHn!dp2yff+dXa@`?l|F-Qd=pqgT+ZQ6xL=Ntbi^Pc(Vw0Z zdi6|bT_OSp#NstODkaAS;wH+GkScHzkd-%MZOQav+mHgNSXTU7CNMA6&^=XZH7XWH z6SuPm&F6tHR+K{+d0Z&Wnxu+$NZRShC}s7k=7c{3xuoc|Sb&0!c-2#1_P#fU40v+I zO09Uug2kj03y4U4anE%&@E(?o?eN(R265i^`N{O`COgdnY5#rh(gE9Z9|yY^rR55C zXdU|KegX~-gp;aJ{!MR=*J}pX$JqO-Pbho7(XF_<9iIA6?tFXN^1Yba&$UIE0n5ag zP%!4Dn+50nQ-s349yBpt?r$oLNb)rq6=2m~SCh%iPNiYoaqT2MqO z0khF@GNDC8%tpY(XjE+!77Xl}%Y{J1M$aleGwxt<2|pJMYp?|yP}!+?s{etC}l2Jf6P zg))awh^N1XE6GueDl9SWVpCR*F9wCrpb-a9w4Ilf2nPOOBk0pc>rJTz+!Iw(z01YN z?{Z&?hr)8h{bP@3@-buK>z*67SX(2V1N$%=5`qsY`|bB z*ML=L2a-0WkBQ!IU|BC)SgB%opHVb^wNY$sPtCiFWJV$(N|1k0-iGpz|EkAaCaWRZ zV8P!xc?kMNvih;?-;&jcwi+bK>dOYLr@tDsBCcZ+wP~KWYw(&U3@9;+lJpU>F1Hto zXS~2lhD$R;GnNp&S#Ze+xR6rGiL}P9pq9!zw2oDVkQ8{2DHbz4^rADTZORlLxP!&s zdmaeD_zcI&1)O~b;K-W-|7utfSx-hn84-j2_negWaJO-CWxow`bwunMrs`y2!vWH> zb+?DHbAWU`%*Oeh*q{u^E+>K@ z@=!1@uMk*>pC1b40z=rqU^c{Y>Q0vb?GQazGiPU*C1STTGkZ4}4oFK+-hfBJ!`|N9 z%<*D8?0Pn~Za~D(uj{!9)Q7pcAwC)iMO-k1Uzk^bpPQFQ;IHdM91k-9s@ZzNfV^Oc zFvt?-36g`E+nPCY0PUR3+-=-oWx$&20g~8{uqsUkezwk@qLK2FDNb#+c6pWJH*TGQ?R$hOWmkYp%s(PiKo2x9Ws~e<5 z$kG1gbLp2k(K4QrlcLtmQjwz62#86E$k%QzUpRe_yvOlp3)P9$0|!Grwlh!r`b8=I zqv#D)(S6M~Up<3LT^5_>+`lfKbCut>7m8?(YvcrcMqyjQp1tYwa{FZ~yuIh~Scjg; zBy0=KA?Mrn%a*SDOwZlQ^fo_t&!l|Zar*%EBj_W~c99)CUEf^l4#&KG;4^7rQp;5C zj8SZ@XZ*@U@g3^3H^dNmkMH~2RO!{FF&l>mvNT=lzC)9X70C}czIx*xv25J`BJ}7` zK{4Wyo_giP9h#yobG+ktcroIWS1Im$Jw`Qsn*cS0Q&uFs*-Bx!mW!JgjgJjKkyH>nTYY2E-lZaknsVz& z8|LThPef#Ui)gg#XaCXI6)eCXIwC1~Vpkx*_x4Qw>(leKEzk+c8HfEi(3A zf`Z(<%K2t6`#J%N^joR30Uv7xEw69R-~HNT(QvmX56lA;JcO zV(aU~t7`eF%o}QUofi4T-z7$)+7fIcX_aaf$%gsDoRbI{vzKJC*^Y_cDogx+$rL8k zr|9~enZdSPXw(L6{mr~u>b|cg=eqngedU*mkClCkCYYPY9Fy+Z3M+$V;xv3mUERlM zm^(<{n>fQ?1l?&C+Aad3oMeJKOh7LL6fCk-ug449~iKYz`k0_0YbT>zbA7tb+JtNAYlbmVK zHt__n=euFy9>fq(9Ko<~kC|@A$*22|CI&27Kjv*pTl9FSB!zz{@!jPipc`+vIWM9| zB_^%zWrtgyEJ?xC@?dGM`mMOak}b{6mKR&Nl$O3Vy=YF9-`D4ENHm+EKP8N5+Z+6< zm1sQ=+-_s@86=-@nzPFIYT+ZOmfp>e_G!Y4FauA3Os$$bKoCnsMh^VaMfNv!%2Q<=%>2j8KgGnY4=aZ zS%Rqgt*!RRtu24Sk8~6h#XX)s-Nx09=T0PjYYL_Q48KBuCxX8`qk#_03J0X@XbJNM z8iIjBLdG~CU0Yum;u#L;Hqa0Pr3Hi_3POCs!V|x#bsA&A*vxCR*wGDr1|Jx;SVtk_l>Bs7Gxp@pJ zJkm^DHtx7_MOrI>IKvN}Tv_|Mr9xQ}?>@IVp|X}_5~j?_)@a&%!ykm_h1<6j_lBuW zy=FDfziXuMeESrQpqyLj&%5vDZszLl?TWbHyby?xFb)fgyru#Uj_|*k$OYMOM+8ie zf|IMm?@dhqzK1F3!e&4Qh-ivnBp`J&cUN14)m+p8!NAMk#+PSaS{4MP19NloaJ7KB ziHTis5({0JJJ1k>*hduz(t~-s13}6TX4Wv7-;c7tAC-+IBtSAUPTmM>M7%3vI|v9E zZ2XsH2nb0?{I!c}HljoKHW(ly>!yn#i-s1SuNTe-oHTCN$}?)08YYXyA5;%2EMiFj zyrbkILxly8d^BhuLuDqZNGK*M0RU8hgnNI2gjl!v7ccvNXy72a5dR+<4uA1V;eQj$ z|7ROGm%-rI9>^dq#6(6Y1sLd-8%)!~-QLy_<_6MqhB-=GxL+{+3+JE%(lB#?xd9Og zn2Q&eu0+<%-OS#}8l-0CXw5F~Xl-xnhLAqe7OqYg9thz#6l`JkmTrbZ7rIdgh-mY< ze7FolK;esMreh3}lV%4g!R$Q|uk@@CzpQ~AAUU0jlbsyh5f69GCwid-ZLMq(TFk@E*3lYhd+BF+5z0^yXzl}q=s^wi5c=>x_1Qm_XGZ_4 zJ~R413N+CFLFN7%c;SC%`Ty4d^h?eC6%zQs{J#|)KOaKi{XIaGCz{y31(S8PzVmkn zH7lP80%e}NC0A+JR+_FzjFv4LhI^sVgE+V`mrsHo%@;7Grzux`}$_l!D z$xL~Te^FNiSAbm1VaNqV=Qro&<>xhr3R(&X!@zvzd_qu|g(bf^ z;x)e+KTJYQSQsX33FC+GnF*Mi@$*|+nwvvm5I(SgCE{F5Fhs)m@9g(4vl9^b#gidm z2!h?fJb{;_>Tm4C!qoH#p7W3~IyerZ6BQf`*%eQ~{@L9IAh9rw9SW+PqGmDx-c;xw zp(LUpwdm!>j-i&T48qpOOz;616yiVp6RE!uIH-`Y&~F0wcR&0e9`?d1|K-{K)7@Up zUH|{=hX3Yz|L&51yW#(g0GDO}LDZHn{q$e)_c99nHWURb;0439a5sd4c?5t0{JcDT zh^ z&;kno3RRcUN!roT$sMG}uEonE?I>-6IMLC}-NO|IHjy#m0O=#n`*rYNtogRBr8Nw} zi&YWtDkFQzUlGhzMiF7Ei0=ztD=Q6z{LR;0oc?<}m!I`t0^Q|BT?_|dkM0+FJ1`=8 zxxyR~xvXCof`oBjk#MWSEN#vHBHaRr-Q@*^c@Y=<7xKSG`v0}}-tky}|Nr=9lt`hh z?6R}2JtSV&L=sVykz|GJbt$7XWEY_%ima?`A(E8_+1ay%tVCDl?_BD&-k;a!efzB6 zUte84hv#{obw7{Ca*r5m4l2I0_0*p@e@-5w@8k29DlL5rO%cG6IIe(<9MS2ViA2J1FdP<+!{P|wE;0(FPXy^>f0md?Mvy?>^!S^3gH&Nqa3d%&8j3)n zKo}Zi1fI|#Q3x1}h=77({2qdb5@84=5)Hb>7$gRPMxe1kUZE&(1x*AS0Zl=Zz~|dA z5D0^VDd0fyevgX)aq++3i9&$85%eM;2`F$xqmVd|BaD6y>=zih1*ssAFz^Kcy%YdJ z7#+dQ@}XfMB{T}$gF(VcNE{l8BxB%kGKc}n3}V0#AZr8?fdO&ho99p%8O-KN`gsn* zp$OdOT`&X|oMTb=U!fqc&3ou~{P9EK5ulv^4keKC&o=yt9}?h=MAESU`23~)H$#D# zfYv}^z<)TJOy7h0fi?nJ{sk#0@%Q*}B0%JCcSAvWpx8g|MuC{1Q9v1Szf!^crKRao z^7pm}HvwryAb}V|kvJ5Tj6;*KSP~gQK@bTzG!BPE0fEMm32=Zv9*2Vwa6n|pFc=gTpaM6cG)wf>Q8!929{j<46cJi~z$U@gyRgLO`G>SQwg&hay4qkq{^{ zl!V5Spg0fO_M*v-c;enKG9zkosC_ifkBY|OjB#eFq4O9k+hvCsE@HqgS zK!oB5ATKO}J}`qrk`Yim4n{`f5ELu{1zO^FNdZSPNC8b3M=~5o!C{eD7?Fe}V$f(3 z4Ahqh2Z1mY28sfCl8|702S5qpY_Ag#t9m;4FVzbGf)Gdp}*1rjf4bh z2AT_O^wcq+EKn?gOaup@|3JeqU_*frESzpd00V#@utrcA3=PAfu|Q9ept4BO;kr>b#7*HA{J*U6r2kH;Uq7jsT z$q$Kv(ajeyC@_#K$Q_OQH@O3ef>Zu(AyAZ`76L{2(?Wo2n-&5^p<4(P1+j@72E?YL z@ed^f&*gxy{dbU{V?jp);0wg|U+M~w01%+)VRU(*Ya);_a6(4X@u$nszh0xa9^H!m z^**5U^dFoILj&l3l@8$lv!#H{U@-p~R-oN*Xbi9(FwnMiJ3;_wp#DIHC}h~9(0HRs(|SLLxE>{P$ZC6I1Jc! zES3Od5lYAPU%3t7O}DH6Kk*t}&VFh7rez?)2!EGaFvlMl?gK4B1nq3> zAh2`|K@m|D390vr**%4if26~MJ5I0i)ksn9tQ z`->ZaCP9Ha^gF-&$vxmYxcZZc=$Zl)=HGA_@CJYs{K>I&egP@`J2+2d6ur z6dVFcBv5c9B=8~ecnT3spyy2QRsEyw2M#^Z8oC~UBVZ+9aAAO1C`cRui^t&+2oeqn zCE=ks7;vqDf}!DL92V#=8U-XCOGE(&6Ac_J7zM}zjEuw(phN?&g~e@_14;x=1*jT~jKknD zL^1)52PPU63-n`%1SFn_0hC6;;fZ(>iVQdg_^$*U21CZ8U>Fh@JD1PqY?gc^tnPy--5L{MuYnG6Rp=vIXQJcG?6 zev@5+Gy|-FNAmvy8~hjh%>Smx4*KOVBHg>E`+5I55&*hFbkE}-LNIjSaMNP^$2fqW z>FyIS@W2VfQ&0pXkpkKbjv~@YgN#R$F?irhp|MyB5N+UZ;3z22%Rqo`79MnakZ>eu zU;+sa+7%cUG?ef!;}bYQ3~)FFO0tFTtbjtwh;0O2&7z98&fNg-31MLDGTj0o|@dOfrOxH=!dj-xJs4Or6pqEO7 z6X<0@8wgHmk$+d^Oqfh`2K5ZFRs3xO>Jwh-7tU<-jQ1hx>^ zLSPGlEd;g@*g{|nfh`2K5ZFRs3xO>Jwh-7tU<-jQ1hx>^LSPGlEd;g@*g{|nfh`2K z5ZFRs3xO>Jwh-7tU<-jQ1hx>^LSPGlEd;g@*g{|nfh`2K5ZFRs3xO>Jwh-7tU<-jQ z1hx?PFCqY@?)G-K(gV}^T7mfw!7|ifK36a!9$2OgeAfQQig-U4u>zBY+g@e4;9+~g5=^j&cXkGQJu+2B z-^zkMH6vJQ1fvMY%5F|GtOPC+og5sj!2IL%877sq|7BiX80_~oPB!oVdrp6y`0y`t zKL6vazNkM_`fId5m$Ci(r0Kt^Od_5jSy|9$O#U_HJ(!Ul4Fz?-;N+_BY;Iu%mOSya zwXo7tCxAJNZEenjIUW(HKW3fYoH<n@9 z=!yKV5}-%kcmd(s0SSc6F)`GADsJ z=NiDu#>>aQPe4*iT1NID5{1TKamqvznWCaGSX5k6`mF3_O>JF$!>h*Et!?cc zon0Tgdxl3w$3A`<|2#1{{}n8}y7Zm)W0_tr1_;w1ko{x5xIn!anVFfGS?Kj*VDthT z6BqNg{jlwO@W)xqUG^S;U)jM;xcw-vnpGU3H^+0%wS|pW0y!)>Pp{f$&Hif@3-}+^ z?2n55S+5=lI}-zFJSHxP8f1N4CMg*5k6UV0zgpk|cdH;|4{T~(ZG7stJ;!y=jx!}x z9dRvY7@vrrU)E(V)W=^4y%J&e)oocX>PpnQe{;r=hXfnMNVYssWbN<(RI7C?~bVi9RFz5@%RTi#;xw@alS;|{JiV%GndNm z4h8)-Gy{jHuO4F&UiQ1-b9$}VF=50(`~|Eb&G_or1M83HV%FWQ-#R$4r_ULQA1sHo z3}}?s1|1F!$*^DH%neyHc|MGD8dNjVGs1KQ4%*1GT?{T;XQKlV!M3*P2V z7az|vArj(Kbaov(b&sIXq@|H5Icw&b?0X@yt9a1k@{s(?6lK)Hk@s(8I^)HUp**rN z=&U>LMxaBC!s< z>`Z0$5*n!(nH@Qn;{4bZ0egh&9 zXjw9+QynIHf|fC&6*QuTWJ}--*nk`@DODE~*|}!WME380m40$*1A-KYsY;(jca>Ro z#p+Ec$33xA)-utSx}UDTGnptnlTe_-XD^r=mnorhk4FUQ70R~8w076u$=)nLd0Se5 z(mEe?uf}`v8;7WiRSZ=7qjPmV$lvNqlm}vyy6fz-UVrA9Q4%xuC5&Zdi6_`%m!Qu& z1p1z2NmBGC`-h5(bC+kR`!*l}75M0u1Zl-=EmWE|uIUb6el3O1zz!aDQaGn4JU7W^ zLdC4mYuag^^XlByC8bUkg%s`ev^upy|Jq%A!@aedKP2zJP!)}+Q$6S-!|pX;1f_6A z8*C$(P{r5TSVpX@=e?$tR@7E`f|`zsva9YMqzxETPx-vxfY|yRpFdoodfx0#Uqjjf z#MomcRJ`Uc(7*tK688 z#s2CZ_5uF6hL@tdyXA6N8ZGRH6&%D2CUuWqTYLG1zw^Qdgtby_qIE5K`1>k1v9_Rj zpM054?clX4b|0I^W~!Y#x7EG79(cV-4l9&6&}ic#MB9KE9uQIgfc9su6z#d3rmb@<-*GJIWd1H$|iEZ9mdSUNQqadnmK@8X}k z3hnT*np-+_zfq+(_R?>1E6U`PDpM3T0w3cAjd#jGce~)<0 zy7F-Cy>X7Jog$0EsF}cdzio4$l1H>J&VK3f4L$TBM#QpNtQI}@sHfhxKl%W3dSAEv zqtmf-$x9Jy=^nF!lLcBHDxDY4X^OSFzp_-bDGFod$LdNy*noIRl)xdgGO8vnbwbXf zI%`F0wwD~t8j`DfJZ2vZC+-+P74>myOo=>t63DnT{6f;|6!+l=>Fl4G4dFQg6xJW# z=X*z-u2uM>McYaO$Azv%!^K4FO$T4l+%`nb8 z!52}zY?2pdY!GznotG4oRP^IFV(5C>!){blH*fvn$fHTt8fM=v)fpvTTW9t;{8a^& zHnFVlfEL)EC}h7!JN@YO$Ir`f@H4&%NQ|N3o&p^gIT>#ujlA4XKe{;Esz=XTb|1zB zznkaiCU6gyYaZ$Hc%0LpJd6ESP^P*Px*!zAmN6_lJaJBLIA!0$v8EUit=Q;yv$FlN zu9>HM^~aP%RuMFZq5CNnv}dEjMB{nMB}MZ&od7X?SKXPKfdSLxBYSb%y{if;UZ$K4 zCkB5+I+zV*l!mkVF;D}vVe$T{S|gXr-)T^4bK^Uwz1h!LAGso6k^zale~;wQG-%g( zTkFz@siU`|l85ZTrR*~_)}md zMCYAK!#j@|PAP~yoO4Ffc$>G;Qud(b;Jul=dZiqSQY1rcjnIFHhil3XUEvei$ zFIjTi*N*wtJJtpH#ho~~!|VkcR+jrtP=g%XG z*D-P@=DBqr!_nuA6Q4FLRY}BHcZ)&gyTy3rb$Q?WsmlBhkLe(+Q4$0~jcIEGN z>`p7xaB!5oVbJ@mcF%Ad#Qe?7`1eR31FZy$ITJ(UKp3drsuFUPkgYSKADQ~3|9PJU zchZmCTk@C_Z(BY-D>{8FH1i-l%qXFyCDTK|sps&8{yRy7XW|l7{N9QdiH54# zDDe_KEL>bNXnXY@@YRWMMLH{_72DL*tP+oN##z9s$E&%FM3t=Ks!HGzoA571F~bbC*`e?VaRd* z2Igba{2Csg5AZhc5qE4qkbj#O9rIPw-}!Z3YZ_KJLu#UFQeiD{=5fwqfjzlskX&_d zWR}6)jeVP=)a%dn3Fg-W3+wgMw(*42;Cno9=dvbSgWbwHo%OUaZ=60KP>T+%bXMc| zbZJzr^|2>bZ2Kq+c649k_~%1&hi-R1Ja$6uEvwkj)xl7vSChZ3^anK)kHuJ$Z;x4N zjIf(NxMug{svFGJneno*cr=?1Gn3iz?BZ#EC7Q*L6F;Vw(r7IXb9;x>YB_GwFv|T2 z;mhg)$aKD@@~&0y5wx<>Rd+2ptGBUH1NJ2bxkxCB)6;4%OkYr#PxA`Ts!#=uy>chb z6glOQK{Fd(455Ac)c1+C!X+nr{n^NkX2}*6e7YHt)uN(~``X>@%BRH#Zsv&@nxL)vK?-e|DU$tsY?vL+SrVKI5HsLD<4TmGd zc9)7pwW+4%y&ikdsL@Tlta%uVo2FfTB{a&COEeSr>kutssj2E-co{3;Su|qLuPRQ> zRqyC};m1|tRBT`NpzisDhE?s4ZRY;Uz4*47y_mR^mVlN4gbj1l8Rg&lBI^Bn?CZ)( z!e`ZNbh-`ITUWj3E3x|Pd!6=8G1^x0`Y^UB#+rAm?>94&2$-!c#}wZl+9@Sa)L(0_ z_=ur6+#a_MS<9{5N#$7bp(%M5&=U1%Y4a;15g|xk+N1f1`U8Tq`|RgVr>v*<7(BS_ zuqr$(XB;AT>RT1tX9XvF2Pa$m-4DAKUKU8B;b{dm1`m1)&tzUIjx0%d9`SJ4q;g*_ zmlZ$T?K>GGE`|F~lKtQ0+VbhGB|W_F7x-}l667)U-0gVj^Jn)4M!YRcAH)&rHKi=% z%kOH6*-G5L_d&M)i^bVKk>)F_;!mivbv;VgzD4(YWu1|%iW|LXY-~POUUApbTF&@< zYUx1+xVJfcXGV^Wyem<(?3uJMz8QPG4HCm7!7jqeGVAo=eszn9orwH=$J_mJ)eb&t zsR*$HxSSLHle@#>GaDGYdmZ)5-`u+j5ei;SyIFu8>sG}GC&kM)A)}1SiX@U*a%N`M zHXw+V2<5sO@mHA!$#$+O$B@pGJ#KGe;*HPf7`qp>zF$eJ9^h(O~u~l%iCw=&#ZPxRX&d%un&4+hVYM}bc6-I@E2J<;bT9q40;fJ((7Eaj4#}u z@)R%)k}_Q~P4Xjm`@KJxfASzltlhqgx6K}veJZgU&gMJWwW#^{>amt@E14^eqoMEQ zosAzxYMKYRm7QcuViqb0wbFd&=WSQDtAZnI0`pyjo7VPFVnD1k?#BjX7**oSal)+d zZJUWier4aQX~ez&qk3NLuzMQ)W-(NcGx2WhHL7n<+C>{L@n2kT?6_ucXqYK|NcHqf z#n)?+mO1{IbFwOJ@R#N;JVwdJoKqIkUa~8w<41I&FSY9X3 z>9UU{czyc~Udt7{tlGQe_5PtpY^|E$I{!rRP2KVjlby?V-ac`;&HeSmBeypB23+-- zfal}GGtX8It?su_x+dA7;y?2825V98B}^%`BXCx{s9n*Z>u8&TrR3M8NFA{&3F5Mb zeQKHwF5Kqi8pWD(^B>BBUf$VHaS2H8`Iw=XtZ6ijv7hSl^qVpZa;->|KLIb>oAvp) zZfdlwUh+2n^o;gQWMoNQO7HZeZ(Y^7fh|5tH1Ee$*AWeor5zvJJ*MJwqoh*2ia)Iu zrrC0yPJJU|l5Sa2qNj@t4jlClt=cQUzMndBs?a{7h-&;Y&f`;}{lzSHqm=0uuXYcO zudZkBJT_R0WGEi#TEJC^HR%mx+==)P$}ypJ;zbI z(>J(McCI+~i4M2IC&}#TcXy=q@)j7HRs`qWtl#2mNNx*ECepQX*@hz(->Y`5A~H;D z&+N5AZ$P+I%x$G(HXz-hY^GFuas?!*f0FB}NV11ugw(EiIT)Pb>-R4T$*ac#mmKC| zYnr)E_0cqJ`2`}^Jo>gK&)G@e+zq{YNLv?LIsu%hL~{Nob;88OuueA5s#Kwca-Ck=%_6MQdSXEM81|s{ z!P1zxrA6LwZg-lvMEeuDoZD(w7km_i%0)wydDGqmWeRW}Q=L}y`jVm=-^6Pt=TvCX z^SQ?<%wyNy;oK|VYFpNMsBAJ99M2Y9f0$RgvNt9|=b8-MBpG^oHq{2>g;Dn%U)Ia6 ztunCPYx_bwbs{If?lIES_3mYuao>)sMai$OzP3+KcE5Bjf{_6Ud-Y_@W=t4S??Ov9 zY4>AZZ{|Diuqvx^(W{;#v=dt6@sK7mai?hZT7?{SN-A;0EVzU#UfY57Sz860BH!_O zq1d>m5yaRj(Veyzl>*(%m3E!yDm3y8yHGrrsf`*770`Se)jw#Wsqk)X?PIH{so7w^ zCaS+baXo>zHTJj53+83V#$aZ7|57y65n#!VVRWi>19_*ugWW zw=fYhkv}q`edJ^Z#<*@=mc;F9}V;+L=o33sF3j5PC@8UHy8IcBxcicO)C~0XB{1VI-efB(+c^|uL$O6!BF+hQC13)CYb zTR#BW7Sa;sIaQywZTofiSiY~JHj>D+cG2_oU(p$T_EEwdw%2mGi=4|ATsqtrSHS3T zyrr{{;q7yFT9I6Do!@6jeYtb6Jq+ij+NcS*?~_a@dqQB9ldJD@-z&KtIv*x?4AUqJ z2d5)PYkS%YIQNKM>SyX9iTMD7>u z+?q>6{#-Qb>(p`euDBl-SoRBx#-|uxBbv6o%W4sUm{_>4Qtn|J?KVb^+qbJ7c6GYdMQs{1ZinYe^Vw9`+{#dHQTWHu`(+=44g6-F@A=}FrpWLnbEP!P8pE|MIZe6v zT1-rcW}4)azS$xrk-o-##VymZ$BNH-Df>6{1;5?iZ8fG`($9t-*2I^(nFtmZAhg5_ zBgFT-J(YL6;7WTuR8)*PKoi2=DilDpyc#+!{!msHp|(D7}WLXIQPn_v1f&wOl6 zo=>cOuIVR2e53P5Dz^&1@9Cp3rPOw2@6FuDD|fes(npJT5Q4kb zo~U^I<>B+mf~frCp?k}pcVvT(<`=!1F%yLwXX?Y`G3ek2*t9cQS<%Tn-tWpir&`1t zS7Aedb!bxtf%v(~D7Q>I#A=f+}g*ZMA3o7-^qwf6O22v<3~T1UL3&{;Gz z*gbW*(xEd zCx`1dYZa}EDBqpHi1gG_a$EDYN~Y$V)qQJG?<>wItUb(8aC8?9QWKCLy3=s!v5!z; z$GIB|H3@s#8C5Pu)cV?W%sO@?DD3G@xv^$5SJkbygwMRLwAQL@a(zfQU=AMhh`JT0{lcHa?re-gmkM9yeN(}x*pG95g;e$uF=`^?tn(^0aVBu&+zsAB?0CK)+4T` z2pwiS@h~a**g;vcOx^inP08-u!@`|rl34G-?N_2YkfRl8Mz zw`YKR$1#L_IsV6ZYy_Mlk#{b6rBq^8aM&euRE(>weFGA|5@j53k^T=42q~X0xsT81 z?xU^E$JT5>AbyaqC+X+SBF=`u5{;mJa_z5qjmX7 zS^al=WMXMJ#mpMlAndAkcl7f`(FYgecF?Ylq1yr0XozZ~_+ESH=1oEh-WmSm57XKR=LP|sQHpbz_;QivZ1ZO_!n`P-)U zOF3()MJ}UNAx51IHt%yh_*dV_RihoV>feCk?*3+f*IiCnb)Q7=&YQU@*W(UlZV#DB z4D{PxI7f*Pe&V;HSFUE);q-Xtc>ll=(=jjSM2Bp|P6e)Hq*(ex$#IS|Q&{Q~jZ|I)6UuPTk-W#cf5bitd6L4E2wOSH>@e!DldR zdz~+5?S1kwskEppG$4=nkXk`nElyRG+IJ?;`-0LmIVQvUu7%6Fd|B_aEZ<$v^m0lC z9MJHJcq0*HBH9oalT@O8o49F@_QA=18wf)Gd4#Q zP2?hP@Xx+~#5+HrEpOH&AL2het*4>5KcVJi>#RgcSz%egDaUNbtg-VmXG_Ck)FdOd z=lV!P8ll@QEYD8Q;XWNdQfNO6L;jfi5G{A9#2``Y+a1#$UyNElRV@e_@AVS#qBEP{ zy3_|=W3gX)R{3e@Ng;yq*Aw~C9Y4&FUPsq*=2K%W=GBJ#$1d`8R3?ig@2X6DWYQpI ze*gH>J0{i4`JBy8`z>R2N`rLH`g_9(8Q%_CThM(YRexJB|U7mKIAgw=lBS%5e%wkGJ=s6f|ZCS(|zaFQB zj^1zlG&6rtxA2noZ({BXXqL;%RX5iqR+VX2!85u;G&P4O_H$3vUA&SfYqYDJlnxP9 za&6s^2NNZZ_nG#U%^b|vEZ;SET2=erTz;+AzkSr;gec#k4;)+XGgo&3JL}zZy zE&Mr)K@VI#oys@N5xVM^x}cR8q4Rz}^B^_R_yO`cTPtVw_z@>XsH4xr9n@*@d-*3| zVLOjh)=3BX@lQmIQw^7V7M%1IxYy<9nR~8Z+nvVNYMY6At3R#sLob@pd-@(>Mg%oF z7#>M`^4a!`)VxAhP+Ezeyq}N{su1JJYrmJ7^Z?l?-sWKNVP0<1E6n2pXYu>^h~zMn zE@7%Uw4g>->0;`B=|*8e7tNHW`>nHS@79*A>c5Q=zI{|@VpSUH%GBbzIpJ>=_z35w zwW?>}=^6Qc@y#ycaA1wBc=4R#eZIQHo6uY8!5+qjI@`{7oriw4=xcJBJkevnt?%yQSw96kZh0Or`(U;%QkQwr6u2lLfjDIZ&rZhjT# z9kI)~(!zU0RAlmVrvasTxc<%ynf&*UOFCCg;kz31r_Ok2%V}AMSXk)r85)c`+p-E~ z#+J-=#wPEZIj&M(9s@VE<8v#1lr_*88uPrv(a63x@Xk=FPC;)Zo4R9nkFPwh&W)OP zCu`edlz7VT$Evh>mOsyCF2^56evVshLyoXJN-E#=oO7R)(}6WK>IfR#&o5$Qo4IDy z`dYR!^wEfu5VflA&~)|z|83`OU|AaT+9TyRPx-&mjTGF)TzV)T@g|+}W&X6=Tndsmi7flHRO3(FC~*zvuf(3M*A$0KMrqI8c;NeV zrl7S`U+Q6JQ)kz5O*7K9ug1m!x|}5}jZ^Z3rDo4GG%5^a7gd&D6pgVt_1WB3r+eW< zu3_AVxS7S&!8#e~xyRYrWgouhvaSj~t9n)d##Bwh@Y4stQ0VTLXj_4!x)F*!{Mj$> zR<)cZ1xTIz?c7Pz;8*+BgG!2nJ7tCgWQK1@vfZXYZ$A1>_bLgA`vkj87N$IutKD%nW*RA15>Z)9^D_<-~NoTQj~ZO>9}D zAzmcL#ogS#ePH=O8F<)d{G?$-=*Dtvp) zp6aWk(>7FC72bbxjC!_wzwmAGsBc4KSHn4+j)qfwBZ!lTQzDY@9V#@FCXG;^RKf@> zS8l$Nt4P<6?ir*q9#PRd>+N^e!1^JF_}YCx$yFpRcP_RX7%u&hexWrEnk11=9% z$8YX&U&?)xK4(R~8t8sRb6Towd#E&2)q7~zu(lT!Mt&^HTe;(ut@8Ekawsf&=K0(P zq%KYZ({*r%zPK$Htg-Kzg^pqF#F{t5vf>c@mU`*x8xZPc zj(&;dZ|{6~Tl}jj!i4I1rlo`Cx9>;K&DI6Hea4Ktj(WD&bGv5{dZ|wxB~-a zJydQ_)RNcS!N%(Q)&AR@7AHmtsy6zgI)XdBBB8r$~dfb>d-Eh zmkIKqCG~b$e_B4}aG{8QbgiTKX@J{-{F?LzXni1K;La*x@rf&Kf!fAXC`c)p*QEKra8xVfm0g+B6WL_rG zKg+fx7VWA&Y)ecLJ`m%UboCfljb5lp_LWW?GHn0*z9h~xkN&<0sTW!0;r6NE`IGwlFRIlxyB|EB z_;?kanA}ri?)W9x&zqUpT#nsmnq*JgzYwlSgvScr< zN~iQ7^$l_RmGmd*mw2u|3)SQs)!;!}0Al@pS^T7m`n>(H-vjF==KP7Ek#~B-;?+MQ z2d0QE!_kc|K75yfYVKj&=BC9Els>I$C7A1B1f5tq8KwDsX2wS6Cj6Cp!nM!ljwN;; zQ}yp0WcyQRv#W+gkLB|M0ogj!@j1yy)-rk-qN#9nv=e=F6VP`o+QFf zGalA9t6To~CaH1zeNJ8@AGn72igigQR=_hNRh(0zyhBmpVaV(aYqqrSA;V^?T(Lum zH^8%P(O|zr^ES2J!_=|$#{3&y)d?a|Oyfn*0$!UM8kLru^Ro^yE{MK-=A@SF+6kJ= zT;_1sOKnD_ovWxh$16kq+c~d(G2%_!_VB@|X^4wIR^KcA%u}_)AHRL))8mN#bYWKb zglhx!*#wW1$NA-pYD)TV>*tS&z+yXwRkW>RXYJ9WX_kuy(~dC20TyYB*c(vvgU9Wcqr=g&bqaOhg^;n?e=rHq#+APUya1?lf3eBx*o#jEO9($U$cJr-3DovkAly}6TVQWjrW<}`<SXfk*+Z&u6l6kP>(>U(1Qla73YTxM37@H;`moDeU(S6I`n#a2`KPP34 z{}Z=tUZXVaR$f|OTJx(qVkE<)ymG9dV?Vm*dKShRO;mT;^J>Sz6GOwEV|%d7x8Dcg z%@o@!x6`&S>!5{IP2or5Hz3v~hacPEe%yb(^HAdVoZnayC?{5UxZCUZJgV=kNQFN~Dg#c%bL4T-WpP+&0OR*2id*8sx*I;!-{aDfm>-iA2-$zI<~qdY zy^u&{>G*sKERw}ykU8AT3L zbk2?qtQ98)6{DYlxAISTJ6kDHoE+Vi2cUwmr@cOzV z-qFqWkH0Aw%x&Dnkbk`7PEQ5)>ur9@U*D}q{Yy@#bk5mXS-2}{o4dQ(QjK9C7%H~8 z|Kk$_khZ(k-`}_gDGB#M~Q2`j3*n9}A;_=I0a;;*BosnW0FfLP$O1cHsGgAGWU{yl&m_zr;% z20erVuF(+#*T7YMk8|!nF>`hJ^UZx~d~{f~9TSY5G`k**`+nE8=OR z=>T6AN8$puN)eHon6OiU@BGJgr$cg~Jo}dtZ(fVn<-4|MK6_NBJ=y4@9N83BJOVlEMM21j9%T*Gn1?>Y-;%i8Cr=8_Bz@qV5D__qhZ1~ zp7KE8=qWg#%VMK8dG$!7m7Helu5XN-cBVf6BsORO!e7Pal%AEflAeVxzHm{#HrGYVC^J^rPmQO^zUC}P~*XPz|H%0FJ8Ui z9ArGOm+)dtjq}<3p__e=Sq_LEyxgeB`2!oz09g}dll+g6fmF<0-Knlt)@&#&42NTr KlqBm=*#1An$%u6T literal 0 HcmV?d00001 From 6c1dd3afd12b44f28d6672fd5805a34edff04631 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 3 Apr 2024 14:13:57 +0200 Subject: [PATCH 408/869] common: Extend openpgp_oid_to_curve to return an abbreviated name. * common/openpgp-oid.c (oidtable): Add column "abbr" and set them for Brainpool. (openpgp_oid_to_curve): Rename arg "canon" to "mode" and implement mode 2. -- For dual algorithms (PQC) we need shorter versions of brainpool to avoid names which otherwise might be capped when printed. --- common/openpgp-oid.c | 51 +++++++++++++++++++++++++++++++++----------- common/util.h | 2 +- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index 493054950..ceb211dd3 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -43,23 +43,30 @@ static struct { const char *oidstr; /* IETF formatted OID. */ unsigned int nbits; /* Nominal bit length of the curve. */ const char *alias; /* NULL or alternative name of the curve. */ + const char *abbr; /* NULL or abbreviated name of the curve. */ int pubkey_algo; /* Required OpenPGP algo or 0 for ECDSA/ECDH. */ } oidtable[] = { - { "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519", PUBKEY_ALGO_ECDH }, - { "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519", PUBKEY_ALGO_EDDSA }, - { "Curve25519", "1.3.101.110", 255, "cv25519", PUBKEY_ALGO_ECDH }, - { "Ed25519", "1.3.101.112", 255, "ed25519", PUBKEY_ALGO_EDDSA }, - { "X448", "1.3.101.111", 448, "cv448", PUBKEY_ALGO_ECDH }, - { "Ed448", "1.3.101.113", 456, "ed448", PUBKEY_ALGO_EDDSA }, + { "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519", NULL, + PUBKEY_ALGO_ECDH }, + { "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519", NULL, + PUBKEY_ALGO_EDDSA }, + { "Curve25519", "1.3.101.110", 255, "cv25519", NULL, + PUBKEY_ALGO_ECDH }, + { "Ed25519", "1.3.101.112", 255, "ed25519", NULL, + PUBKEY_ALGO_EDDSA }, + { "X448", "1.3.101.111", 448, "cv448", NULL, + PUBKEY_ALGO_ECDH }, + { "Ed448", "1.3.101.113", 456, "ed448", NULL, + PUBKEY_ALGO_EDDSA }, { "NIST P-256", "1.2.840.10045.3.1.7", 256, "nistp256" }, { "NIST P-384", "1.3.132.0.34", 384, "nistp384" }, { "NIST P-521", "1.3.132.0.35", 521, "nistp521" }, - { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", 256 }, - { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", 384 }, - { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 512 }, + { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", 256, NULL, "bp256" }, + { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", 384, NULL, "bp384" }, + { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 512, NULL, "bp512" }, { "secp256k1", "1.3.132.0.10", 256 }, @@ -477,10 +484,20 @@ openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo) /* Map an OpenPGP OID to the Libgcrypt curve name. Returns NULL for - * unknown curve names. Unless CANON is set we prefer an alias name - * here which is more suitable for printing. */ + * unknown curve names. MODE defines which version of the curve name + * is returned. For example: + * + * | OID | mode=0 | mode=1 | mode=2 | + * |----------------------+-----------------+-----------------+----------| + * | 1.2.840.10045.3.1.7 | nistp256 | NIST P-256 | nistp256 | + * | 1.3.36.3.3.2.8.1.1.7 | brainpoolP256r1 | brainpoolP256r1 | bp256 | + * + * Thus mode 0 returns the name as commonly used gpg, mode 1 returns + * the canonical name, and mode 2 prefers an abbreviated name over the + * commonly used name. + */ const char * -openpgp_oid_to_curve (const char *oidstr, int canon) +openpgp_oid_to_curve (const char *oidstr, int mode) { int i; @@ -489,7 +506,15 @@ openpgp_oid_to_curve (const char *oidstr, int canon) for (i=0; oidtable[i].name; i++) if (!strcmp (oidtable[i].oidstr, oidstr)) - return !canon && oidtable[i].alias? oidtable[i].alias : oidtable[i].name; + { + if (mode == 2) + { + if (oidtable[i].abbr) + return oidtable[i].abbr; + mode = 0; /* No abbreviation - fallback to mode 0. */ + } + return !mode && oidtable[i].alias? oidtable[i].alias : oidtable[i].name; + } return NULL; } diff --git a/common/util.h b/common/util.h index 7948b5d82..7b2601db1 100644 --- a/common/util.h +++ b/common/util.h @@ -229,7 +229,7 @@ int openpgp_oid_is_cv448 (gcry_mpi_t a); int openpgp_oid_is_ed448 (gcry_mpi_t a); const char *openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo); -const char *openpgp_oid_to_curve (const char *oid, int canon); +const char *openpgp_oid_to_curve (const char *oid, int mode); const char *openpgp_oid_or_name_to_curve (const char *oidname, int canon); const char *openpgp_enum_curves (int *idxp); const char *openpgp_is_curve_supported (const char *name, From 97f5159495146ce29d2011a07d493adc7c1b4086 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 3 Apr 2024 18:00:44 +0200 Subject: [PATCH 409/869] gpg: Initial support for generating Kyber subkeys. * common/openpgpdefs.h (PUBKEY_ALGO_KY768_25519): Remove. (PUBKEY_ALGO_KY1024_448): Remove. (PUBKEY_ALGO_KYBER): New. Use them everywhere instead of the removed. * g10/build-packet.c (gpg_mpi_write_nohdr): Rename to (gpg_mpi_write_opaque_nohdr): this. Change callers. (gpg_mpi_write_opaque_32): New. (do_key): Support Kyber keys using the revised format. * g10/gpg.h (MAX_EXTERN_KEYPARM_BITS): New. * g10/parse-packet.c (read_octet_string): Add arg nbytes so support reading with a length prefix. Adjust callers. (parse_key): Parse Kyber public keys. * g10/misc.c (pubkey_get_npkey): Support Kyber. (pubkey_get_nskey): Ditto. * g10/keyid.c (pubkey_string): Support dual algorithms. (do_hash_public_key): Support Kyber. (nbits_from_pk): Ditto. (keygrip_from_pk): Return the Kyber part for the ECC+Kyber dual algo. * g10/keygen.c (struct common_gen_cb_parm_s): Add genkey_result2. Note that this callback is not yet used. (ecckey_from_sexp): Add optional arg sexp2 and use it for Kyber. Change callers. (ecckey_from_sexp): Do not leak LIST in case of an error. (common_gen): Add arg keyparms2, change callers, and support Kyber. (gen_kyber): New. (get_keysize_range): Support Kyber. (fixup_keysize): Simplify and support Kyber. (do_create): Handle Kyber. (parse_key_parameter_part): Remove algo strings "ky768" and "ky1024" and add a generic "kyber" with default parameters. -- This uses a revised format which is more aligned with the usual OpenPGP structure. A lot of things are still missing. For example support for handling two keygrips and checking both of them in a -K listing. There is also only ky768_bp384 as fixed algorithm for now. No passphrase for the Kyber part of the dual algorithm is on purpose. A test was done using gpg --quick-gen-key pqc1 nistp256 and then running gpg -v --quick-add-key kyber which creates a v5 subkey on a v4 primary key. A second test using gpg --quick-gen-key pqc2 Ed448 followed by a --quick-add-key created a v5 key with a v5 subkey. GnuPG-bug-id: 6815 --- common/openpgpdefs.h | 3 +- g10/build-packet.c | 95 ++++++++++++++--- g10/ecdh.c | 4 +- g10/gpg.h | 4 + g10/keygen.c | 249 +++++++++++++++++++++++++++++++++++-------- g10/keyid.c | 91 ++++++++++++++-- g10/misc.c | 8 +- g10/packet.h | 4 +- g10/parse-packet.c | 113 +++++++++++++++----- 9 files changed, 461 insertions(+), 110 deletions(-) diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index d8672ac47..bf11d597f 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -172,8 +172,7 @@ typedef enum PUBKEY_ALGO_ELGAMAL = 20, /* Elgamal encrypt+sign (legacy). */ /* 21 reserved by OpenPGP. */ PUBKEY_ALGO_EDDSA = 22, /* EdDSA. */ - PUBKEY_ALGO_KY768_25519 = 29, /* Kyber768 + X25519 (aka ML-KEM-768) */ - PUBKEY_ALGO_KY1024_448 = 30, /* Kyber1024 + X448 (aka ML-KEM-1024) */ + PUBKEY_ALGO_KYBER = 29, /* Kyber */ PUBKEY_ALGO_DIL3_25519 = 35, /* Dilithium3 + Ed25519 (aka ML-DSA-65) */ PUBKEY_ALGO_DIL5_448 = 36, /* Dilithium5 + Ed448 (aka ML-DSA-87) */ PUBKEY_ALGO_SPHINX_SHA2 = 41, /* SPHINX+-simple-SHA2 (aka SLH-DSA-SHA2) */ diff --git a/g10/build-packet.c b/g10/build-packet.c index 9927b7695..78828c8dc 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -433,7 +433,7 @@ sos_write (iobuf_t out, gcry_mpi_t a, unsigned int *r_nwritten) * Write an opaque string to the output stream without length info. */ gpg_error_t -gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a) +gpg_mpi_write_opaque_nohdr (iobuf_t out, gcry_mpi_t a) { int rc; @@ -452,6 +452,45 @@ gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a) } +/* + * Write an opaque MPI string with a four-byte octet count to the + * output stream. If R_NWRITTEN is not NULL the number of written + * bytes is stored there. OUT may be NULL in which case only + * R_NWRITTEN is updated and error checking is done. + */ +gpg_error_t +gpg_mpi_write_opaque_32 (iobuf_t out, gcry_mpi_t a, unsigned int *r_nwritten) +{ + gpg_error_t err; + + if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + { + unsigned int nbits, nbytes; + const void *p; + + p = gcry_mpi_get_opaque (a, &nbits); + nbytes = (nbits + 7)/8; + if (out) + { + write_32 (out, nbytes); + err = p ? iobuf_write (out, p, nbytes) : 0; + } + else + err = 0; + if (r_nwritten) + *r_nwritten = 4 + (p? nbytes : 0); + } + else + { + err = gpg_error (GPG_ERR_BAD_MPI); + if (r_nwritten) + *r_nwritten = 0; + } + + return err; +} + + /* Calculate the length of a packet described by PKT. */ u32 calc_packet_length( PACKET *pkt ) @@ -639,8 +678,14 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) { if ( (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && (i == 0)) || (pk->pubkey_algo == PUBKEY_ALGO_EDDSA && (i == 0)) - || (pk->pubkey_algo == PUBKEY_ALGO_ECDH && (i == 0 || i == 2))) - err = gpg_mpi_write_nohdr (a, pk->pkey[i]); + || (pk->pubkey_algo == PUBKEY_ALGO_ECDH && (i == 0 || i == 2)) + || (pk->pubkey_algo == PUBKEY_ALGO_KYBER && (i == 0))) + err = gpg_mpi_write_opaque_nohdr (a, pk->pkey[i]); + else if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && i == 2) + { + /* Write a four-octet count prefixed Kyber public key. */ + err = gpg_mpi_write_opaque_32 (a, pk->pkey[2], NULL); + } else if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA || pk->pubkey_algo == PUBKEY_ALGO_EDDSA || pk->pubkey_algo == PUBKEY_ALGO_ECDH) @@ -779,9 +824,15 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) for (j=i; j < nskey; j++ ) { - if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA - || pk->pubkey_algo == PUBKEY_ALGO_EDDSA - || pk->pubkey_algo == PUBKEY_ALGO_ECDH) + if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && j == 4) + { + if ((err=gpg_mpi_write_opaque_32 (NULL,pk->pkey[j], &n))) + goto leave; + } + else if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_EDDSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDH + || pk->pubkey_algo == PUBKEY_ALGO_KYBER) { if ((err = sos_write (NULL, pk->pkey[j], &n))) goto leave; @@ -798,16 +849,26 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) } for ( ; i < nskey; i++ ) - if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA - || pk->pubkey_algo == PUBKEY_ALGO_EDDSA - || pk->pubkey_algo == PUBKEY_ALGO_ECDH) - { - if ((err = sos_write (a, pk->pkey[i], NULL))) - goto leave; - } - else - if ((err = gpg_mpi_write (a, pk->pkey[i], NULL))) - goto leave; + { + if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && i == 4) + { + err = gpg_mpi_write_opaque_32 (a, pk->pkey[i], NULL); + if (err) + goto leave; + } + else if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_EDDSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDH) + { + if ((err = sos_write (a, pk->pkey[i], NULL))) + goto leave; + } + else + { + if ((err = gpg_mpi_write (a, pk->pkey[i], NULL))) + goto leave; + } + } write_16 (a, ski->csum ); } @@ -922,7 +983,7 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) for (i=0; i < n && !rc ; i++ ) { if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1) - rc = gpg_mpi_write_nohdr (a, enc->data[i]); + rc = gpg_mpi_write_opaque_nohdr (a, enc->data[i]); else if (enc->pubkey_algo == PUBKEY_ALGO_ECDH) rc = sos_write (a, enc->data[i], NULL); else diff --git a/g10/ecdh.c b/g10/ecdh.c index dbce846b9..4938e419d 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -156,11 +156,11 @@ build_kdf_params (unsigned char kdf_params[256], size_t *r_size, return gpg_error_from_syserror (); /* variable-length field 1, curve name OID */ - err = gpg_mpi_write_nohdr (obuf, pkey[0]); + err = gpg_mpi_write_opaque_nohdr (obuf, pkey[0]); /* fixed-length field 2 */ iobuf_put (obuf, PUBKEY_ALGO_ECDH); /* variable-length field 3, KDF params */ - err = (err ? err : gpg_mpi_write_nohdr (obuf, pkey[2])); + err = (err ? err : gpg_mpi_write_opaque_nohdr (obuf, pkey[2])); /* fixed-length field 4 */ iobuf_write (obuf, "Anonymous Sender ", 20); /* fixed-length field 5, recipient fp (or first 20 octets of fp) */ diff --git a/g10/gpg.h b/g10/gpg.h index c51bbbb46..167cdaf28 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -41,6 +41,10 @@ /* Number of bits we accept when reading or writing MPIs. */ #define MAX_EXTERN_MPI_BITS 16384 +/* Number of bytes we accept when reading four-octet count prefixed + * key parameters. Needs to fit as a positive number into an int. */ +#define MAX_EXTERN_KEYPARM_BITS (32768*8) + /* The maximum length of a binary fingerprints. This is used to * provide a static buffer and will be increased if we need to support * longer fingerprints. Warning: At some places we have some diff --git a/g10/keygen.c b/g10/keygen.c index c98deb635..8df8294d6 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -139,6 +139,9 @@ struct common_gen_cb_parm_s * may take a copy of this so that the result can be used after we * are back from the deep key generation call stack. */ gcry_sexp_t genkey_result; + /* For a dual algorithms the result of the second algorithm + * (e.g. Kyber). */ + gcry_sexp_t genkey_result2; }; typedef struct common_gen_cb_parm_s *common_gen_cb_parm_t; @@ -1311,8 +1314,12 @@ curve_is_448 (gcry_sexp_t sexp) } +/* Extract the parameters in OpenPGP format from SEXP and put them + * into the caller provided ARRAY. SEXP2 is used to provide the + * parameters for dual algorithm (e.g. Kyber). */ static gpg_error_t -ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) +ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, + gcry_sexp_t sexp2, int algo) { gpg_error_t err; gcry_sexp_t list, l2; @@ -1364,8 +1371,46 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) goto leave; gcry_sexp_release (list); + list = NULL; - if (algo == PUBKEY_ALGO_ECDH) + if (algo == PUBKEY_ALGO_KYBER) + { + if (!sexp2) + { + err = gpg_error (GPG_ERR_MISSING_VALUE); + goto leave; + } + + list = gcry_sexp_find_token (sexp2, "public-key", 0); + if (!list) + { + err = gpg_error (GPG_ERR_INV_OBJ); + goto leave; + } + l2 = gcry_sexp_cadr (list); + gcry_sexp_release (list); + list = l2; + if (!list) + { + err = gpg_error (GPG_ERR_NO_OBJ); + goto leave; + } + + l2 = gcry_sexp_find_token (list, "p", 1); + if (!l2) + { + err = gpg_error (GPG_ERR_NO_OBJ); /* required parameter not found */ + goto leave; + } + array[2] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_OPAQUE); + gcry_sexp_release (l2); + if (!array[2]) + { + err = gpg_error (GPG_ERR_INV_OBJ); /* required parameter invalid */ + goto leave; + } + } + else if (algo == PUBKEY_ALGO_ECDH) { array[2] = pk_ecdh_default_params (nbits); if (!array[2]) @@ -1377,6 +1422,7 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) leave: xfree (curve); + gcry_sexp_release (list); if (err) { for (i=0; i < 3; i++) @@ -1515,7 +1561,7 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH ) - err = ecckey_from_sexp (pk->pkey, s_key, algo); + err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo); else err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); if (err) @@ -1543,12 +1589,13 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, } -/* Common code for the key generation function gen_xxx. The optinal +/* Common code for the key generation function gen_xxx. The optional * (COMMON_GEN_CB,COMMON_GEN_CB_PARM) can be used as communication - * object. + * object. A KEYPARMS2 forces the use of a dual key (e.g. Kyber+ECC). */ static int -common_gen (const char *keyparms, int algo, const char *algoelem, +common_gen (const char *keyparms, const char *keyparms2, + int algo, const char *algoelem, kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, const char *passphrase, char **cache_nonce_addr, char **passwd_nonce_addr, @@ -1559,6 +1606,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem, PACKET *pkt; PKT_public_key *pk; gcry_sexp_t s_key; + gcry_sexp_t s_key2 = NULL; err = agent_genkey (NULL, cache_nonce_addr, passwd_nonce_addr, keyparms, !!(keygen_flags & KEYGEN_FLAG_NO_PROTECTION), @@ -1570,14 +1618,32 @@ common_gen (const char *keyparms, int algo, const char *algoelem, return err; } + if (keyparms2) + { + err = agent_genkey (NULL, NULL, NULL, keyparms2, + 1 /* No protection */, + NULL, timestamp, + &s_key2); + if (err) + { + log_error ("agent_genkey failed for second algo: %s\n", + gpg_strerror (err) ); + gcry_sexp_release (s_key); + return err; + } + } + if (common_gen_cb && common_gen_cb_parm) { common_gen_cb_parm->genkey_result = s_key; + common_gen_cb_parm->genkey_result2 = s_key2; err = common_gen_cb (common_gen_cb_parm); common_gen_cb_parm->genkey_result = NULL; + common_gen_cb_parm->genkey_result2 = NULL; if (err) { gcry_sexp_release (s_key); + gcry_sexp_release (s_key2); return err; } } @@ -1596,10 +1662,12 @@ common_gen (const char *keyparms, int algo, const char *algoelem, pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; - if (algo == PUBKEY_ALGO_ECDSA - || algo == PUBKEY_ALGO_EDDSA - || algo == PUBKEY_ALGO_ECDH ) - err = ecckey_from_sexp (pk->pkey, s_key, algo); + if (algo == PUBKEY_ALGO_KYBER) + err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo); + else if (algo == PUBKEY_ALGO_ECDSA + || algo == PUBKEY_ALGO_EDDSA + || algo == PUBKEY_ALGO_ECDH ) + err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo); else err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); if (err) @@ -1610,6 +1678,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem, return err; } gcry_sexp_release (s_key); + gcry_sexp_release (s_key2); pkt = xtrycalloc (1, sizeof *pkt); if (!pkt) @@ -1675,7 +1744,7 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root, err = gpg_error_from_syserror (); else { - err = common_gen (keyparms, algo, "pgy", + err = common_gen (keyparms, NULL, algo, "pgy", pub_root, timestamp, expireval, is_subkey, keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr, @@ -1767,7 +1836,7 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, err = gpg_error_from_syserror (); else { - err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy", + err = common_gen (keyparms, NULL, PUBKEY_ALGO_DSA, "pqgy", pub_root, timestamp, expireval, is_subkey, keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr, @@ -1868,7 +1937,7 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root, err = gpg_error_from_syserror (); else { - err = common_gen (keyparms, algo, "", + err = common_gen (keyparms, NULL, algo, "", pub_root, timestamp, expireval, is_subkey, *keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr, @@ -1880,6 +1949,79 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root, } +/* Generate a dual ECC+Kyber key. Note that KEYGEN_FLAGS will be + * updated by this function to indicate the forced creation of a v5 + * key. */ +static gpg_error_t +gen_kyber (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, + u32 timestamp, u32 expireval, int is_subkey, + int *keygen_flags, const char *passphrase, + char **cache_nonce_addr, char **passwd_nonce_addr, + gpg_error_t (*common_gen_cb)(common_gen_cb_parm_t), + common_gen_cb_parm_t common_gen_cb_parm) +{ + gpg_error_t err; + char *keyparms1; + const char *keyparms2; + + log_assert (algo == PUBKEY_ALGO_KYBER); + + if (nbits == 768) + keyparms2 = "(genkey(kyber768))"; + else if (nbits == 1024) + keyparms2 = "(genkey(kyber1024))"; + else + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + + if (!curve || !*curve) + return gpg_error (GPG_ERR_UNKNOWN_CURVE); + + *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + + if (!strcmp (curve, "Curve25519")) + { + keyparms1 = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } + else if (!strcmp (curve, "X448")) + { + keyparms1 = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags comp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } + else /* Should we use the compressed format? Check smartcard support. */ + { + keyparms1 = xtryasprintf + ("(genkey(ecc(curve %zu:%s)(flags nocomp%s)))", + strlen (curve), curve, + (((*keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (*keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + " transient-key" : "")); + } + + if (!keyparms1) + err = gpg_error_from_syserror (); + else + { + err = common_gen (keyparms1, keyparms2, algo, "", + pub_root, timestamp, expireval, is_subkey, + *keygen_flags, passphrase, + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); + xfree (keyparms1); + } + + return err; +} + + /* * Generate an RSA key. */ @@ -1928,7 +2070,7 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, err = gpg_error_from_syserror (); else { - err = common_gen (keyparms, algo, "ne", + err = common_gen (keyparms, NULL, algo, "ne", pub_root, timestamp, expireval, is_subkey, keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr, @@ -2547,6 +2689,12 @@ get_keysize_range (int algo, unsigned int *min, unsigned int *max) def=255; break; + case PUBKEY_ALGO_KYBER: + *min = 768; + *max = 1024; + def = 768; + break; + default: *min = opt.compliance == CO_DE_VS ? 2048: 1024; *max = 4096; @@ -2562,45 +2710,44 @@ get_keysize_range (int algo, unsigned int *min, unsigned int *max) static unsigned int fixup_keysize (unsigned int nbits, int algo, int silent) { + unsigned int orig_nbits = nbits; + if (algo == PUBKEY_ALGO_DSA && (nbits % 64)) { nbits = ((nbits + 63) / 64) * 64; - if (!silent) - tty_printf (_("rounded up to %u bits\n"), nbits); } else if (algo == PUBKEY_ALGO_EDDSA) { - if (nbits != 255 && nbits != 441) - { - if (nbits < 256) - nbits = 255; - else - nbits = 441; - if (!silent) - tty_printf (_("rounded to %u bits\n"), nbits); - } + if (nbits < 256) + nbits = 255; + else + nbits = 441; } else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA) { - if (nbits != 256 && nbits != 384 && nbits != 521) - { - if (nbits < 256) - nbits = 256; - else if (nbits < 384) - nbits = 384; - else - nbits = 521; - if (!silent) - tty_printf (_("rounded to %u bits\n"), nbits); - } + if (nbits < 256) + nbits = 256; + else if (nbits < 384) + nbits = 384; + else + nbits = 521; + } + else if (algo == PUBKEY_ALGO_KYBER) + { + /* (in reality the numbers are not bits) */ + if (nbits < 768) + nbits = 768; + else if (nbits > 1024) + nbits = 1024; } else if ((nbits % 32)) { nbits = ((nbits + 31) / 32) * 32; - if (!silent) - tty_printf (_("rounded up to %u bits\n"), nbits ); } + if (!silent && orig_nbits != nbits) + tty_printf (_("rounded to %u bits\n"), nbits); + return nbits; } @@ -3330,6 +3477,12 @@ do_create (int algo, unsigned int nbits, const char *curve, kbnode_t pub_root, keygen_flags, passphrase, cache_nonce_addr, passwd_nonce_addr, common_gen_cb, common_gen_cb_parm); + else if (algo == PUBKEY_ALGO_KYBER) + err = gen_kyber (algo, nbits, curve, + pub_root, timestamp, expiredate, is_subkey, + keygen_flags, passphrase, + cache_nonce_addr, passwd_nonce_addr, + common_gen_cb, common_gen_cb_parm); else if (algo == PUBKEY_ALGO_RSA) err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey, *keygen_flags, passphrase, @@ -3434,6 +3587,7 @@ parse_key_parameter_part (ctrl_t ctrl, ; /* We need the flags before we can figure out the key to use. */ else if (algo) { + /* This is one of the algos parsed above (rsa, dsa, or elg). */ if (!string[3]) size = get_keysize_range (algo, NULL, NULL); else @@ -3443,14 +3597,15 @@ parse_key_parameter_part (ctrl_t ctrl, return gpg_error (GPG_ERR_INV_VALUE); } } - else if (!ascii_strcasecmp (string, "ky768")) + else if (!ascii_strcasecmp (string, "kyber")) { - algo = PUBKEY_ALGO_KY768_25519; - is_pqc = 1; - } - else if (!ascii_strcasecmp (string, "ky1024")) - { - algo = PUBKEY_ALGO_KY1024_448; + /* Get the curve and check that it can technically be used + * (i.e. everything except the EdXXXX curves. */ + curve = openpgp_is_curve_supported ("brainpoolP384r1", &algo, NULL); + if (!curve || algo == PUBKEY_ALGO_EDDSA) + return gpg_error (GPG_ERR_UNKNOWN_CURVE); + algo = PUBKEY_ALGO_KYBER; + size = 768; is_pqc = 1; } else if (!ascii_strcasecmp (string, "dil3")) @@ -3782,6 +3937,8 @@ parse_key_parameter_part (ctrl_t ctrl, * cv25519 := ECDH using curve Curve25519. * cv448 := ECDH using curve X448. * nistp256:= ECDSA or ECDH using curve NIST P-256 + * kyber := Kyber with the default parameters + * ky768_bp384 := Kyber-768 with BrainpoolP256r1 as second algo * * All strings with an unknown prefix are considered an elliptic * curve. Curves which have no implicit algorithm require that FLAGS @@ -6495,7 +6652,7 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH ) - err = ecckey_from_sexp (pk->pkey, s_key, algo); + err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo); else err = gpg_error (GPG_ERR_PUBKEY_ALGO); gcry_sexp_release (s_key); diff --git a/g10/keyid.c b/g10/keyid.c index 7e4c50b59..b42d918a4 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -74,12 +74,18 @@ pubkey_letter( int algo ) is copied to the supplied buffer up a length of BUFSIZE-1. Examples for the output are: - "rsa3072" - RSA with 3072 bit - "elg1024" - Elgamal with 1024 bit - "ed25519" - ECC using the curve Ed25519. - "E_1.2.3.4" - ECC using the unsupported curve with OID "1.2.3.4". + "rsa3072" - RSA with 3072 bit + "elg1024" - Elgamal with 1024 bit + "ed25519" - EdDSA using the curve Ed25519. + "cv25519" - ECDH using the curve X25519. + "ky768_cv448 - Kyber-768 with X448 as second algo. + "ky1025_bp512 - Kyber-1024 with BrainpoolP256r1 as second algo. + "E_1.2.3.4" - ECC using the unsupported curve with OID "1.2.3.4". + "unknown_N" - Unknown OpenPGP algorithm N. "E_1.3.6.1.4.1.11591.2.12242973" ECC with a bogus OID. - "unknown_N" - Unknown OpenPGP algorithm N. + + Note that with Kyber we use "bp" as abbreviation for BrainpoolP and + ignore the final r1 part. If the option --legacy-list-mode is active, the output use the legacy format: @@ -97,6 +103,9 @@ char * pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize) { const char *prefix = NULL; + int dual = 0; + char *curve; + const char *name; if (opt.legacy_list_mode) { @@ -116,19 +125,34 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize) case PUBKEY_ALGO_ECDH: case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_EDDSA: prefix = ""; break; - case PUBKEY_ALGO_KY768_25519: prefix = "ky768"; break; - case PUBKEY_ALGO_KY1024_448: prefix = "ky1024"; break; + case PUBKEY_ALGO_KYBER: prefix = "ky"; dual = 1; break; case PUBKEY_ALGO_DIL3_25519: prefix = "dil3"; break; case PUBKEY_ALGO_DIL5_448: prefix = "dil5"; break; case PUBKEY_ALGO_SPHINX_SHA2: prefix = "sphinx_sha2"; break; } + if (prefix && *prefix) - snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk)); + { + if (dual) + { + curve = openpgp_oid_to_str (pk->pkey[0]); + /* Note that we prefer the abbreviated name of the curve. */ + name = openpgp_oid_to_curve (curve, 2); + if (!name) + name = "unknown"; + + snprintf (buffer, bufsize, "%s%u_%s", + prefix, nbits_from_pk (pk), name); + xfree (curve); + } + else + snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk)); + } else if (prefix) { - char *curve = openpgp_oid_to_str (pk->pkey[0]); - const char *name = openpgp_oid_to_curve (curve, 0); + curve = openpgp_oid_to_str (pk->pkey[0]); + name = openpgp_oid_to_curve (curve, 0); if (name) snprintf (buffer, bufsize, "%s", name); @@ -308,6 +332,23 @@ do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5) pp[i] = NULL; nn[i] = 0; } + else if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && i == 2) + { + /* Ugly: We need to re-construct the wire format of the + * key parameter. It would be easier to use a second + * second index for pp and nn which could bump + * independet of i. */ + const char *p; + + p = gcry_mpi_get_opaque (pk->pkey[i], &nbits); + pp[i] = xmalloc ((nbits+7)/8 + 1); + if (p) + memcpy (pp[i], p, (nbits+7)/8); + else + pp[i] = NULL; + nn[i] = (nbits+7)/8; + n += nn[i]; + } else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)) { const char *p; @@ -805,11 +846,28 @@ namehash_from_uid (PKT_user_id *uid) /* - * Return the number of bits used in PK. + * Return the number of bits used in PK. For Kyber we return the + * octet count of the Kyber part and not of the ECC (thus likely + * values are 768 or 1024). */ unsigned int nbits_from_pk (PKT_public_key *pk) { + if (pk->pubkey_algo == PUBKEY_ALGO_KYBER) + { + unsigned int nbits; + if (!gcry_mpi_get_opaque (pk->pkey[2], &nbits)) + return 0; + switch (nbits/8) + { + case 800: nbits = 512; break; + case 1184: nbits = 768; break; + case 1568: nbits = 1024; break; + default: nbits = 0; break; /* Unkown version. */ + } + return nbits; + } + else return pubkey_nbits (pk->pubkey_algo, pk->pkey); } @@ -1292,6 +1350,17 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) } break; + case PUBKEY_ALGO_KYBER: + { + char tmpname[15]; + + snprintf (tmpname, sizeof tmpname, "kyber%u", nbits_from_pk (pk)); + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(%s(p%m)))", + tmpname, pk->pkey[2]); + } + break; + default: err = gpg_error (GPG_ERR_PUBKEY_ALGO); break; diff --git a/g10/misc.c b/g10/misc.c index 24242cc30..432fe1760 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -801,8 +801,7 @@ openpgp_pk_algo_usage ( int algo ) use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; break; - case PUBKEY_ALGO_KY768_25519: - case PUBKEY_ALGO_KY1024_448: + case PUBKEY_ALGO_KYBER: use = PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC; break; @@ -1724,6 +1723,7 @@ pubkey_get_npkey (pubkey_algo_t algo) case PUBKEY_ALGO_ECDSA: return 2; case PUBKEY_ALGO_ELGAMAL: return 3; case PUBKEY_ALGO_EDDSA: return 2; + case PUBKEY_ALGO_KYBER: return 3; default: return 0; } } @@ -1744,6 +1744,7 @@ pubkey_get_nskey (pubkey_algo_t algo) case PUBKEY_ALGO_ECDSA: return 3; case PUBKEY_ALGO_ELGAMAL: return 4; case PUBKEY_ALGO_EDDSA: return 3; + case PUBKEY_ALGO_KYBER: return 5; default: return 0; } } @@ -1783,8 +1784,7 @@ pubkey_get_nenc (pubkey_algo_t algo) case PUBKEY_ALGO_ECDSA: return 0; case PUBKEY_ALGO_ELGAMAL: return 2; case PUBKEY_ALGO_EDDSA: return 0; - case PUBKEY_ALGO_KY768_25519: return 4; - case PUBKEY_ALGO_KY1024_448: return 4; + case PUBKEY_ALGO_KYBER: return 4; default: return 0; } } diff --git a/g10/packet.h b/g10/packet.h index a13d3cdc8..40e5051c0 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -863,7 +863,9 @@ gpg_error_t build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf); int build_packet (iobuf_t out, PACKET *pkt); gpg_error_t build_packet_and_meta (iobuf_t out, PACKET *pkt); gpg_error_t gpg_mpi_write (iobuf_t out, gcry_mpi_t a, unsigned int *t_nwritten); -gpg_error_t gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a); +gpg_error_t gpg_mpi_write_opaque_nohdr (iobuf_t out, gcry_mpi_t a); +gpg_error_t gpg_mpi_write_opaque_32 (iobuf_t out, gcry_mpi_t a, + unsigned int *r_nwritten); u32 calc_packet_length( PACKET *pkt ); void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, const byte *buffer, size_t buflen ); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 34760a2d1..2163787cb 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -188,13 +188,21 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure) } -/* Read an octet string of length NBYTES from INP and return it at - * R_DATA. On error return an error code and store NULL at R_DATA. - * PKTLEN shall give the current lenhgth of the packt and is updated - * with each read. If SECURE is true, the integer is stored in secure - * memory (allocated using gcry_xmalloc_secure). */ +/* If NLENGTH is zero read an octet string of length NBYTES from INP + * and return it at R_DATA. + * + * If NLENGTH is either 1, 2, or 4 and NLENGTH is zero read an + * NLENGTH-octet count and use this count number octets from INP and + * return it at R_DATA. + * + * On error return an error code and store NULL at R_DATA. PKTLEN + * shall give the current length of the packet and is updated with + * each read. If SECURE is true, the integer is stored in secure + * memory (allocated using gcry_xmalloc_secure). + */ static gpg_error_t -read_octet_string (iobuf_t inp, unsigned long *pktlen, unsigned int nbytes, +read_octet_string (iobuf_t inp, unsigned long *pktlen, + unsigned int nlength, unsigned int nbytes, int secure, gcry_mpi_t *r_data) { gpg_error_t err; @@ -204,12 +212,48 @@ read_octet_string (iobuf_t inp, unsigned long *pktlen, unsigned int nbytes, *r_data = NULL; - if (nbytes*8 > MAX_EXTERN_MPI_BITS) + if ((nbytes && nlength) + || (!nbytes && !(nlength == 1 || nlength == 2 || nlength == 4))) + { + err = gpg_error (GPG_ERR_INV_ARG); + goto leave; + } + + if (nlength) + { + for (i = 0; i < nlength; i++) + { + if (!*pktlen) + { + err = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + c = iobuf_readbyte (inp); + if (c < 0) + { + err = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + --*pktlen; + nbytes <<= 8; + nbytes |= c; + } + + if (!nbytes) + { + err = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + } + + if (nbytes*8 > (nbytes==4? MAX_EXTERN_KEYPARM_BITS:MAX_EXTERN_MPI_BITS) + || (nbytes*8 < nbytes)) { log_error ("octet string too large (%u octets)\n", nbytes); err = gpg_error (GPG_ERR_TOO_LARGE); goto leave; } + if (nbytes > *pktlen) { log_error ("octet string larger than packet (%u octets)\n", nbytes); @@ -1408,7 +1452,6 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, int i, ndata; unsigned int n; PKT_pubkey_enc *k; - int is_ky1024 = 0; k = packet->pkt.pubkey_enc = xmalloc_clear (sizeof *packet->pkt.pubkey_enc); if (pktlen < 12) @@ -1467,23 +1510,19 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, if (rc) goto leave; } - else if (k->pubkey_algo == PUBKEY_ALGO_KY768_25519 - || (is_ky1024 = (k->pubkey_algo == PUBKEY_ALGO_KY1024_448))) + else if (k->pubkey_algo == PUBKEY_ALGO_KYBER) { log_assert (ndata == 4); /* Get the ephemeral public key. */ - n = is_ky1024? 56 : 32; - rc = read_octet_string (inp, &pktlen, n, 0, k->data + 0); + rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 0); if (rc) goto leave; /* Get the Kyber ciphertext. */ - n = is_ky1024? 1568 : 1088; - rc = read_octet_string (inp, &pktlen, n, 0, k->data + 1); + rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 1); if (rc) goto leave; /* Get the algorithm id. */ - n = 1; - rc = read_octet_string (inp, &pktlen, n, 0, k->data + 2); + rc = read_octet_string (inp, &pktlen, 0, 1, 0, k->data + 2); if (rc) goto leave; /* Get the wrapped symmetric key. */ @@ -2681,17 +2720,25 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, { if ( (algorithm == PUBKEY_ALGO_ECDSA && (i == 0)) || (algorithm == PUBKEY_ALGO_EDDSA && (i == 0)) - || (algorithm == PUBKEY_ALGO_ECDH && (i == 0 || i == 2))) + || (algorithm == PUBKEY_ALGO_ECDH && (i == 0 || i == 2)) + || (algorithm == PUBKEY_ALGO_KYBER && (i == 0))) { /* Read the OID (i==0) or the KDF params (i==2). */ err = read_sized_octet_string (inp, &pktlen, pk->pkey+i); } + else if (algorithm == PUBKEY_ALGO_KYBER && i == 2) + { + /* Read the four-octet count prefixed Kyber public key. */ + err = read_octet_string (inp, &pktlen, 4, 0, 0, pk->pkey+i); + } else { + /* Read MPI or SOS. */ unsigned int n = pktlen; if (algorithm == PUBKEY_ALGO_ECDSA || algorithm == PUBKEY_ALGO_EDDSA - || algorithm == PUBKEY_ALGO_ECDH) + || algorithm == PUBKEY_ALGO_ECDH + || algorithm == PUBKEY_ALGO_KYBER) pk->pkey[i] = sos_read (inp, &n, 0); else pk->pkey[i] = mpi_read (inp, &n, 0); @@ -2707,7 +2754,8 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, mpi_print (listfp, pk->pkey[i], mpi_print_mode); if ((algorithm == PUBKEY_ALGO_ECDSA || algorithm == PUBKEY_ALGO_EDDSA - || algorithm == PUBKEY_ALGO_ECDH) && i==0) + || algorithm == PUBKEY_ALGO_ECDH + || algorithm == PUBKEY_ALGO_KYBER) && i==0) { char *curve = openpgp_oid_to_str (pk->pkey[0]); const char *name = openpgp_oid_to_curve (curve, 0); @@ -3044,21 +3092,32 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, /* Not encrypted. */ for (i = npkey; i < nskey; i++) { - unsigned int n; if (pktlen < 2) /* At least two bytes for the length. */ { err = gpg_error (GPG_ERR_INV_PACKET); goto leave; } - n = pktlen; - if (algorithm == PUBKEY_ALGO_ECDSA - || algorithm == PUBKEY_ALGO_EDDSA - || algorithm == PUBKEY_ALGO_ECDH) - pk->pkey[i] = sos_read (inp, &n, 0); + if (algorithm == PUBKEY_ALGO_KYBER && i == npkey+1) + { + err = read_octet_string (inp, &pktlen, 4, 0, 1, pk->pkey+i); + if (err) + goto leave; + } else - pk->pkey[i] = mpi_read (inp, &n, 0); - pktlen -= n; + { + unsigned int n = pktlen; + + if (algorithm == PUBKEY_ALGO_ECDSA + || algorithm == PUBKEY_ALGO_EDDSA + || algorithm == PUBKEY_ALGO_ECDH + || algorithm == PUBKEY_ALGO_KYBER) + pk->pkey[i] = sos_read (inp, &n, 0); + else + pk->pkey[i] = mpi_read (inp, &n, 0); + pktlen -= n; + } + if (list_mode) { es_fprintf (listfp, "\tskey[%d]: ", i); From 98e287ba6d55a74dad3ce9b8b33501d3f960787c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 4 Apr 2024 15:09:12 +0200 Subject: [PATCH 410/869] gpgconf: Change layout of the gpgconf -X output. * tools/gpgconf.c (list_dirs): Change the config mode output. (my_copy_file): Adjust output for org-mode style. (show_configs_one_file): Ditto. (show_other_registry_entries): Ditto. (show_registry_entries_from_file): Ditto. (show_configs): Ditto. --- tools/gpgconf.c | 123 ++++++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 52 deletions(-) diff --git a/tools/gpgconf.c b/tools/gpgconf.c index 0515aa807..061a4f727 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -288,6 +288,8 @@ list_dirs (estream_t fp, char **names, int show_config_mode) const char *s; gpg_error_t err; + if (show_config_mode) + es_fprintf (fp, "#+begin_example\n"); for (idx = 0; idx < DIM (list); idx++) { s = list[idx].fnc (); @@ -302,12 +304,15 @@ list_dirs (estream_t fp, char **names, int show_config_mode) if (!list[idx].name) ; else if (!names) - es_fprintf (fp, "%s:%s\n", list[idx].name, gc_percent_escape (s)); + es_fprintf (fp, "%s%s:%s\n", show_config_mode? " ":"", + list[idx].name, gc_percent_escape (s)); else { for (j=0; names[j]; j++) if (!strcmp (names[j], list[idx].name)) { + if (show_config_mode) + es_fputs (" ", fp); es_fputs (s, fp); es_putc (opt.null? '\0':'\n', fp); } @@ -326,12 +331,14 @@ list_dirs (estream_t fp, char **names, int show_config_mode) ; /* No such file/ No such device or address - this is okay. */ else es_fprintf (fp, - "### Warning: error reading existing file '%s': %s\n", + "# Warning: error reading existing file '%s': %s\n", s, gpg_strerror (err)); } xfree (tmp); } + if (show_config_mode) + es_fprintf (fp, "#+end_example\n"); #ifdef HAVE_W32_SYSTEM @@ -362,7 +369,7 @@ list_dirs (estream_t fp, char **names, int show_config_mode) es_fflush (fp); if (show_config_mode) es_fprintf (fp, "\n" - "### Note: homedir taken from registry key %s%s\\%s:%s\n" + "Note: homedir taken from registry key %s%s\\%s:%s\n" "\n", hkcu?"HKCU":"", hklm?"HKLM":"", GNUPG_REGISTRY_DIR, "HomeDir"); @@ -380,7 +387,7 @@ list_dirs (estream_t fp, char **names, int show_config_mode) es_fflush (fp); if (show_config_mode) es_fprintf (fp, "\n" - "### Note: registry %s without value in HKCU or HKLM\n" + "Note: registry %s without value in HKCU or HKLM\n" "\n", GNUPG_REGISTRY_DIR); else log_info ("Warning: registry key (%s) without value in HKCU or HKLM\n", @@ -1185,14 +1192,14 @@ show_version_gnupg (estream_t fp, const char *prefix) gpgrt_strusage (13), BUILD_REVISION, prefix, gpgrt_strusage (17)); /* Show the GnuPG VS-Desktop version in --show-configs mode */ - if (prefix && *prefix == '#') + if (prefix && *prefix) { fname = make_filename (gnupg_bindir (), NULL); n = strlen (fname); if (n > 10 && (!ascii_strcasecmp (fname + n - 10, "/GnuPG/bin") || !ascii_strcasecmp (fname + n - 10, "\\GnuPG\\bin"))) { - /* Append VERSION to the ../../ direcory. Note that VERSION + /* Append VERSION to the ../../ directory. Note that VERSION * is only 7 bytes and thus fits. */ strcpy (fname + n - 9, "VERSION"); verfp = es_fopen (fname, "r"); @@ -1376,7 +1383,14 @@ my_copy_file (estream_t src, estream_t dst, strlist_t *listp) while ((length = es_read_line (src, &line, &line_len, NULL)) > 0) { - /* Strip newline and carriage return, if present. */ + /* Prefix each line with two spaces but use a comma if the line + * starts with a special org-mode character. */ + if (*line == '*' || (*line == '#' && line[1] == '+')) + es_fputc (',', dst); + else + es_fputc (' ', dst); + es_fputc (' ', dst); + written = gpgrt_fwrite (line, 1, length, dst); if (written != length) return gpg_error_from_syserror (); @@ -1444,21 +1458,19 @@ show_configs_one_file (const char *fname, int global, estream_t outfp, if (!fp) { err = gpg_error_from_syserror (); - es_fprintf (outfp, "###\n### %s config \"%s\": %s\n###\n", - global? "global":"local", fname, - (gpg_err_code (err) == GPG_ERR_ENOENT)? - "not installed" : gpg_strerror (err)); + if (gpg_err_code (err) != GPG_ERR_ENOENT) + es_fprintf (outfp, "** %s config \"%s\": %s\n", + global? "global":"local", fname, gpg_strerror (err)); } else { - es_fprintf (outfp, "###\n### %s config \"%s\"\n###\n", + es_fprintf (outfp, "** %s config \"%s\"\n#+begin_src\n", global? "global":"local", fname); - es_fprintf (outfp, CUTLINE_FMT, "start"); err = my_copy_file (fp, outfp, listp); + es_fprintf (outfp, "\n#+end_src\n"); if (err) - log_error ("error copying file \"%s\": %s\n", + log_error ("Error copying file \"%s\": %s\n", fname, gpg_strerror (err)); - es_fprintf (outfp, CUTLINE_FMT, "end--"); es_fclose (fp); } } @@ -1533,7 +1545,7 @@ show_other_registry_entries (estream_t outfp) if (names[idx].group != group) { group = names[idx].group; - es_fprintf (outfp, "###\n### %s related:\n", + es_fprintf (outfp, "\n%s related:\n", group == 1 ? "GnuPG Desktop" : group == 2 ? "Outlook" : group == 3 ? "\\Software\\GNU\\GpgOL" @@ -1541,16 +1553,15 @@ show_other_registry_entries (estream_t outfp) } if (group == 3) - es_fprintf (outfp, "### %s=%s%s\n", names[idx].name, value, + es_fprintf (outfp, " %s=%s%s\n", names[idx].name, value, from_hklm? " [hklm]":""); else - es_fprintf (outfp, "### %s\n### ->%s<-%s\n", name, value, + es_fprintf (outfp, " %s\n ->%s<-%s\n", name, value, from_hklm? " [hklm]":""); xfree (value); } - es_fprintf (outfp, "###\n"); xfree (namebuf); } @@ -1601,10 +1612,10 @@ show_registry_entries_from_file (estream_t outfp) if (!any) { any = 1; - es_fprintf (outfp, "### Taken from gpgconf.rnames:\n"); + es_fprintf (outfp, "Taken from gpgconf.rnames:\n"); } - es_fprintf (outfp, "### %s\n### ->%s<-%s\n", line, value, + es_fprintf (outfp, " %s\n ->%s<-%s\n", line, value, from_hklm? " [hklm]":""); } @@ -1615,8 +1626,6 @@ show_registry_entries_from_file (estream_t outfp) } leave: - if (any) - es_fprintf (outfp, "###\n"); xfree (value); xfree (line); es_fclose (fp); @@ -1643,18 +1652,21 @@ show_configs (estream_t outfp) gnupg_dir_t dir; gnupg_dirent_t dir_entry; size_t n; - int any; + int any, anywarn; strlist_t list = NULL; strlist_t sl; const char *s; int got_gpgconfconf = 0; - es_fprintf (outfp, "### Dump of all standard config files\n"); - show_version_gnupg (outfp, "### "); - es_fprintf (outfp, "### Libgcrypt %s\n", gcry_check_version (NULL)); - es_fprintf (outfp, "### GpgRT %s\n", gpg_error_check_version (NULL)); + es_fprintf (outfp, "# gpgconf -X invoked %s%*s-*- org -*-\n\n", + isotimestamp (time (NULL)), 28, ""); + es_fprintf (outfp, "* General information\n"); + es_fprintf (outfp, "** Versions\n"); + show_version_gnupg (outfp, " "); + es_fprintf (outfp, " Libgcrypt %s\n", gcry_check_version (NULL)); + es_fprintf (outfp, " GpgRT %s\n", gpg_error_check_version (NULL)); #ifdef HAVE_W32_SYSTEM - es_fprintf (outfp, "### Codepages:"); + es_fprintf (outfp, " Codepages:"); if (GetConsoleCP () != GetConsoleOutputCP ()) es_fprintf (outfp, " %u/%u", GetConsoleCP (), GetConsoleOutputCP ()); else @@ -1662,16 +1674,19 @@ show_configs (estream_t outfp) es_fprintf (outfp, " %u", GetACP ()); es_fprintf (outfp, " %u\n", GetOEMCP ()); #endif - es_fprintf (outfp, "###\n\n"); + es_fprintf (outfp, "\n\n"); + es_fprintf (outfp, "** Directories\n"); list_dirs (outfp, NULL, 1); es_fprintf (outfp, "\n"); + es_fprintf (outfp, "** Environment\n#+begin_example\n"); for (idx=0; idx < DIM(envvars); idx++) if ((s = getenv (envvars[idx]))) es_fprintf (outfp, "%s=%s\n", envvars[idx], s); - es_fprintf (outfp, "\n"); + es_fprintf (outfp, "#+end_example\n"); + es_fprintf (outfp, "* Config files\n"); fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL); if (!gnupg_access (fname, F_OK)) { @@ -1693,6 +1708,7 @@ show_configs (estream_t outfp) } /* Print the encountered registry values and envvars. */ + es_fprintf (outfp, "* Other info\n"); if (list) { any = 0; @@ -1703,20 +1719,21 @@ show_configs (estream_t outfp) { any = 1; es_fprintf (outfp, - "###\n" - "### List of encountered environment variables:\n"); + "** List of encountered environment variables\n" + "#+begin_example\n"); } if ((s = getenv (sl->d))) - es_fprintf (outfp, "### %-12s ->%s<-\n", sl->d, s); + es_fprintf (outfp, " %-12s ->%s<-\n", sl->d, s); else - es_fprintf (outfp, "### %-12s [not set]\n", sl->d); + es_fprintf (outfp, " %-12s [not set]\n", sl->d); } if (any) - es_fprintf (outfp, "###\n"); + es_fprintf (outfp, "#+end_example\n"); } #ifdef HAVE_W32_SYSTEM - es_fprintf (outfp, "###\n### Registry entries:\n"); + es_fprintf (outfp, "** Registry entries\n"); + es_fprintf (outfp, "#+begin_example\n"); any = 0; if (list) { @@ -1729,33 +1746,31 @@ show_configs (estream_t outfp) if (!any) { any = 1; - es_fprintf (outfp, "###\n### Encountered in config files:\n"); + es_fprintf (outfp, "Encountered in config files:\n"); } if ((p = read_w32_reg_string (sl->d, &from_hklm))) - es_fprintf (outfp, "### %s ->%s<-%s\n", sl->d, p, + es_fprintf (outfp, " %s ->%s<-%s\n", sl->d, p, from_hklm? " [hklm]":""); else - es_fprintf (outfp, "### %s [not set]\n", sl->d); + es_fprintf (outfp, " %s [not set]\n", sl->d); xfree (p); } } - if (!any) - es_fprintf (outfp, "###\n"); show_other_registry_entries (outfp); show_registry_entries_from_file (outfp); + es_fprintf (outfp, "#+end_example\n"); #endif /*HAVE_W32_SYSTEM*/ free_strlist (list); - any = 0; - /* Additional warning. */ + anywarn = 0; if (got_gpgconfconf) { + anywarn = 1; + es_fprintf (outfp, "* Warnings\n"); es_fprintf (outfp, - "###\n" - "### Warning: legacy config file \"gpgconf.conf\" found\n"); - any = 1; + "- Legacy config file \"gpgconf.conf\" found\n"); } /* Check for uncommon files in the home directory. */ @@ -1768,6 +1783,7 @@ show_configs (estream_t outfp) return; } + any = 0; while ((dir_entry = gnupg_readdir (dir))) { for (idx = 0; idx < DIM (names); idx++) @@ -1777,19 +1793,22 @@ show_configs (estream_t outfp) && dir_entry->d_name[n] == '-' && ascii_strncasecmp (dir_entry->d_name, "gpg.conf-1", 10)) { + if (!anywarn) + { + anywarn = 1; + es_fprintf (outfp, "* Warnings\n"); + } if (!any) { any = 1; es_fprintf (outfp, - "###\n" - "### Warning: suspicious files in \"%s\":\n", + "- Suspicious files in \"%s\":\n", gnupg_homedir ()); } - es_fprintf (outfp, "### %s\n", dir_entry->d_name); + es_fprintf (outfp, " - %s\n", dir_entry->d_name); } } } - if (any) - es_fprintf (outfp, "###\n"); gnupg_closedir (dir); + es_fprintf (outfp, "# eof #\n"); } From 0b1f7427b3ca9a378f9a8290a2b1e31b71d608f6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 4 Apr 2024 16:39:14 +0200 Subject: [PATCH 411/869] gpg: Do not allow to accidently set the RENC usage. * g10/keygen.c (print_key_flags): Print "RENC" if set. (ask_key_flags_with_mask): Remove RENC from the possible set of usages. Add a direct way to set it iff the key is encryption capable. -- This could be done by using "set your own capabilities" for an RSA key. In fact it was always set in this case. GnuPG-bug-id: 7072 --- g10/keygen.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/g10/keygen.c b/g10/keygen.c index b263a47de..48e5b3a40 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1982,6 +1982,9 @@ print_key_flags(int flags) if(flags&PUBKEY_USAGE_AUTH) tty_printf("%s ",_("Authenticate")); + + if(flags&PUBKEY_USAGE_RENC) + tty_printf("%s ", "RENC"); } @@ -2014,10 +2017,14 @@ ask_key_flags_with_mask (int algo, int subkey, unsigned int current, togglers = "11223300"; } + /* restrict the mask to the actual useful bits. */ + /* Mask the possible usage flags. This is for example used for a * card based key. For ECDH we need to allows additional usages if - * they are provided. */ + * they are provided. RENC is not directly poissible here but see + * below for a workaround. */ possible = (openpgp_pk_algo_usage (algo) & mask); + possible &= ~PUBKEY_USAGE_RENC; if (algo == PUBKEY_ALGO_ECDH) possible |= (current & (PUBKEY_USAGE_ENC |PUBKEY_USAGE_CERT @@ -2086,6 +2093,12 @@ ask_key_flags_with_mask (int algo, int subkey, unsigned int current, want to experiment with a cert-only primary key. */ current |= PUBKEY_USAGE_CERT; } + else if ((*s == 'r' || *s == 'R') && (possible&PUBKEY_USAGE_ENC)) + { + /* Allow to set RENC or an encryption capable key. + * This is on purpose not shown in the menu. */ + current |= PUBKEY_USAGE_RENC; + } } break; } From 131dd2a35145a1db1a45ab76764f32cbbca3fd43 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 5 Apr 2024 14:17:25 +0900 Subject: [PATCH 412/869] agent: Add initial support for hybrid ECC+PQC decryption with KEM. * agent/agent.h (enum kemid): New. (agent_kem_decrypt): New. * agent/command.c (cmd_pkdecrypt): Support --kem option to call agent_kem_decrypt. * agent/pkdecrypt.c (reverse_buffer): New. (agent_hybrid_pgp_kem_decrypt): New. (agent_kem_decrypt): New. -- Now, it only supports X25519 + ML-KEM. GnuPG-bug-id: 7014 Signed-off-by: NIIBE Yutaka --- agent/agent.h | 12 ++ agent/command.c | 45 ++++++- agent/pkdecrypt.c | 312 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 362 insertions(+), 7 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index b3d3c0407..af040b63f 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -560,6 +560,18 @@ gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *ciphertext, size_t ciphertextlen, membuf_t *outbuf, int *r_padding); +enum kemid + { + KEM_PQC_PGP, + KEM_PGP, + KEM_CMS, + }; + +gpg_error_t agent_kem_decrypt (ctrl_t ctrl, const char *desc_text, int kemid, + const unsigned char *ct, size_t ctlen, + const unsigned char *option, size_t optionlen, + membuf_t *outbuf); + /*-- genkey.c --*/ #define CHECK_CONSTRAINTS_NOT_EMPTY 1 #define CHECK_CONSTRAINTS_NEW_SYMKEY 2 diff --git a/agent/command.c b/agent/command.c index 5e74381ed..fd050ee6b 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1049,10 +1049,14 @@ cmd_pksign (assuan_context_t ctx, char *line) static const char hlp_pkdecrypt[] = - "PKDECRYPT []\n" + "PKDECRYPT [--kem[=] []\n" "\n" "Perform the actual decrypt operation. Input is not\n" - "sensitive to eavesdropping."; + "sensitive to eavesdropping.\n" + "If the --kem option is used, decryption is done with the KEM,\n" + "inquiring upper-layer option, when needed. KEMID can be\n" + "specified with --kem option; Valid value is: PQC-PGP, PGP, or CMS.\n" + "Default is PQC-PGP."; static gpg_error_t cmd_pkdecrypt (assuan_context_t ctx, char *line) { @@ -1061,22 +1065,51 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) unsigned char *value; size_t valuelen; membuf_t outbuf; - int padding; + int padding = -1; + unsigned char *option = NULL; + size_t optionlen = 0; + const char *p; + int kemid = -1; - (void)line; + p = has_option_name (line, "--kem"); + if (p) + { + kemid = KEM_PQC_PGP; + if (*p++ == '=') + { + if (strcmp (p, "PQC-PGP")) + kemid = KEM_PQC_PGP; + else if (strcmp (p, "PGP")) + kemid = KEM_PGP; + else if (strcmp (p, "CMS")) + kemid = KEM_CMS; + else + return set_error (GPG_ERR_ASS_PARAMETER, "invalid KEM algorithm"); + } + } /* First inquire the data to decrypt */ rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_CIPHERTEXT); if (!rc) rc = assuan_inquire (ctx, "CIPHERTEXT", &value, &valuelen, MAXLEN_CIPHERTEXT); + if (!rc && kemid > KEM_PQC_PGP) + rc = assuan_inquire (ctx, "OPTION", + &option, &optionlen, MAXLEN_CIPHERTEXT); if (rc) return rc; init_membuf (&outbuf, 512); - rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc, - value, valuelen, &outbuf, &padding); + if (kemid < 0) + rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc, + value, valuelen, &outbuf, &padding); + else + { + rc = agent_kem_decrypt (ctrl, ctrl->server_local->keydesc, kemid, + value, valuelen, option, optionlen, &outbuf); + xfree (option); + } xfree (value); if (rc) clear_outbuf (&outbuf); diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index c26f21d35..9d87e9fba 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -27,7 +27,7 @@ #include #include "agent.h" - +#include "../common/openpgpdefs.h" /* DECRYPT the stuff in ciphertext which is expected to be a S-Exp. Try to get the key from CTRL and write the decoded stuff back to @@ -157,3 +157,313 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, xfree (shadow_info); return err; } + + +/* Reverse BUFFER to change the endianness. */ +static void +reverse_buffer (unsigned char *buffer, unsigned int length) +{ + unsigned int tmp, i; + + for (i=0; i < length/2; i++) + { + tmp = buffer[i]; + buffer[i] = buffer[length-1-i]; + buffer[length-1-i] = tmp; + } +} + +/* For hybrid PGP KEM (ECC+ML-KEM), decrypt CIPHERTEXT using KEM API. + First keygrip is for ECC, second keygrip is for PQC. CIPHERTEXT + should follow the format of: + + (enc-val(pqc(s%m)(e%m)(k%m)))) + s: encrypted session key + e: ECDH ciphertext + k: ML-KEM ciphertext + + FIXME: For now, possibile keys on smartcard are not supported. + */ +static gpg_error_t +agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, + gcry_sexp_t s_cipher, membuf_t *outbuf) +{ + gcry_sexp_t s_skey0 = NULL; + gcry_sexp_t s_skey1 = NULL; + unsigned char *shadow_info = NULL; + gpg_error_t err = 0; + + unsigned int nbits; + const unsigned char *p; + size_t len; + + gcry_mpi_t encrypted_sessionkey_mpi; + const unsigned char *encrypted_sessionkey; + size_t encrypted_sessionkey_len; + + gcry_mpi_t ecc_sk_mpi; + unsigned char ecc_sk[32]; + gcry_mpi_t ecc_pk_mpi; + unsigned char ecc_pk[32]; + gcry_mpi_t ecc_ct_mpi; + const unsigned char *ecc_ct; + size_t ecc_ct_len; + unsigned char ecc_ecdh[32]; + unsigned char ecc_ss[32]; + + gcry_mpi_t mlkem_sk_mpi; + gcry_mpi_t mlkem_ct_mpi; + const unsigned char *mlkem_sk; + const unsigned char *mlkem_ct; + unsigned char mlkem_ss[GCRY_KEM_MLKEM768_SHARED_LEN]; + + gcry_buffer_t iov[6]; + + unsigned char kekkey[32]; + size_t kekkeylen = 32; /* AES-256 is mandatory */ + + gcry_cipher_hd_t hd; + unsigned char sessionkey[256]; + size_t sessionkey_len; + const unsigned char fixedinfo[1] = { 105 }; + + err = agent_key_from_file (ctrl, NULL, desc_text, + ctrl->keygrip, &shadow_info, + CACHE_MODE_NORMAL, NULL, &s_skey0, NULL, NULL); + if (err) + { + log_error ("failed to read the secret key\n"); + goto leave; + } + + err = agent_key_from_file (ctrl, NULL, desc_text, + ctrl->keygrip1, &shadow_info, + CACHE_MODE_NORMAL, NULL, &s_skey1, NULL, NULL); + if (err) + { + log_error ("failed to read the another secret key\n"); + goto leave; + } + + /* Here assumes no smartcard, but private keys */ + + gcry_sexp_extract_param (s_cipher, NULL, "/e/k/s", + &ecc_ct_mpi, + &mlkem_ct_mpi, + &encrypted_sessionkey_mpi, NULL); + + encrypted_sessionkey = gcry_mpi_get_opaque (encrypted_sessionkey_mpi, &nbits); + encrypted_sessionkey_len = (nbits+7)/8; + encrypted_sessionkey_len--; + + if (encrypted_sessionkey[0] != encrypted_sessionkey_len) + { + err = GPG_ERR_INV_DATA; + goto leave; + } + encrypted_sessionkey++; /* Skip the length. */ + + if (encrypted_sessionkey[0] != CIPHER_ALGO_AES256) + { + err = GPG_ERR_INV_DATA; + goto leave; + } + encrypted_sessionkey_len--; + encrypted_sessionkey++; /* Skip the sym algo */ + + /* Fistly, ECC part. FIXME: For now, we assume X25519. */ + gcry_sexp_extract_param (s_skey0, NULL, "/q/d", + &ecc_pk_mpi, &ecc_sk_mpi, NULL); + p = gcry_mpi_get_opaque (ecc_pk_mpi, &nbits); + len = (nbits+7)/8; + memcpy (ecc_pk, p+1, 32); /* Remove the 0x40 prefix */ + p = gcry_mpi_get_opaque (ecc_sk_mpi, &nbits); + len = (nbits+7)/8; + if (len > 32) + { + err = GPG_ERR_INV_DATA; + goto leave; + } + memset (ecc_sk, 0, 32); + memcpy (ecc_sk + 32 - len, p, len); + reverse_buffer (ecc_sk, 32); + mpi_release (ecc_pk_mpi); + mpi_release (ecc_sk_mpi); + + ecc_ct = gcry_mpi_get_opaque (ecc_ct_mpi, &nbits); + ecc_ct_len = (nbits+7)/8; + if (ecc_ct_len != 32) + { + err = GPG_ERR_INV_DATA; + goto leave; + } + + err = gcry_kem_decap (GCRY_KEM_RAW_X25519, ecc_sk, 32, ecc_ct, ecc_ct_len, + ecc_ecdh, 32, NULL, 0); + + iov[0].data = ecc_ecdh; + iov[0].off = 0; + iov[0].len = 32; + iov[1].data = (unsigned char *)ecc_ct; + iov[1].off = 0; + iov[1].len = 32; + iov[2].data = ecc_pk; + iov[2].off = 0; + iov[2].len = 32; + gcry_md_hash_buffers (GCRY_MD_SHA3_256, 0, ecc_ss, iov, 3); + + /* Secondly, PQC part. For now, we assume ML-KEM. */ + gcry_sexp_extract_param (s_skey1, NULL, "/s", &mlkem_sk_mpi, NULL); + mlkem_sk = gcry_mpi_get_opaque (mlkem_sk_mpi, &nbits); + len = (nbits+7)/8; + if (len != GCRY_KEM_MLKEM768_SECKEY_LEN) + { + err = GPG_ERR_INV_DATA; + goto leave; + } + mlkem_ct = gcry_mpi_get_opaque (mlkem_ct_mpi, &nbits); + len = (nbits+7)/8; + if (len != GCRY_KEM_MLKEM768_CIPHER_LEN) + { + err = GPG_ERR_INV_DATA; + goto leave; + } + err = gcry_kem_decap (GCRY_KEM_MLKEM768, + mlkem_sk, GCRY_KEM_MLKEM768_SECKEY_LEN, + mlkem_ct, GCRY_KEM_MLKEM768_CIPHER_LEN, + mlkem_ss, GCRY_KEM_MLKEM768_SHARED_LEN, + NULL, 0); + + mpi_release (mlkem_sk_mpi); + + /* Then, combine two shared secrets into one */ + + iov[0].data = "\x00\x00\x00\x01"; /* Counter */ + iov[0].off = 0; + iov[0].len = 4; + + iov[1].data = ecc_ss; + iov[1].off = 0; + iov[1].len = 32; + + iov[2].data = (unsigned char *)ecc_ct; + iov[2].off = 0; + iov[2].len = 32; + + iov[3].data = mlkem_ss; + iov[3].off = 0; + iov[3].len = GCRY_KEM_MLKEM768_SHARED_LEN; + + iov[4].data = (unsigned char *)mlkem_ct; + iov[4].off = 0; + iov[4].len = GCRY_KEM_MLKEM768_ENCAPS_LEN; + + iov[5].data = (unsigned char *)fixedinfo; + iov[5].off = 0; + iov[5].len = 1; + + err = compute_kmac256 (kekkey, kekkeylen, + "OpenPGPCompositeKeyDerivationFunction", 37, + "KDF", 3, iov, 6); + + mpi_release (ecc_ct_mpi); + mpi_release (mlkem_ct_mpi); + + if (DBG_CRYPTO) + { + log_printhex (kekkey, kekkeylen, "KEK key: "); + } + + err = gcry_cipher_open (&hd, GCRY_CIPHER_AES256, + GCRY_CIPHER_MODE_AESWRAP, 0); + if (err) + { + log_error ("ecdh failed to initialize AESWRAP: %s\n", + gpg_strerror (err)); + mpi_release (encrypted_sessionkey_mpi); + goto leave; + } + + err = gcry_cipher_setkey (hd, kekkey, kekkeylen); + + sessionkey_len = encrypted_sessionkey_len - 8; + err = gcry_cipher_decrypt (hd, sessionkey, sessionkey_len, + encrypted_sessionkey, encrypted_sessionkey_len); + gcry_cipher_close (hd); + + mpi_release (encrypted_sessionkey_mpi); + + if (err) + { + log_error ("KEM decrypt failed: %s\n", gpg_strerror (err)); + goto leave; + } + + put_membuf_printf (outbuf, + "(5:value%u:", (unsigned int)sessionkey_len); + put_membuf (outbuf, sessionkey, sessionkey_len); + put_membuf (outbuf, ")", 2); + + leave: + gcry_sexp_release (s_skey0); + gcry_sexp_release (s_skey1); + return err; +} + +/* DECRYPT the encrypted stuff (like encrypted session key) in + CIPHERTEXT using KEM API, with KEMID. Keys (or a key) are + specified in CTRL. DESC_TEXT is used to retrieve private key. + OPTION can be specified for upper layer option for KEM. Decrypted + stuff (like session key) is written to OUTBUF. + */ +gpg_error_t +agent_kem_decrypt (ctrl_t ctrl, const char *desc_text, int kemid, + const unsigned char *ciphertext, size_t ciphertextlen, + const unsigned char *option, size_t optionlen, + membuf_t *outbuf) +{ + gcry_sexp_t s_cipher = NULL; + gpg_error_t err = 0; + + /* For now, only PQC-PGP is supported. */ + if (kemid != KEM_PQC_PGP) + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + + (void)optionlen; + if (kemid == KEM_PQC_PGP && option) + { + log_error ("PQC-PGP requires no option\n"); + return gpg_error (GPG_ERR_INV_ARG); + } + + if (!ctrl->have_keygrip) + { + log_error ("speculative decryption not yet supported\n"); + return gpg_error (GPG_ERR_NO_SECKEY); + } + + if (!ctrl->have_keygrip1) + { + log_error ("hybrid KEM requires two KEYGRIPs\n"); + return gpg_error (GPG_ERR_NO_SECKEY); + } + + err = gcry_sexp_sscan (&s_cipher, NULL, (char*)ciphertext, ciphertextlen); + if (err) + { + log_error ("failed to convert ciphertext: %s\n", gpg_strerror (err)); + return gpg_error (GPG_ERR_INV_DATA); + } + + if (DBG_CRYPTO) + { + log_printhex (ctrl->keygrip, 20, "keygrip:"); + log_printhex (ctrl->keygrip1, 20, "keygrip1:"); + log_printhex (ciphertext, ciphertextlen, "cipher: "); + } + + err = agent_hybrid_pgp_kem_decrypt (ctrl, desc_text, s_cipher, outbuf); + + gcry_sexp_release (s_cipher); + return err; +} From 548fd7bca787bfa9439c2bec4153a9311dbbea34 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Apr 2024 11:02:43 +0200 Subject: [PATCH 413/869] gpg: Don't show the "fast path listing" diagnostic with --quiet. * g10/call-agent.c (agent_probe_any_secret_key): Act on --quiet. -- When using the extra-socket this disagnostic will be printed because a listing of all secret keys is not allowed by a remote gpg. --- g10/call-agent.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index daf12fae7..69207566e 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -2319,8 +2319,9 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock) } if (err) { - log_info ("problem with fast path key listing: %s - ignored\n", - gpg_strerror (err)); + if (!opt.quiet) + log_info ("problem with fast path key listing: %s - ignored\n", + gpg_strerror (err)); err = 0; } /* We want to do this only once. */ From ce8b25270b2ac7ec1dc830e657d04edeff36be4b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Apr 2024 11:14:10 +0200 Subject: [PATCH 414/869] agent: Make "PKDECRYPT --kem" with optional value work. * agent/command.c (cmd_pkdecrypt): Fix comparison. * agent/agent.h (enum kemids): Rename type and strip trailing comma. * agent/pkdecrypt.c (agent_hybrid_pgp_kem_decrypt): Allow building with Libgcrypt < 1.11 -- Eventually we should change the libgcrypt requirement in configure. --- agent/agent.h | 4 ++-- agent/command.c | 9 +++++---- agent/pkdecrypt.c | 4 ++++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index af040b63f..4a945102a 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -560,11 +560,11 @@ gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *ciphertext, size_t ciphertextlen, membuf_t *outbuf, int *r_padding); -enum kemid +enum kemids { KEM_PQC_PGP, KEM_PGP, - KEM_CMS, + KEM_CMS }; gpg_error_t agent_kem_decrypt (ctrl_t ctrl, const char *desc_text, int kemid, diff --git a/agent/command.c b/agent/command.c index fd050ee6b..2fd9a85d4 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1075,13 +1075,14 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) if (p) { kemid = KEM_PQC_PGP; - if (*p++ == '=') + if (*p == '=') { - if (strcmp (p, "PQC-PGP")) + p++; + if (!strcmp (p, "PQC-PGP")) kemid = KEM_PQC_PGP; - else if (strcmp (p, "PGP")) + else if (!strcmp (p, "PGP")) kemid = KEM_PGP; - else if (strcmp (p, "CMS")) + else if (!strcmp (p, "CMS")) kemid = KEM_CMS; else return set_error (GPG_ERR_ASS_PARAMETER, "invalid KEM algorithm"); diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 9d87e9fba..e93ac0a26 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -188,6 +188,7 @@ static gpg_error_t agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_sexp_t s_cipher, membuf_t *outbuf) { +#if GCRYPT_VERSION_NUMBER >= 0x010b00 gcry_sexp_t s_skey0 = NULL; gcry_sexp_t s_skey1 = NULL; unsigned char *shadow_info = NULL; @@ -408,6 +409,9 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_sexp_release (s_skey0); gcry_sexp_release (s_skey1); return err; +#else + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +#endif } /* DECRYPT the encrypted stuff (like encrypted session key) in From 53c6b1e85854e242da254334ad84145b2b4d963e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Apr 2024 12:02:32 +0200 Subject: [PATCH 415/869] gpg: Support dual keygrips. * g10/keyid.c (keygrip_from_pk): Add arg get_second to support dual algos. Implement for Kyber. (hexkeygrip_from_pk): Extend for dual algos. * g10/call-agent.c (agent_keytotpm): Bail out for dual algos. (agent_keytocard): Ditto. (agent_probe_secret_key): Handle dual algos. (agent_probe_any_secret_key): Ditto. (agent_get_keyinfo): Allow for dual algos but take only the first key. * g10/export.c (do_export_one_keyblock): Bail out for dual algos. -- This also adds some fixmes which we eventually need to address. GnuPG-bug-id: 6815 --- doc/DETAILS | 12 ++--- g10/call-agent.c | 119 ++++++++++++++++++++++++++++++++++++++++------- g10/export.c | 5 ++ g10/keydb.h | 3 +- g10/keyedit.c | 1 + g10/keygen.c | 2 + g10/keyid.c | 79 +++++++++++++++++++++++-------- g10/keyring.c | 2 +- g10/pubkey-enc.c | 2 + g10/sign.c | 2 + 10 files changed, 181 insertions(+), 46 deletions(-) diff --git a/doc/DETAILS b/doc/DETAILS index 583022113..a278d045f 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -169,10 +169,11 @@ described here. (the colon is quoted =\x3a=). For a "pub" record this field is not used on --fixed-list-mode. A "uat" record puts the attribute subpacket count here, a space, and then the total attribute - subpacket size. In gpgsm the issuer name comes here. The FPR and FP2 - records store the fingerprints here. The fingerprint of a + subpacket size. In gpgsm the issuer name comes here. The FPR and + FP2 records store the fingerprints here. The fingerprint of a revocation key is also stored here. A "grp" records puts the - keygrip here. + keygrip here; for combined algorithms the keygrips are delimited + by comma. *** Field 11 - Signature class @@ -186,9 +187,6 @@ described here. "rev" and "rvs" may be followed by a comma and a 2 digit hexnumber with the revocation reason. - In a "grp" record the second keygrip for combined algorithms is - given here. - *** Field 12 - Key capabilities The defined capabilities are: @@ -248,7 +246,7 @@ described here. For pub, sub, sec, ssb, crt, and crs records this field is used for the ECC curve name. For combined algorithms the first and the - second algorithm name, delimited by a '+', are put here. + second algorithm name, delimited by an underscore are put here. *** Field 18 - Compliance flags diff --git a/g10/call-agent.c b/g10/call-agent.c index 06ed232fa..e7046f7b2 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1080,6 +1080,12 @@ agent_keytotpm (ctrl_t ctrl, const char *hexgrip) snprintf(line, DIM(line), "KEYTOTPM %s\n", hexgrip); + if (strchr (hexgrip, ',')) + { + log_error ("storing a part of a dual key is not yet supported\n"); + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } + rc = start_agent (ctrl, 0); if (rc) return rc; @@ -1109,6 +1115,13 @@ agent_keytocard (const char *hexgrip, int keyno, int force, memset (&parm, 0, sizeof parm); + if (strchr (hexgrip, ',')) + { + log_error ("storing a part of a dual key is not yet supported\n"); + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } + + snprintf (line, DIM(line), "KEYTOCARD %s%s %s OPENPGP.%d %s%s%s", force?"--force ": "", hexgrip, serialno, keyno, timestamp, ecdh_param_str? " ":"", ecdh_param_str? ecdh_param_str:""); @@ -2240,9 +2253,9 @@ agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk) { gpg_error_t err; char line[ASSUAN_LINELENGTH]; - char *hexgrip; - + char *hexgrip, *p; struct keyinfo_data_parm_s keyinfo; + int result, result2; memset (&keyinfo, 0, sizeof keyinfo); @@ -2253,28 +2266,64 @@ agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk) err = hexkeygrip_from_pk (pk, &hexgrip); if (err) return 0; + if ((p=strchr (hexgrip, ','))) + *p++ = 0; snprintf (line, sizeof line, "KEYINFO %s", hexgrip); - xfree (hexgrip); err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, keyinfo_status_cb, &keyinfo); xfree (keyinfo.serialno); if (err) - return 0; + result = 0; + else if (keyinfo.card_available) + result = 4; + else if (keyinfo.passphrase_cached) + result = 3; + else if (keyinfo.is_smartcard) + result = 2; + else + result = 1; - if (keyinfo.card_available) - return 4; + if (!p) + { + xfree (hexgrip); + return result; /* Not a dual algo - we are ready. */ + } - if (keyinfo.passphrase_cached) - return 3; + /* Now check the second keygrip. */ + memset (&keyinfo, 0, sizeof keyinfo); + snprintf (line, sizeof line, "KEYINFO %s", p); - if (keyinfo.is_smartcard) - return 2; + err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, + keyinfo_status_cb, &keyinfo); + xfree (keyinfo.serialno); + if (err) + result2 = 0; + else if (keyinfo.card_available) + result2 = 4; + else if (keyinfo.passphrase_cached) + result2 = 3; + else if (keyinfo.is_smartcard) + result2 = 2; + else + result2 = 1; - return 1; + xfree (hexgrip); + + if (result == result2) + return result; /* Both keys have the same status. */ + else if (!result && result2) + return 0; /* Only first key available - return no key. */ + else if (result && !result2) + return 0; /* Only second key not availabale - return no key. */ + else if (result == 4 || result == 2) + return result; /* First key on card - don't care where the second is. */ + else + return result; } + /* Ask the agent whether a secret key is available for any of the keys (primary or sub) in KEYBLOCK. Returns 0 if available. */ gpg_error_t @@ -2286,6 +2335,8 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock) kbnode_t kbctx, node; int nkeys; /* (always zero in secret_keygrips mode) */ unsigned char grip[KEYGRIP_LEN]; + unsigned char grip2[KEYGRIP_LEN]; + int grip2_valid; const unsigned char *s; unsigned int n; @@ -2320,8 +2371,9 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock) } if (err) { - log_info ("problem with fast path key listing: %s - ignored\n", - gpg_strerror (err)); + if (opt.quiet) + log_info ("problem with fast path key listing: %s - ignored\n", + gpg_strerror (err)); err = 0; } /* We want to do this only once. */ @@ -2340,22 +2392,30 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock) if (ctrl && ctrl->secret_keygrips) { /* We got an array with all secret keygrips. Check this. */ - err = keygrip_from_pk (node->pkt->pkt.public_key, grip); + err = keygrip_from_pk (node->pkt->pkt.public_key, grip, 0); if (err) return err; + err = keygrip_from_pk (node->pkt->pkt.public_key, grip2, 1); + if (err && gpg_err_code (err) != GPG_ERR_FALSE) + return err; + grip2_valid = !err; + for (s=ctrl->secret_keygrips, n = 0; n < ctrl->secret_keygrips_len; s += 20, n += 20) { if (!memcmp (s, grip, 20)) return 0; + if (grip2_valid && !memcmp (s, grip2, 20)) + return 0; } err = gpg_error (GPG_ERR_NO_SECKEY); /* Keep on looping over the keyblock. Never bump nkeys. */ } else { - if (nkeys && ((p - line) + 41) > (ASSUAN_LINELENGTH - 2)) + if (nkeys + && ((p - line) + 4*KEYGRIP_LEN+1+1) > (ASSUAN_LINELENGTH - 2)) { err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); @@ -2365,13 +2425,24 @@ agent_probe_any_secret_key (ctrl_t ctrl, kbnode_t keyblock) nkeys = 0; } - err = keygrip_from_pk (node->pkt->pkt.public_key, grip); + err = keygrip_from_pk (node->pkt->pkt.public_key, grip, 0); if (err) return err; *p++ = ' '; bin2hex (grip, 20, p); p += 40; nkeys++; + + err = keygrip_from_pk (node->pkt->pkt.public_key, grip2, 1); + if (err && gpg_err_code (err) != GPG_ERR_FALSE) + return err; + if (!err) /* Add the second keygrip from dual algos. */ + { + *p++ = ' '; + bin2hex (grip2, 20, p); + p += 40; + nkeys++; + } } } @@ -2398,6 +2469,7 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, gpg_error_t err; char line[ASSUAN_LINELENGTH]; struct keyinfo_data_parm_s keyinfo; + char *s; memset (&keyinfo, 0,sizeof keyinfo); @@ -2407,10 +2479,20 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, if (err) return err; - if (!hexkeygrip || strlen (hexkeygrip) != 40) + /* FIXME: Support dual keys. Maybe under the assumption that the + * first key might be on a card. */ + if (!hexkeygrip) + return gpg_error (GPG_ERR_INV_VALUE); + s = strchr (hexkeygrip, ','); + if (!s) + s = hexkeygrip + strlen (hexkeygrip); + if (s - hexkeygrip != 40) return gpg_error (GPG_ERR_INV_VALUE); - snprintf (line, DIM(line), "KEYINFO %s", hexkeygrip); + /* Note that for a dual algo we only get info for the first key. + * FIXME: We need to see how we can show the status of the second + * key in a key listing. */ + snprintf (line, DIM(line), "KEYINFO %.40s", hexkeygrip); err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, keyinfo_status_cb, &keyinfo); @@ -3174,6 +3256,7 @@ agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc, return err; } + /* FIXME: Shall we add support to DELETE_KEY for dual keys? */ snprintf (line, DIM(line), "DELETE_KEY%s %s", force? " --force":"", hexkeygrip); err = assuan_transact (agent_ctx, line, NULL, NULL, diff --git a/g10/export.c b/g10/export.c index 74cb03764..2417edef1 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1961,6 +1961,11 @@ do_export_one_keyblock (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, err = 0; continue; } + if (strchr (hexgrip, ',')) + { + log_error ("exporting a secret dual key is not yet supported\n"); + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } xfree (serialno); serialno = NULL; diff --git a/g10/keydb.h b/g10/keydb.h index 62a99295d..75a8ded72 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -578,7 +578,8 @@ char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen); char *v5hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen); char *format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen); -gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array); +gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array, + int get_second); gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip); char *ecdh_param_str_from_pk (PKT_public_key *pk); diff --git a/g10/keyedit.c b/g10/keyedit.c index 7523a1a62..a09797a36 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1103,6 +1103,7 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock) err = hexkeygrip_from_pk (pk, &hexgrip); if (err) goto leave; + /* FIXME: Handle dual keys. */ err = agent_get_keyinfo (ctrl, hexgrip, &serialno, NULL); if (!err && serialno) ; /* Key on card. */ diff --git a/g10/keygen.c b/g10/keygen.c index 8df8294d6..6426f7e4f 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -6308,6 +6308,8 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr, err = hexkeygrip_from_pk (pri_psk, &hexgrip); if (err) goto leave; + /* FIXME: Right now the primary key won't be a dual key. But this + * will change */ if (agent_get_keyinfo (NULL, hexgrip, &serialno, NULL)) { if (interactive) diff --git a/g10/keyid.c b/g10/keyid.c index b42d918a4..09940cbfe 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -1293,16 +1293,22 @@ format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen) /* Return the so called KEYGRIP which is the SHA-1 hash of the public - key parameters expressed as an canonical encoded S-Exp. ARRAY must - be 20 bytes long. Returns 0 on success or an error code. */ + * key parameters expressed as an canonical encoded S-Exp. ARRAY must + * be 20 bytes long. Returns 0 on success or an error code. If + * GET_SECOND Is one and PK has dual algorithm, the keygrip of the + * second algorithm is return; GPG_ERR_FALSE is returned if the algo + * is not a dual algorithm. */ gpg_error_t -keygrip_from_pk (PKT_public_key *pk, unsigned char *array) +keygrip_from_pk (PKT_public_key *pk, unsigned char *array, int get_second) { gpg_error_t err; gcry_sexp_t s_pkey; if (DBG_PACKET) - log_debug ("get_keygrip for public key\n"); + log_debug ("get_keygrip for public key%s\n", get_second?" (second)":""); + + if (get_second && pk->pubkey_algo != PUBKEY_ALGO_KYBER) + return gpg_error (GPG_ERR_FALSE); switch (pk->pubkey_algo) { @@ -1351,14 +1357,30 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) break; case PUBKEY_ALGO_KYBER: - { - char tmpname[15]; + if (get_second) + { + char tmpname[15]; - snprintf (tmpname, sizeof tmpname, "kyber%u", nbits_from_pk (pk)); - err = gcry_sexp_build (&s_pkey, NULL, - "(public-key(%s(p%m)))", - tmpname, pk->pkey[2]); - } + snprintf (tmpname, sizeof tmpname, "kyber%u", nbits_from_pk (pk)); + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(%s(p%m)))", + tmpname, pk->pkey[2]); + } + else + { + char *curve = openpgp_oid_to_str (pk->pkey[0]); + if (!curve) + err = gpg_error_from_syserror (); + else + { + err = gcry_sexp_build (&s_pkey, NULL, + openpgp_oid_is_cv25519 (pk->pkey[0]) + ? "(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))" + : "(public-key(ecc(curve%s)(q%m)))", + curve, pk->pkey[1]); + xfree (curve); + } + } break; default: @@ -1393,26 +1415,45 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) /* Store an allocated buffer with the keygrip of PK encoded as a - hexstring at r_GRIP. Returns 0 on success. */ + * hexstring at r_GRIP. Returns 0 on success. For dual algorithms + * the keygrips are delimited by a comma. */ gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip) { gpg_error_t err; + char *buf; unsigned char grip[KEYGRIP_LEN]; + unsigned char grip2[KEYGRIP_LEN]; *r_grip = NULL; - err = keygrip_from_pk (pk, grip); + err = keygrip_from_pk (pk, grip, 0); if (!err) { - char * buf = xtrymalloc (KEYGRIP_LEN * 2 + 1); - if (!buf) - err = gpg_error_from_syserror (); - else + if (pk->pubkey_algo == PUBKEY_ALGO_KYBER) { - bin2hex (grip, KEYGRIP_LEN, buf); - *r_grip = buf; + err = keygrip_from_pk (pk, grip2, 1); + if (err) + goto leave; + buf = xtrymalloc (2 * KEYGRIP_LEN * 2 + 1 + 1); } + else + buf = xtrymalloc (KEYGRIP_LEN * 2 + 1); + + if (!buf) + { + err = gpg_error_from_syserror (); + goto leave; + } + + bin2hex (grip, KEYGRIP_LEN, buf); + if (pk->pubkey_algo == PUBKEY_ALGO_KYBER) + { + buf[2*KEYGRIP_LEN] = ','; + bin2hex (grip2, KEYGRIP_LEN, buf+2*KEYGRIP_LEN+1); + } + *r_grip = buf; } + leave: return err; } diff --git a/g10/keyring.c b/g10/keyring.c index baddf5d54..0fe8bcd9c 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -1148,7 +1148,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, if (need_keyid) keyid_from_pk (pk, aki); if (need_grip) - keygrip_from_pk (pk, grip); + keygrip_from_pk (pk, grip, 0); if (use_key_present_hash && !key_present_hash_ready diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 6e1b0898e..3e9daa963 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -248,6 +248,8 @@ get_it (ctrl_t ctrl, /* Decrypt. */ desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1); + + /*FIXME: Support dual keys. */ err = agent_pkdecrypt (NULL, keygrip, desc, sk->keyid, sk->main_keyid, sk->pubkey_algo, s_data, &frame, &nframe, &padding); diff --git a/g10/sign.c b/g10/sign.c index e00baf3e7..67ea5a038 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -495,6 +495,7 @@ do_sign (ctrl_t ctrl, PKT_public_key *pksk, PKT_signature *sig, gcry_sexp_t s_sigval; desc = gpg_format_keydesc (ctrl, pksk, FORMAT_KEYDESC_NORMAL, 1); + /* FIXME: Eventually support dual keys. */ err = agent_pksign (NULL/*ctrl*/, cache_nonce, hexgrip, desc, pksk->keyid, pksk->main_keyid, pksk->pubkey_algo, dp, gcry_md_get_algo_dlen (mdalgo), mdalgo, @@ -580,6 +581,7 @@ openpgp_card_v1_p (PKT_public_key *pk) { char *hexgrip; + /* Note: No need to care about dual keys for non-RSA keys. */ err = hexkeygrip_from_pk (pk, &hexgrip); if (err) { From b261478c06f07d92a6a9c003316b09c5716da223 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Apr 2024 14:45:05 +0200 Subject: [PATCH 416/869] agent: Fix error handling of READKEY. * agent/command.c (cmd_readkey): Jump to leave on reading error. -- Fixes-commit: d7a3c455c5e29b19b66772f86dda925064e34896 --- agent/command.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/agent/command.c b/agent/command.c index 575456cc5..40322f385 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1418,7 +1418,9 @@ cmd_readkey (assuan_context_t ctx, char *line) goto leave; rc = agent_public_key_from_file (ctrl, grip, &s_pkey); - if (!rc) + if (rc) + goto leave; + else { if (opt_format_ssh) { From 68d9bc9c35bb65375430c1861514a72fd7d7549a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Apr 2024 14:45:05 +0200 Subject: [PATCH 417/869] agent: Fix error handling of READKEY. * agent/command.c (cmd_readkey): Jump to leave on reading error. -- Fixes-commit: d7a3c455c5e29b19b66772f86dda925064e34896 --- agent/command.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/agent/command.c b/agent/command.c index 2fd9a85d4..b152a5ea4 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1458,7 +1458,9 @@ cmd_readkey (assuan_context_t ctx, char *line) goto leave; rc = agent_public_key_from_file (ctrl, grip, &s_pkey); - if (!rc) + if (rc) + goto leave; + else { if (opt_format_ssh) { From 03d53c88ccf53a282d994fbc9978dba9b51f8ce1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 5 Apr 2024 16:16:53 +0200 Subject: [PATCH 418/869] gpg: Allow to create a Kyber key from keygrips. * agent/cvt-openpgp.c (extract_private_key): Support Kyber algorithms. * common/openpgp-oid.c (map_gcry_pk_to_openpgp): Map KEM to Kyber. * common/sexputil.c (get_pk_algo_from_key): Increase buffer for use with "kyber1024". * g10/call-agent.c (agent_get_keyinfo): Fix warning. * g10/keygen.c (do_create_from_keygrip): Support Kyber. (ask_algo): Ditto. -- To test create a standard key and the use --edit-key and "addkey" with selection 13 and use the comma delimited keygrips. GnuPG-bug-id: 7014 --- agent/cvt-openpgp.c | 11 ++++++ agent/divert-scd.c | 2 +- common/openpgp-oid.c | 1 + common/sexputil.c | 2 +- g10/call-agent.c | 2 +- g10/keygen.c | 92 +++++++++++++++++++++++++++++++++++++++----- 6 files changed, 97 insertions(+), 13 deletions(-) diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 50755c0fd..420dbb464 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -1384,6 +1384,17 @@ extract_private_key (gcry_sexp_t s_key, int req_private_key_data, err = gcry_sexp_extract_param (list, NULL, format, array+0, array+1, NULL); } + else if ( !strcmp (name, (algoname = "kyber512")) + || !strcmp (name, (algoname = "kyber768")) + || !strcmp (name, (algoname = "kyber1024"))) + { + format = "/ps?"; + elems = "ps?"; + npkey = 1; + nskey = 2; + err = gcry_sexp_extract_param (list, NULL, format, + array+0, array+1, NULL); + } else { err = gpg_error (GPG_ERR_PUBKEY_ALGO); diff --git a/agent/divert-scd.c b/agent/divert-scd.c index ed0173ea1..4a2bebffa 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -377,7 +377,7 @@ divert_pksign (ctrl_t ctrl, const unsigned char *grip, } -/* Decrypt the value given asn an S-expression in CIPHER using the +/* Decrypt the value given as an s-expression in CIPHER using the key identified by SHADOW_INFO and return the plaintext in an allocated buffer in R_BUF. The padding information is stored at R_PADDING with -1 for not known. */ diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index ceb211dd3..bc82cc6b0 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -623,6 +623,7 @@ map_gcry_pk_to_openpgp (enum gcry_pk_algos algo) case GCRY_PK_EDDSA: return PUBKEY_ALGO_EDDSA; case GCRY_PK_ECDSA: return PUBKEY_ALGO_ECDSA; case GCRY_PK_ECDH: return PUBKEY_ALGO_ECDH; + case GCRY_PK_KEM: return PUBKEY_ALGO_KYBER; default: return algo < 110 ? (pubkey_algo_t)algo : 0; } } diff --git a/common/sexputil.c b/common/sexputil.c index c7471be85..e6fc84da0 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -992,7 +992,7 @@ get_pk_algo_from_key (gcry_sexp_t key) gcry_sexp_t list; const char *s; size_t n; - char algoname[6]; + char algoname[10]; int algo = 0; list = gcry_sexp_nth (key, 1); diff --git a/g10/call-agent.c b/g10/call-agent.c index e7046f7b2..a49c987fa 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -2469,7 +2469,7 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, gpg_error_t err; char line[ASSUAN_LINELENGTH]; struct keyinfo_data_parm_s keyinfo; - char *s; + const char *s; memset (&keyinfo, 0,sizeof keyinfo); diff --git a/g10/keygen.c b/g10/keygen.c index 6426f7e4f..c2acf74c3 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1,7 +1,7 @@ /* keygen.c - Generate a key pair * Copyright (C) 1998-2007, 2009-2011 Free Software Foundation, Inc. * Copyright (C) 2014, 2015, 2016, 2017, 2018 Werner Koch - * Copyright (C) 2020 g10 Code GmbH + * Copyright (C) 2020, 2024 g10 Code GmbH * * This file is part of GnuPG. * @@ -1501,10 +1501,24 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, PACKET *pkt; PKT_public_key *pk; gcry_sexp_t s_key; + gcry_sexp_t s_key2 = NULL; const char *algoelem; + char *hexkeygrip_buffer = NULL; + char *hexkeygrip2 = NULL; if (hexkeygrip[0] == '&') hexkeygrip++; + if (strchr (hexkeygrip, ',')) + { + hexkeygrip_buffer = xtrystrdup (hexkeygrip); + if (!hexkeygrip_buffer) + return gpg_error_from_syserror (); + hexkeygrip = hexkeygrip_buffer; + hexkeygrip2 = strchr (hexkeygrip_buffer, ','); + if (hexkeygrip2) + *hexkeygrip2++ = 0; + } + switch (algo) { @@ -1514,16 +1528,21 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, case PUBKEY_ALGO_ECDH: case PUBKEY_ALGO_ECDSA: algoelem = ""; break; case PUBKEY_ALGO_EDDSA: algoelem = ""; break; - default: return gpg_error (GPG_ERR_INTERNAL); + case PUBKEY_ALGO_KYBER: algoelem = ""; break; + default: + xfree (hexkeygrip_buffer); + return gpg_error (GPG_ERR_INTERNAL); } - /* Ask the agent for the public key matching HEXKEYGRIP. */ if (cardkey) { err = agent_scd_readkey (ctrl, hexkeygrip, &s_key, NULL); if (err) - return err; + { + xfree (hexkeygrip_buffer); + return err; + } } else { @@ -1531,16 +1550,41 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, err = agent_readkey (ctrl, 0, hexkeygrip, &public); if (err) - return err; + { + xfree (hexkeygrip_buffer); + return err; + } err = gcry_sexp_sscan (&s_key, NULL, public, gcry_sexp_canon_len (public, 0, NULL, NULL)); xfree (public); if (err) - return err; + { + xfree (hexkeygrip_buffer); + return err; + } + if (hexkeygrip2) + { + err = agent_readkey (ctrl, 0, hexkeygrip2, &public); + if (err) + { + gcry_sexp_release (s_key); + xfree (hexkeygrip_buffer); + return err; + } + err = gcry_sexp_sscan (&s_key2, NULL, public, + gcry_sexp_canon_len (public, 0, NULL, NULL)); + xfree (public); + if (err) + { + gcry_sexp_release (s_key); + xfree (hexkeygrip_buffer); + return err; + } + } } - /* For X448 we force the use of v5 packets. */ - if (curve_is_448 (s_key)) + /* For X448 and Kyber we force the use of v5 packets. */ + if (curve_is_448 (s_key) || algo == PUBKEY_ALGO_KYBER) *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; /* Build a public key packet. */ @@ -1549,6 +1593,8 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, { err = gpg_error_from_syserror (); gcry_sexp_release (s_key); + gcry_sexp_release (s_key2); + xfree (hexkeygrip_buffer); return err; } @@ -1558,7 +1604,9 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; - if (algo == PUBKEY_ALGO_ECDSA + if (algo == PUBKEY_ALGO_KYBER) + err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo); + else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH ) err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo); @@ -1568,16 +1616,20 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, { log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) ); gcry_sexp_release (s_key); + gcry_sexp_release (s_key2); free_public_key (pk); + xfree (hexkeygrip_buffer); return err; } gcry_sexp_release (s_key); + gcry_sexp_release (s_key2); pkt = xtrycalloc (1, sizeof *pkt); if (!pkt) { err = gpg_error_from_syserror (); free_public_key (pk); + xfree (hexkeygrip_buffer); return err; } @@ -1585,6 +1637,7 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, pkt->pkt.public_key = pk; add_kbnode (pub_root, new_kbnode (pkt)); + xfree (hexkeygrip_buffer); return 0; } @@ -2479,7 +2532,26 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage, continue; } - if (strlen (answer) != 40 && + if (strlen (answer) == 40+1+40 && answer[40]==',') + { + int algo1, algo2; + + answer[40] = 0; + algo1 = check_keygrip (ctrl, answer); + algo2 = check_keygrip (ctrl, answer+41); + answer[40] = ','; + if (algo1 == PUBKEY_ALGO_ECDH && algo2 == PUBKEY_ALGO_KYBER) + { + algo = PUBKEY_ALGO_KYBER; + break; + } + else if (!algo1 || !algo2) + tty_printf (_("No key with this keygrip\n")); + else + tty_printf ("Invalid combination for dual algo (%d,%d)\n", + algo1, algo2); + } + else if (strlen (answer) != 40 && !(answer[0] == '&' && strlen (answer+1) == 40)) tty_printf (_("Not a valid keygrip (expecting 40 hex digits)\n")); From c5d7a332c8401e24263f0e235824f5862e37433a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 4 Apr 2024 16:39:14 +0200 Subject: [PATCH 419/869] gpg: Do not allow to accidently set the RENC usage. * g10/keygen.c (print_key_flags): Print "RENC" if set. (ask_key_flags_with_mask): Remove RENC from the possible set of usages. Add a direct way to set it iff the key is encryption capable. -- This could be done by using "set your own capabilities" for an RSA key. In fact it was always set in this case. GnuPG-bug-id: 7072 --- g10/keygen.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/g10/keygen.c b/g10/keygen.c index c2acf74c3..763d23ee4 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -2177,6 +2177,9 @@ print_key_flags(int flags) if(flags&PUBKEY_USAGE_AUTH) tty_printf("%s ",_("Authenticate")); + + if(flags&PUBKEY_USAGE_RENC) + tty_printf("%s ", "RENC"); } @@ -2209,10 +2212,14 @@ ask_key_flags_with_mask (int algo, int subkey, unsigned int current, togglers = "11223300"; } + /* restrict the mask to the actual useful bits. */ + /* Mask the possible usage flags. This is for example used for a * card based key. For ECDH we need to allows additional usages if - * they are provided. */ + * they are provided. RENC is not directly poissible here but see + * below for a workaround. */ possible = (openpgp_pk_algo_usage (algo) & mask); + possible &= ~PUBKEY_USAGE_RENC; if (algo == PUBKEY_ALGO_ECDH) possible |= (current & (PUBKEY_USAGE_ENC |PUBKEY_USAGE_CERT @@ -2281,6 +2288,12 @@ ask_key_flags_with_mask (int algo, int subkey, unsigned int current, want to experiment with a cert-only primary key. */ current |= PUBKEY_USAGE_CERT; } + else if ((*s == 'r' || *s == 'R') && (possible&PUBKEY_USAGE_ENC)) + { + /* Allow to set RENC or an encryption capable key. + * This is on purpose not shown in the menu. */ + current |= PUBKEY_USAGE_RENC; + } } break; } From f7a26aa8adc3b6e0350a53e0bd4c2dfb3d4b03c4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 8 Apr 2024 20:32:47 +0200 Subject: [PATCH 420/869] kbx: Fix keyid search for mixed v4/v5 case. * kbx/keybox-search.c (blob_cmp_fpr_part): Reworked. (has_short_kid, has_long_kid): Simplify. -- The old code was too complicated and did not cope correctly a blob having a mix of v5 and v4 keys. Fixes-commit: 01329da8a778d3b0d121c83bfb61d99a39cccac4 GnuPG-bug-id: 5888 --- kbx/keybox-search.c | 53 +++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index 31ea0ba60..303c19b79 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -279,7 +279,8 @@ blob_cmp_fpr (KEYBOXBLOB blob, const unsigned char *fpr, unsigned int fprlen) } -/* Helper for has_short_kid and has_long_kid. */ +/* Helper for has_short_kid and has_long_kid. This function is called + * with FPROFF 12 and FPRLEN 4 or with FPROFF 12 and FPRLEN 8. */ static int blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, int fproff, int fprlen) @@ -288,7 +289,8 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, size_t length; size_t pos, off; size_t nkeys, keyinfolen; - int idx, fpr32, storedfprlen; + int idx; + int fpr32; /* Set if this blob stores all fingerprints as 32 bytes. */ buffer = _keybox_get_blob_image (blob, &length); if (length < 40) @@ -307,13 +309,24 @@ blob_cmp_fpr_part (KEYBOXBLOB blob, const unsigned char *fpr, for (idx=0; idx < nkeys; idx++) { off = pos + idx*keyinfolen; - if (fpr32) - storedfprlen = (get16 (buffer + off + 32) & 0x80)? 32:20; + if (!fpr32) + { + /* Blob has only 20 fingerprints - use the FPROFF. */ + if (!memcmp (buffer + off + fproff, fpr, fprlen)) + return idx+1; /* found */ + } + else if ((buffer[off + 32 + 1] & 0x80)) + { + /* This (sub)key has a 32 byte fpr -> use 0 as offset. */ + if (!memcmp (buffer + off, fpr, fprlen)) + return idx+1; /* found */ + } else - storedfprlen = 20; - if ((fpr32 || storedfprlen == fproff + fprlen) - && !memcmp (buffer + off + fproff, fpr, fprlen)) - return idx+1; /* found */ + { + /* This (sub)key has a 20 byte fpr -> use the FPROFF */ + if (!memcmp (buffer + off + fproff, fpr, fprlen)) + return idx+1; /* found */ + } } return 0; /* not found */ } @@ -683,43 +696,30 @@ blob_x509_has_grip (KEYBOXBLOB blob, const unsigned char *grip) static inline int has_short_kid (KEYBOXBLOB blob, u32 lkid) { - const unsigned char *buffer; size_t length; - int fpr32; unsigned char buf[4]; - buffer = _keybox_get_blob_image (blob, &length); + _keybox_get_blob_image (blob, &length); if (length < 48) return 0; /* blob too short */ - fpr32 = buffer[5] == 2; - if (fpr32 && length < 56) - return 0; /* blob to short */ buf[0] = lkid >> 24; buf[1] = lkid >> 16; buf[2] = lkid >> 8; buf[3] = lkid; - if (fpr32 && (get16 (buffer + 20 + 32) & 0x80)) - return blob_cmp_fpr_part (blob, buf, 0, 4); - else - return blob_cmp_fpr_part (blob, buf, 16, 4); + return blob_cmp_fpr_part (blob, buf, 16, 4); } static inline int has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid) { - const unsigned char *buffer; size_t length; - int fpr32; unsigned char buf[8]; - buffer = _keybox_get_blob_image (blob, &length); + _keybox_get_blob_image (blob, &length); if (length < 48) return 0; /* blob too short */ - fpr32 = buffer[5] == 2; - if (fpr32 && length < 56) - return 0; /* blob to short */ buf[0] = mkid >> 24; buf[1] = mkid >> 16; @@ -730,10 +730,7 @@ has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid) buf[6] = lkid >> 8; buf[7] = lkid; - if (fpr32 && (get16 (buffer + 20 + 32) & 0x80)) - return blob_cmp_fpr_part (blob, buf, 0, 8); - else - return blob_cmp_fpr_part (blob, buf, 12, 8); + return blob_cmp_fpr_part (blob, buf, 12, 8); } static inline int From 3a344d6236521d768793e8b34a96a18ce13bab0e Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 9 Apr 2024 09:24:11 +0900 Subject: [PATCH 421/869] gpg: Allow no CRC24 checksum in armor. * g10/armor.c (radix64_read): Detect the end of armor when there is no CRC24 checksum. -- GnuPG-bug-id: 7071 Signed-off-by: NIIBE Yutaka --- g10/armor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g10/armor.c b/g10/armor.c index b47c04ab3..81af15339 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1031,10 +1031,10 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, checkcrc++; break; } - else if (afx->dearmor_state && c == '-' + else if (c == '-' && afx->buffer_pos + 8 < afx->buffer_len && !strncmp (afx->buffer, "-----END ", 8)) { - break; /* End in --dearmor mode. */ + break; /* End in --dearmor mode or No CRC. */ } else { log_error(_("invalid radix64 character %02X skipped\n"), c); From 1a37f0080b3e366f5de929b1c01c419eb9cf4ebb Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Apr 2024 10:54:34 +0200 Subject: [PATCH 422/869] kbx: Support kyber in the blob parser. * kbx/keybox-openpgp.c (keygrip_from_keyparm): Support Kyber. (parse_key): Ditto. -- GnuPG-bug-id: 6815 --- kbx/keybox-blob.c | 2 +- kbx/keybox-openpgp.c | 46 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 2564d1f48..7d0670d9f 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -96,7 +96,7 @@ bit 0 = qualified signature (not yet implemented} bit 7 = 32 byte fingerprint in use. - u16 RFU - - b20 keygrip + - b20 keygrip FIXME: Support a second grip. - bN Optional filler up to the specified length of this structure. - u16 Size of the serial number (may be zero) diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c index f5bd1b641..c91885b32 100644 --- a/kbx/keybox-openpgp.c +++ b/kbx/keybox-openpgp.c @@ -233,6 +233,26 @@ keygrip_from_keyparm (int algo, struct keyparm_s *kp, unsigned char *grip) } break; + case PUBKEY_ALGO_KYBER: + /* There is no space in the BLOB for a second grip, thus for now + * we store only the ECC keygrip. */ + { + char *curve = openpgp_oidbuf_to_str (kp[0].mpi, kp[0].len); + if (!curve) + err = gpg_error_from_syserror (); + else + { + err = gcry_sexp_build + (&s_pkey, NULL, + openpgp_oidbuf_is_cv25519 (kp[0].mpi, kp[0].len) + ?"(public-key(ecc(curve%s)(flags djb-tweak)(q%b)))" + : "(public-key(ecc(curve%s)(q%b)))", + curve, kp[1].len, kp[1].mpi); + xfree (curve); + } + } + break; + default: err = gpg_error (GPG_ERR_PUBKEY_ALGO); break; @@ -273,6 +293,7 @@ parse_key (const unsigned char *data, size_t datalen, unsigned char hashbuffer[768]; gcry_md_hd_t md; int is_ecc = 0; + int is_kyber = 0; int is_v5; /* unsigned int pkbytes; for v5: # of octets of the public key params. */ struct keyparm_s keyparm[OPENPGP_MAX_NPKEY]; @@ -331,6 +352,10 @@ parse_key (const unsigned char *data, size_t datalen, npkey = 2; is_ecc = 1; break; + case PUBKEY_ALGO_KYBER: + npkey = 3; + is_kyber = 1; + break; default: /* Unknown algorithm. */ return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM); } @@ -345,7 +370,8 @@ parse_key (const unsigned char *data, size_t datalen, if (datalen < 2) return gpg_error (GPG_ERR_INV_PACKET); - if (is_ecc && (i == 0 || i == 2)) + if ((is_ecc && (i == 0 || i == 2)) + || (is_kyber && i == 0 )) { nbytes = data[0]; if (nbytes < 2 || nbytes > 254) @@ -354,6 +380,20 @@ parse_key (const unsigned char *data, size_t datalen, if (datalen < nbytes) return gpg_error (GPG_ERR_INV_PACKET); + keyparm[i].mpi = data; + keyparm[i].len = nbytes; + } + else if (is_kyber && i == 2) + { + if (datalen < 4) + return gpg_error (GPG_ERR_INV_PACKET); + nbytes = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3])); + data += 4; + datalen -= 4; + /* (for the limit see also MAX_EXTERN_MPI_BITS in g10/gpg.h) */ + if (datalen < nbytes || nbytes > (32768*8)) + return gpg_error (GPG_ERR_INV_PACKET); + keyparm[i].mpi = data; keyparm[i].len = nbytes; } @@ -378,7 +418,7 @@ parse_key (const unsigned char *data, size_t datalen, /* Note: Starting here we need to jump to leave on error. */ /* For non-ECC, make sure the MPIs are unsigned. */ - if (!is_ecc) + if (!is_ecc && !is_kyber) for (i=0; i < npkey; i++) { if (!keyparm[i].len || (keyparm[i].mpi[0] & 0x80)) @@ -438,7 +478,7 @@ parse_key (const unsigned char *data, size_t datalen, */ if (version == 5) { - if ( 5 + n < sizeof hashbuffer ) + if (5 + n < sizeof hashbuffer ) { hashbuffer[0] = 0x9a; /* CTB */ hashbuffer[1] = (n >> 24);/* 4 byte length header. */ From 52c4b0908043993e266b7d0e3fbf567076f8262d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Apr 2024 11:00:35 +0200 Subject: [PATCH 423/869] gpg: Some support to allow Kyber decryption. * g10/call-agent.c (agent_pkdecrypt): Support dual keygrips and switch to KEM mode. * g10/ecdh.c (pk_ecdh_decrypt): Add an extra length check. * g10/keyid.c (do_hash_public_key): Fix Kyber fingerprint computation. * g10/mainproc.c (release_list): Free all 4 data elements. (proc_pubkey_enc): Copy all 4 data elements. * g10/misc.c (openpgp_pk_test_algo2): Map Kyber to KEM. * g10/parse-packet.c (parse_pubkeyenc): Fix Kyber parser. * g10/pubkey-enc.c (get_session_key): Allow Kyber. (get_it): Support Kyber. -- GnuPG-bug-id: 6815 --- g10/call-agent.c | 31 +++++++++++++++++++++++++++---- g10/ecdh.c | 2 +- g10/keyid.c | 17 ++++++++++++----- g10/mainproc.c | 6 +++++- g10/misc.c | 2 ++ g10/parse-packet.c | 12 +++++++++--- g10/pubkey-enc.c | 12 +++++++++++- 7 files changed, 67 insertions(+), 15 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index a49c987fa..31943d7df 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -2878,6 +2878,7 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, membuf_t data; size_t n, len; char *p, *buf, *endp; + const char *keygrip2 = NULL; struct default_inq_parm_s dfltparm; memset (&dfltparm, 0, sizeof dfltparm); @@ -2886,13 +2887,26 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, dfltparm.keyinfo.mainkeyid = mainkeyid; dfltparm.keyinfo.pubkey_algo = pubkey_algo; - if (!keygrip || strlen(keygrip) != 40 - || !s_ciphertext || !r_buf || !r_buflen || !r_padding) + if (!keygrip || !s_ciphertext || !r_buf || !r_buflen || !r_padding) return gpg_error (GPG_ERR_INV_VALUE); *r_buf = NULL; *r_padding = -1; + /* Parse the keygrip in case of a dual algo. */ + keygrip2 = strchr (keygrip, ','); + if (!keygrip2) + keygrip2 = keygrip + strlen (keygrip); + if (keygrip2 - keygrip != 40) + return gpg_error (GPG_ERR_INV_VALUE); + if (*keygrip2) + { + keygrip2++; + if (strlen (keygrip2) != 40) + return gpg_error (GPG_ERR_INV_VALUE); + } + + err = start_agent (ctrl, 0); if (err) return err; @@ -2903,11 +2917,19 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, if (err) return err; - snprintf (line, sizeof line, "SETKEY %s", keygrip); + snprintf (line, sizeof line, "SETKEY %.40s", keygrip); err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); if (err) return err; + if (*keygrip2) + { + snprintf (line, sizeof line, "SETKEY --another %.40s", keygrip2); + err = assuan_transact (agent_ctx, line, NULL, NULL,NULL,NULL,NULL,NULL); + if (err) + return err; + } + if (desc) { snprintf (line, DIM(line), "SETKEYDESC %s", desc); @@ -2926,7 +2948,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, err = make_canon_sexp (s_ciphertext, &parm.ciphertext, &parm.ciphertextlen); if (err) return err; - err = assuan_transact (agent_ctx, "PKDECRYPT", + err = assuan_transact (agent_ctx, + *keygrip2? "PKDECRYPT --kem=PQC-PGP":"PKDECRYPT", put_membuf_cb, &data, inq_ciphertext_cb, &parm, padding_info_cb, r_padding); diff --git a/g10/ecdh.c b/g10/ecdh.c index 4938e419d..279508bec 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -537,7 +537,7 @@ pk_ecdh_decrypt (gcry_mpi_t *r_result, const byte sk_fp[MAX_FINGERPRINT_LEN], nbytes = (nbits+7)/8; data_buf_size = nbytes; - if ((data_buf_size & 7) != 1) + if ((data_buf_size & 7) != 1 || data_buf_size <= 1 + 8) { log_error ("can't use a shared secret of %d bytes for ecdh\n", data_buf_size); diff --git a/g10/keyid.c b/g10/keyid.c index 09940cbfe..08f684829 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -336,17 +336,24 @@ do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5) { /* Ugly: We need to re-construct the wire format of the * key parameter. It would be easier to use a second - * second index for pp and nn which could bump - * independet of i. */ + * index for pp and nn which we could bump independet of + * i. */ const char *p; p = gcry_mpi_get_opaque (pk->pkey[i], &nbits); - pp[i] = xmalloc ((nbits+7)/8 + 1); + nn[i] = (nbits+7)/8; + pp[i] = xmalloc (4 + nn[i] + 1); if (p) - memcpy (pp[i], p, (nbits+7)/8); + { + pp[i][0] = nn[i] >> 24; + pp[i][1] = nn[i] >> 16; + pp[i][2] = nn[i] >> 8; + pp[i][3] = nn[i]; + memcpy (pp[i] + 4 , p, nn[i]); + nn[i] += 4; + } else pp[i] = NULL; - nn[i] = (nbits+7)/8; n += nn[i]; } else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)) diff --git a/g10/mainproc.c b/g10/mainproc.c index d2e00514f..6f3254e88 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -143,6 +143,8 @@ release_list( CTX c ) mpi_release (c->pkenc_list->data[0]); mpi_release (c->pkenc_list->data[1]); + mpi_release (c->pkenc_list->data[2]); + mpi_release (c->pkenc_list->data[3]); xfree (c->pkenc_list); c->pkenc_list = tmp; } @@ -527,11 +529,13 @@ proc_pubkey_enc (CTX c, PACKET *pkt) x->keyid[1] = enc->keyid[1]; x->pubkey_algo = enc->pubkey_algo; x->result = -1; - x->data[0] = x->data[1] = NULL; + x->data[0] = x->data[1] = x->data[2] = x->data[3] = NULL; if (enc->data[0]) { x->data[0] = mpi_copy (enc->data[0]); x->data[1] = mpi_copy (enc->data[1]); + x->data[2] = mpi_copy (enc->data[2]); + x->data[3] = mpi_copy (enc->data[3]); } x->next = c->pkenc_list; c->pkenc_list = x; diff --git a/g10/misc.c b/g10/misc.c index 432fe1760..ce0c04b3b 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -750,6 +750,8 @@ openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use) ga = GCRY_PK_ELG; break; + case PUBKEY_ALGO_KYBER: ga = GCRY_PK_KEM; break; + default: break; } diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 2163787cb..c55bb1b71 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1444,6 +1444,7 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } +/* Parse a public key encrypted packet (Tag 1). */ static int parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, PACKET * packet) @@ -1514,9 +1515,14 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, { log_assert (ndata == 4); /* Get the ephemeral public key. */ - rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 0); - if (rc) - goto leave; + n = pktlen; + k->data[0] = sos_read (inp, &n, 0); + pktlen -= n; + if (!k->data[0]) + { + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } /* Get the Kyber ciphertext. */ rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 1); if (rc) diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 3e9daa963..873b864b5 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -117,6 +117,7 @@ get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek) { if (!(k->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E || k->pubkey_algo == PUBKEY_ALGO_ECDH + || k->pubkey_algo == PUBKEY_ALGO_KYBER || k->pubkey_algo == PUBKEY_ALGO_RSA || k->pubkey_algo == PUBKEY_ALGO_RSA_E || k->pubkey_algo == PUBKEY_ALGO_ELGAMAL)) @@ -237,6 +238,16 @@ get_it (ctrl_t ctrl, err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))", enc->data[1], enc->data[0]); } + else if (sk->pubkey_algo == PUBKEY_ALGO_KYBER) + { + if (!enc->data[0] || !enc->data[1] || !enc->data[2] || !enc->data[3]) + err = gpg_error (GPG_ERR_BAD_MPI); + else + err = gcry_sexp_build (&s_data, NULL, + "(enc-val(pqc(e%m)(k%m)(s%m)(fixed-info%s)))", + enc->data[0], enc->data[1], enc->data[3], + "\x1d" /*PUBKEY_ALGO_KYBER*/); + } else err = gpg_error (GPG_ERR_BUG); @@ -249,7 +260,6 @@ get_it (ctrl_t ctrl, /* Decrypt. */ desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1); - /*FIXME: Support dual keys. */ err = agent_pkdecrypt (NULL, keygrip, desc, sk->keyid, sk->main_keyid, sk->pubkey_algo, s_data, &frame, &nframe, &padding); From 04b81ec236cf66987a77e0aaafd9f2363daac60c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 10 Apr 2024 11:09:29 +0900 Subject: [PATCH 424/869] common,agent: Factor out KEM functions into common/kem.c. * common/util.h (compute_kmac256): Remove. (gnupg_ecc_kem_kdf, gnupg_kem_combiner): New. * common/kmac.c (compute_kmac256): Don't expose. (gnupg_ecc_kem_kdf, gnupg_kem_combiner): New. * agent/pkdecrypt.c (agent_hybrid_pgp_kem_decrypt): Use gnupg_ecc_kem_kdf and gnupg_kem_combiner. -- Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 95 +++++++++++++++++++++-------------------------- common/kmac.c | 77 +++++++++++++++++++++++++++++++++++++- common/util.h | 17 ++++++--- 3 files changed, 130 insertions(+), 59 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index e93ac0a26..3848bcefc 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -198,30 +198,28 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *p; size_t len; - gcry_mpi_t encrypted_sessionkey_mpi; + gcry_mpi_t encrypted_sessionkey_mpi = NULL; const unsigned char *encrypted_sessionkey; size_t encrypted_sessionkey_len; - gcry_mpi_t ecc_sk_mpi; + gcry_mpi_t ecc_sk_mpi = NULL; unsigned char ecc_sk[32]; - gcry_mpi_t ecc_pk_mpi; + gcry_mpi_t ecc_pk_mpi = NULL; unsigned char ecc_pk[32]; - gcry_mpi_t ecc_ct_mpi; + gcry_mpi_t ecc_ct_mpi = NULL; const unsigned char *ecc_ct; size_t ecc_ct_len; unsigned char ecc_ecdh[32]; unsigned char ecc_ss[32]; - gcry_mpi_t mlkem_sk_mpi; - gcry_mpi_t mlkem_ct_mpi; + gcry_mpi_t mlkem_sk_mpi = NULL; + gcry_mpi_t mlkem_ct_mpi = NULL; const unsigned char *mlkem_sk; const unsigned char *mlkem_ct; unsigned char mlkem_ss[GCRY_KEM_MLKEM768_SHARED_LEN]; - gcry_buffer_t iov[6]; - - unsigned char kekkey[32]; - size_t kekkeylen = 32; /* AES-256 is mandatory */ + unsigned char kek[32]; + size_t kek_len = 32; /* AES-256 is mandatory */ gcry_cipher_hd_t hd; unsigned char sessionkey[256]; @@ -290,6 +288,8 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, reverse_buffer (ecc_sk, 32); mpi_release (ecc_pk_mpi); mpi_release (ecc_sk_mpi); + ecc_pk_mpi = NULL; + ecc_sk_mpi = NULL; ecc_ct = gcry_mpi_get_opaque (ecc_ct_mpi, &nbits); ecc_ct_len = (nbits+7)/8; @@ -302,16 +302,14 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, err = gcry_kem_decap (GCRY_KEM_RAW_X25519, ecc_sk, 32, ecc_ct, ecc_ct_len, ecc_ecdh, 32, NULL, 0); - iov[0].data = ecc_ecdh; - iov[0].off = 0; - iov[0].len = 32; - iov[1].data = (unsigned char *)ecc_ct; - iov[1].off = 0; - iov[1].len = 32; - iov[2].data = ecc_pk; - iov[2].off = 0; - iov[2].len = 32; - gcry_md_hash_buffers (GCRY_MD_SHA3_256, 0, ecc_ss, iov, 3); + if (err) + goto leave; + + err = gnupg_ecc_kem_kdf (ecc_ss, 32, GCRY_MD_SHA3_256, + ecc_ecdh, 32, ecc_ct, 32, ecc_pk, 32); + + if (err) + goto leave; /* Secondly, PQC part. For now, we assume ML-KEM. */ gcry_sexp_extract_param (s_skey1, NULL, "/s", &mlkem_sk_mpi, NULL); @@ -334,45 +332,32 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, mlkem_ct, GCRY_KEM_MLKEM768_CIPHER_LEN, mlkem_ss, GCRY_KEM_MLKEM768_SHARED_LEN, NULL, 0); + if (err) + goto leave; mpi_release (mlkem_sk_mpi); + mlkem_sk_mpi = NULL; - /* Then, combine two shared secrets into one */ - - iov[0].data = "\x00\x00\x00\x01"; /* Counter */ - iov[0].off = 0; - iov[0].len = 4; - - iov[1].data = ecc_ss; - iov[1].off = 0; - iov[1].len = 32; - - iov[2].data = (unsigned char *)ecc_ct; - iov[2].off = 0; - iov[2].len = 32; - - iov[3].data = mlkem_ss; - iov[3].off = 0; - iov[3].len = GCRY_KEM_MLKEM768_SHARED_LEN; - - iov[4].data = (unsigned char *)mlkem_ct; - iov[4].off = 0; - iov[4].len = GCRY_KEM_MLKEM768_ENCAPS_LEN; - - iov[5].data = (unsigned char *)fixedinfo; - iov[5].off = 0; - iov[5].len = 1; - - err = compute_kmac256 (kekkey, kekkeylen, - "OpenPGPCompositeKeyDerivationFunction", 37, - "KDF", 3, iov, 6); + /* Then, combine two shared secrets and ciphertexts into one KEK */ + err = gnupg_kem_combiner (kek, kek_len, + ecc_ss, 32, ecc_ct, 32, + mlkem_ss, GCRY_KEM_MLKEM768_SHARED_LEN, + mlkem_ct, GCRY_KEM_MLKEM768_CIPHER_LEN, + fixedinfo, 1); + if (err) + { + log_error ("KEM combiner failed: %s\n", gpg_strerror (err)); + goto leave; + } mpi_release (ecc_ct_mpi); mpi_release (mlkem_ct_mpi); + ecc_ct_mpi = NULL; + mlkem_ct_mpi = NULL; if (DBG_CRYPTO) { - log_printhex (kekkey, kekkeylen, "KEK key: "); + log_printhex (kek, kek_len, "KEK key: "); } err = gcry_cipher_open (&hd, GCRY_CIPHER_AES256, @@ -381,11 +366,10 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, { log_error ("ecdh failed to initialize AESWRAP: %s\n", gpg_strerror (err)); - mpi_release (encrypted_sessionkey_mpi); goto leave; } - err = gcry_cipher_setkey (hd, kekkey, kekkeylen); + err = gcry_cipher_setkey (hd, kek, kek_len); sessionkey_len = encrypted_sessionkey_len - 8; err = gcry_cipher_decrypt (hd, sessionkey, sessionkey_len, @@ -393,6 +377,7 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_cipher_close (hd); mpi_release (encrypted_sessionkey_mpi); + encrypted_sessionkey_mpi = NULL; if (err) { @@ -406,6 +391,12 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, put_membuf (outbuf, ")", 2); leave: + mpi_release (mlkem_sk_mpi); + mpi_release (ecc_pk_mpi); + mpi_release (ecc_sk_mpi); + mpi_release (ecc_ct_mpi); + mpi_release (mlkem_ct_mpi); + mpi_release (encrypted_sessionkey_mpi); gcry_sexp_release (s_skey0); gcry_sexp_release (s_skey1); return err; diff --git a/common/kmac.c b/common/kmac.c index 69e18a2c3..c5de8b102 100644 --- a/common/kmac.c +++ b/common/kmac.c @@ -1,4 +1,4 @@ -/* kmac.c - Keccak based MAC +/* kem.c - KEM helper functions * Copyright (C) 2024 g10 Code GmbH. * * This file is part of GnuPG. @@ -36,7 +36,7 @@ #include "mischelp.h" #define KECCAK512_BLOCKSIZE 136 -gpg_error_t +static gpg_error_t compute_kmac256 (void *digest, size_t digestlen, const void *key, size_t keylen, const void *custom, size_t customlen, @@ -134,3 +134,76 @@ compute_kmac256 (void *digest, size_t digestlen, return gpg_error (GPG_ERR_NOT_IMPLEMENTED); #endif } + +/* Compute KEK (shared secret) for ECC with HASHALGO, ECDH result, + ciphertext in ECC_CT, public key in ECC_PK. */ +gpg_error_t +gnupg_ecc_kem_kdf (void *kek, size_t kek_len, + int hashalgo, const void *ecdh, size_t ecdh_len, + const void *ecc_ct, size_t ecc_ct_len, + const void *ecc_pk, size_t ecc_pk_len) +{ + gcry_buffer_t iov[3]; + unsigned int dlen; + + dlen = gcry_md_get_algo_dlen (hashalgo); + if (kek_len != dlen) + return gpg_error (GPG_ERR_INV_LENGTH); + + memset (iov, 0, sizeof (iov)); + + iov[0].data = (unsigned char *)ecdh; + iov[0].len = ecdh_len; + iov[1].data = (unsigned char *)ecc_ct; + iov[1].len = ecc_ct_len; + iov[2].data = (unsigned char *)ecc_pk; + iov[2].len = ecc_pk_len; + gcry_md_hash_buffers (hashalgo, 0, kek, iov, 3); + + return 0; +} + + +/* domSeperation */ +#define KMAC_KEY "OpenPGPCompositeKeyDerivationFunction" + +/* customizationString */ +#define KMAC_CUSTOM "KDF" + +/* Compute KEK by combining two KEMs. */ +gpg_error_t +gnupg_kem_combiner (void *kek, size_t kek_len, + const void *ecc_ss, size_t ecc_ss_len, + const void *ecc_ct, size_t ecc_ct_len, + const void *mlkem_ss, size_t mlkem_ss_len, + const void *mlkem_ct, size_t mlkem_ct_len, + const void *fixedinfo, size_t fixedinfo_len) +{ + gpg_error_t err; + gcry_buffer_t iov[6]; + + memset (iov, 0, sizeof (iov)); + + iov[0].data = "\x00\x00\x00\x01"; /* Counter */ + iov[0].len = 4; + + iov[1].data = (unsigned char *)ecc_ss; + iov[1].len = ecc_ss_len; + + iov[2].data = (unsigned char *)ecc_ct; + iov[2].len = ecc_ct_len; + + iov[3].data = (unsigned char *)mlkem_ss; + iov[3].len = mlkem_ss_len; + + iov[4].data = (unsigned char *)mlkem_ct; + iov[4].len = mlkem_ct_len; + + iov[5].data = (unsigned char *)fixedinfo; + iov[5].len = fixedinfo_len; + + err = compute_kmac256 (kek, kek_len, + KMAC_KEY, strlen (KMAC_KEY), + KMAC_CUSTOM, strlen (KMAC_CUSTOM), iov, 6); + return err; +} diff --git a/common/util.h b/common/util.h index 7b2601db1..5c953a8a1 100644 --- a/common/util.h +++ b/common/util.h @@ -299,11 +299,18 @@ char *gnupg_get_help_string (const char *key, int only_current_locale); /*-- localename.c --*/ const char *gnupg_messages_locale_name (void); -/*-- kmac.c --*/ -gpg_error_t compute_kmac256 (void *digest, size_t digestlen, - const void *key, size_t keylen, - const void *custom, size_t customlen, - gcry_buffer_t *data_iov, int data_iovlen); +/*-- kem.c --*/ +gpg_error_t gnupg_ecc_kem_kdf (void *kek, size_t kek_len, + int hashalgo, const void *ecdh, size_t ecdh_len, + const void *ecc_ct, size_t ecc_ct_len, + const void *ecc_pk, size_t ecc_pk_len); + +gpg_error_t gnupg_kem_combiner (void *kek, size_t kek_len, + const void *ecc_ss, size_t ecc_ss_len, + const void *ecc_ct, size_t ecc_ct_len, + const void *mlkem_ss, size_t mlkem_ss_len, + const void *mlkem_ct, size_t mlkem_ct_len, + const void *fixedinfo, size_t fixedinfo_len); /*-- miscellaneous.c --*/ From aee6b1131b53703872e12aa6a02852bd506cc5eb Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 10 Apr 2024 11:13:31 +0900 Subject: [PATCH 425/869] common: Rename to kem.c from kmac.c. * common/Makefile.am (common_sources): Fix to kem.c. * common/kem.c: Rename. -- Signed-off-by: NIIBE Yutaka --- common/Makefile.am | 2 +- common/{kmac.c => kem.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename common/{kmac.c => kem.c} (100%) diff --git a/common/Makefile.am b/common/Makefile.am index e4dcf8ad6..a4840fbdd 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -98,7 +98,7 @@ common_sources = \ comopt.c comopt.h \ compliance.c compliance.h \ pkscreening.c pkscreening.h \ - kmac.c + kem.c if HAVE_W32_SYSTEM common_sources += w32-reg.c w32-cmdline.c diff --git a/common/kmac.c b/common/kem.c similarity index 100% rename from common/kmac.c rename to common/kem.c From c21237ac27220a834f47888ff2b4d3b570eb2dc0 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 10 Apr 2024 12:52:13 +0900 Subject: [PATCH 426/869] agent:kem: Externalize FIXED_INFO. * agent/pkdecrypt.c (agent_hybrid_pgp_kem_decrypt): Don't hard code the value of FIXED_INFO. Get it from frontend. -- Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 69 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 3848bcefc..24ba1fd64 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -177,12 +177,13 @@ reverse_buffer (unsigned char *buffer, unsigned int length) First keygrip is for ECC, second keygrip is for PQC. CIPHERTEXT should follow the format of: - (enc-val(pqc(s%m)(e%m)(k%m)))) - s: encrypted session key + (enc-val(pqc(e%m)(k%m)(s%m)(fixed-info&))) e: ECDH ciphertext k: ML-KEM ciphertext + s: encrypted session key + fixed-info: A buffer with the fixed info. - FIXME: For now, possibile keys on smartcard are not supported. + FIXME: For now, possible keys on smartcard are not supported. */ static gpg_error_t agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, @@ -224,7 +225,10 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_cipher_hd_t hd; unsigned char sessionkey[256]; size_t sessionkey_len; - const unsigned char fixedinfo[1] = { 105 }; + gcry_buffer_t fixed_info = { 0, 0, 0, NULL }; + + gcry_sexp_t curve = NULL; + const char *curve_name; err = agent_key_from_file (ctrl, NULL, desc_text, ctrl->keygrip, &shadow_info, @@ -246,33 +250,62 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, /* Here assumes no smartcard, but private keys */ - gcry_sexp_extract_param (s_cipher, NULL, "/e/k/s", + gcry_sexp_extract_param (s_cipher, NULL, "/eks&'fixed-info'", &ecc_ct_mpi, &mlkem_ct_mpi, - &encrypted_sessionkey_mpi, NULL); + &encrypted_sessionkey_mpi, + &fixed_info, NULL); + if (err) + goto leave; encrypted_sessionkey = gcry_mpi_get_opaque (encrypted_sessionkey_mpi, &nbits); encrypted_sessionkey_len = (nbits+7)/8; - encrypted_sessionkey_len--; + if (encrypted_sessionkey_len < 1+1+8) + { + /* Fixme: This is a basic check but we should better test + * against the expected length and something which + * is required to avoid an underflow. */ + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + encrypted_sessionkey_len--; if (encrypted_sessionkey[0] != encrypted_sessionkey_len) { - err = GPG_ERR_INV_DATA; + err = gpg_error (GPG_ERR_INV_DATA); goto leave; } encrypted_sessionkey++; /* Skip the length. */ if (encrypted_sessionkey[0] != CIPHER_ALGO_AES256) { - err = GPG_ERR_INV_DATA; + err = gpg_error (GPG_ERR_INV_DATA); goto leave; } + encrypted_sessionkey_len--; encrypted_sessionkey++; /* Skip the sym algo */ /* Fistly, ECC part. FIXME: For now, we assume X25519. */ - gcry_sexp_extract_param (s_skey0, NULL, "/q/d", - &ecc_pk_mpi, &ecc_sk_mpi, NULL); + curve = gcry_sexp_find_token (s_skey0, "curve", 0); + if (!curve) + { + err = gpg_error (GPG_ERR_BAD_SECKEY); + goto leave; + } + + curve_name = gcry_sexp_nth_data (curve, 1, &len); + if (len != 10 || memcmp (curve_name, "Curve25519", len)) + { + err = gpg_error (GPG_ERR_BAD_SECKEY); + goto leave; + } + + err = gcry_sexp_extract_param (s_skey0, NULL, "/q/d", + &ecc_pk_mpi, &ecc_sk_mpi, NULL); + if (err) + goto leave; + p = gcry_mpi_get_opaque (ecc_pk_mpi, &nbits); len = (nbits+7)/8; memcpy (ecc_pk, p+1, 32); /* Remove the 0x40 prefix */ @@ -280,7 +313,7 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, len = (nbits+7)/8; if (len > 32) { - err = GPG_ERR_INV_DATA; + err = gpg_error (GPG_ERR_INV_DATA); goto leave; } memset (ecc_sk, 0, 32); @@ -295,19 +328,17 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, ecc_ct_len = (nbits+7)/8; if (ecc_ct_len != 32) { - err = GPG_ERR_INV_DATA; + err = gpg_error (GPG_ERR_INV_DATA); goto leave; } err = gcry_kem_decap (GCRY_KEM_RAW_X25519, ecc_sk, 32, ecc_ct, ecc_ct_len, ecc_ecdh, 32, NULL, 0); - if (err) goto leave; err = gnupg_ecc_kem_kdf (ecc_ss, 32, GCRY_MD_SHA3_256, ecc_ecdh, 32, ecc_ct, 32, ecc_pk, 32); - if (err) goto leave; @@ -317,14 +348,14 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, len = (nbits+7)/8; if (len != GCRY_KEM_MLKEM768_SECKEY_LEN) { - err = GPG_ERR_INV_DATA; + err = gpg_error (GPG_ERR_INV_DATA); goto leave; } mlkem_ct = gcry_mpi_get_opaque (mlkem_ct_mpi, &nbits); len = (nbits+7)/8; if (len != GCRY_KEM_MLKEM768_CIPHER_LEN) { - err = GPG_ERR_INV_DATA; + err = gpg_error (GPG_ERR_INV_DATA); goto leave; } err = gcry_kem_decap (GCRY_KEM_MLKEM768, @@ -343,7 +374,7 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, ecc_ss, 32, ecc_ct, 32, mlkem_ss, GCRY_KEM_MLKEM768_SHARED_LEN, mlkem_ct, GCRY_KEM_MLKEM768_CIPHER_LEN, - fixedinfo, 1); + fixed_info.data, fixed_info.size); if (err) { log_error ("KEM combiner failed: %s\n", gpg_strerror (err)); @@ -397,6 +428,8 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, mpi_release (ecc_ct_mpi); mpi_release (mlkem_ct_mpi); mpi_release (encrypted_sessionkey_mpi); + gcry_free (fixed_info.data); + gcry_sexp_release (curve); gcry_sexp_release (s_skey0); gcry_sexp_release (s_skey1); return err; From 84ddb24e30c54cc290121061ef4f93fbb306f4f1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Apr 2024 15:49:00 +0200 Subject: [PATCH 427/869] gpg: Make Kyber creation more flexible. * common/openpgp-oid.c (openpgp_is_curve_supported): Allow the abbreviated curve name. * g10/pkglue.c (pk_encrypt): Add debug output. * g10/seskey.c (encode_session_key): Handle Kyber session key like ECDH. This is just a stub. * g10/keygen.c (ecckey_from_sexp): Use the modern OID for cv25519. (parse_key_parameter_part): Allow more Kyber variants. -- Test by creating an ed25519 key and using gpg --quick-add-key --batch --passphrase "" to create several subkeys. Tested with ALGOs: kyber768 kyber1024 ky768_cv25519 ky768_bp256 kyber768_nistp256 ky1024_cv448 All curves capable of encryption should work. GnuPG-bug-id: 6815 --- common/openpgp-oid.c | 4 +++- g10/encrypt.c | 2 +- g10/keygen.c | 51 +++++++++++++++++++++++++++++++++++++------- g10/pkglue.c | 5 +++++ g10/seskey.c | 4 +++- 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index bc82cc6b0..4b59c1aeb 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -599,7 +599,9 @@ openpgp_is_curve_supported (const char *name, int *r_algo, { if ((!ascii_strcasecmp (name, oidtable[idx].name) || (oidtable[idx].alias - && !ascii_strcasecmp (name, (oidtable[idx].alias)))) + && !ascii_strcasecmp (name, (oidtable[idx].alias))) + || (oidtable[idx].abbr + && !ascii_strcasecmp (name, (oidtable[idx].abbr)))) && curve_supported_p (oidtable[idx].name)) { if (r_algo) diff --git a/g10/encrypt.c b/g10/encrypt.c index 62483fa16..aa0c3c6dd 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -758,7 +758,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, aead_algo_t aead_algo, * Encrypt the file with the given userids (or ask if none is * supplied). Either FILENAME or FILEFD must be given, but not both. * The caller may provide a checked list of public keys in - * PROVIDED_PKS; if not the function builds a list of keys on its own. + * PROVIDED_KEYS; if not the function builds a list of keys on its own. * * Note that FILEFD is currently only used by cmd_encrypt in the * not yet finished server.c. diff --git a/g10/keygen.c b/g10/keygen.c index 763d23ee4..119f7ca5d 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1319,7 +1319,7 @@ curve_is_448 (gcry_sexp_t sexp) * parameters for dual algorithm (e.g. Kyber). */ static gpg_error_t ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, - gcry_sexp_t sexp2, int algo) + gcry_sexp_t sexp2, int algo, int pkversion) { gpg_error_t err; gcry_sexp_t list, l2; @@ -1362,6 +1362,10 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, err = gpg_error (GPG_ERR_INV_OBJ); goto leave; } + /* For v5 keys we prefer the modern OID for cv25519. */ + if (pkversion > 4 && !strcmp (oidstr, "1.3.6.1.4.1.3029.1.5.1")) + oidstr = "1.3.101.110"; + err = openpgp_oid_from_str (oidstr, &array[0]); if (err) goto leave; @@ -1605,11 +1609,11 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, pk->pubkey_algo = algo; if (algo == PUBKEY_ALGO_KYBER) - err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo); + err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo, pk->version); else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH ) - err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo); + err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo, pk->version); else err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); if (err) @@ -1716,11 +1720,11 @@ common_gen (const char *keyparms, const char *keyparms2, pk->pubkey_algo = algo; if (algo == PUBKEY_ALGO_KYBER) - err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo); + err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo, pk->version); else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH ) - err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo); + err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo, pk->version); else err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); if (err) @@ -3682,7 +3686,8 @@ parse_key_parameter_part (ctrl_t ctrl, return gpg_error (GPG_ERR_INV_VALUE); } } - else if (!ascii_strcasecmp (string, "kyber")) + else if (!ascii_strcasecmp (string, "kyber") + || !ascii_strcasecmp (string, "kyber768")) { /* Get the curve and check that it can technically be used * (i.e. everything except the EdXXXX curves. */ @@ -3693,6 +3698,35 @@ parse_key_parameter_part (ctrl_t ctrl, size = 768; is_pqc = 1; } + else if (!ascii_strcasecmp (string, "kyber1024")) + { + /* Get the curve and check that it can technically be used + * (i.e. everything except the EdXXXX curves. */ + curve = openpgp_is_curve_supported ("brainpoolP512r1", &algo, NULL); + if (!curve || algo == PUBKEY_ALGO_EDDSA) + return gpg_error (GPG_ERR_UNKNOWN_CURVE); + algo = PUBKEY_ALGO_KYBER; + size = 1024; + is_pqc = 1; + } + else if (!ascii_strncasecmp (string, "ky768_", 6) + || !ascii_strncasecmp (string, "ky1024_", 7) + || !ascii_strncasecmp (string, "kyber768_", 9) + || !ascii_strncasecmp (string, "kyber1024_", 10) + ) + { + /* Get the curve and check that it can technically be used + * (i.e. everything except the EdXXXX curves. */ + s = strchr (string, '_'); + log_assert (s); + s++; + curve = openpgp_is_curve_supported (s, &algo, NULL); + if (!curve || algo == PUBKEY_ALGO_EDDSA) + return gpg_error (GPG_ERR_UNKNOWN_CURVE); + algo = PUBKEY_ALGO_KYBER; + size = strstr (string, "768_")? 768 : 1024; + is_pqc = 1; + } else if (!ascii_strcasecmp (string, "dil3")) { algo = PUBKEY_ALGO_DIL3_25519; @@ -6734,12 +6768,14 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, if (curve_is_448 (s_key)) *keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY; + pk->version = (*keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; + if (algo == PUBKEY_ALGO_RSA) err = key_from_sexp (pk->pkey, s_key, "public-key", "ne"); else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_EDDSA || algo == PUBKEY_ALGO_ECDH ) - err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo); + err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo, pk->version); else err = gpg_error (GPG_ERR_PUBKEY_ALGO); gcry_sexp_release (s_key); @@ -6752,7 +6788,6 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root, } pk->timestamp = *timestamp; - pk->version = (*keygen_flags & KEYGEN_FLAG_CREATE_V5_KEY)? 5 : 4; if (expireval) pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; diff --git a/g10/pkglue.c b/g10/pkglue.c index f18313913..037e97a14 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -480,6 +480,11 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_release (k); } } + else if (algo == PUBKEY_ALGO_KYBER) + { + log_debug ("Implement Kyber encryption\n"); + rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } else rc = gpg_error (GPG_ERR_PUBKEY_ALGO); diff --git a/g10/seskey.c b/g10/seskey.c index 15c210b78..e5397080d 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -92,7 +92,9 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) /* Shortcut for ECDH. It's padding is minimal to simply make the output be a multiple of 8 bytes. */ - if (openpgp_pk_algo == PUBKEY_ALGO_ECDH) + /* FIXME: We use the ECDH also for Kyber for now. */ + if (openpgp_pk_algo == PUBKEY_ALGO_ECDH + || openpgp_pk_algo == PUBKEY_ALGO_KYBER) { /* Pad to 8 byte granularity; the padding byte is the number of * padded bytes. From 87025e5da6c49978983dd1c230d7b5cef00f1088 Mon Sep 17 00:00:00 2001 From: Todd Zullinger via Gnupg-devel Date: Wed, 10 Apr 2024 12:08:24 -0400 Subject: [PATCH 428/869] doc: Fix a few typos in agent/keyformat.txt -- Signed-off-by: Todd Zullinger --- agent/keyformat.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/agent/keyformat.txt b/agent/keyformat.txt index e0c4df0f0..dadfed4eb 100644 --- a/agent/keyformat.txt +++ b/agent/keyformat.txt @@ -59,7 +59,7 @@ A name must start with a letter and end with a colon. Valid characters are all ASCII letters, numbers and the hyphen. Comparison of names is done case insensitively. Names may be used several times to represent an array of values. Note that the name "Key" is special -in that it is madandory must occur only once. +in that it is mandatory and must occur only once. *** Values Values are UTF-8 encoded strings. Values can be wrapped at any point, @@ -156,7 +156,7 @@ dialog window when card is not available. When the value is "no", a card operation is refused with GPG_ERR_UNUSABLE_SECKEY error. *** Backup-info -This gives information for a backup of the key. The follwoing fields +This gives information for a backup of the key. The following fields are space delimited: - Hexified keygrip (uppercase) to make it easy to identify the @@ -345,7 +345,7 @@ The currently defined protection modes are: ** Shadowed Private Key Format To keep track of keys stored on IC cards we use a third format for -private kyes which are called shadow keys as they are only a reference +private keys which are called shadow keys as they are only a reference to keys stored on a token: (shadowed-private-key @@ -395,7 +395,7 @@ This format is used to transfer keys between gpg and gpg-agent. * PUBKEYALGO is a Libgcrypt algo name * CURVENAME is the name of the curve - only used with ECC. * P1 .. PN are the parameters; the public parameters are never encrypted - the secrect key parameters are encrypted if the "protection" list is + the secret key parameters are encrypted if the "protection" list is given. To make this more explicit each parameter is preceded by a flag "_" for cleartext or "e" for encrypted text. * CSUM is the deprecated 16 bit checksum as defined by OpenPGP. This @@ -404,7 +404,7 @@ This format is used to transfer keys between gpg and gpg-agent. the old 16 bit checksum (above) is used and if it is "none" no protection at all is used. * PROTALGO is a Libgcrypt style cipher algorithm name - * IV is the initialization verctor. + * IV is the initialization vector. * S2KMODE is the value from RFC-4880. * S2KHASH is a libgcrypt style hash algorithm identifier. * S2KSALT is the 8 byte salt @@ -492,7 +492,7 @@ with "encrypted_octet_string" decoding to: (hash sha1 #0102030405060708091011121314151617181920#) ) -To compute the hash this S-expression (in canoncical format) was +To compute the hash this S-expression (in canonical format) was hashed: ((desc "List of system passphrases") From 6737e07a9b04064947ae37abd28b845a09abee22 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 Apr 2024 08:27:53 +0200 Subject: [PATCH 429/869] doc: Move keyformat.txt to here. -- --- doc/Makefile.am | 2 +- {agent => doc}/keyformat.txt | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {agent => doc}/keyformat.txt (100%) diff --git a/doc/Makefile.am b/doc/Makefile.am index 390153c76..66a934cef 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -42,7 +42,7 @@ EXTRA_DIST = samplekeys.asc mksamplekeys com-certs.pem \ FAQ gnupg7.texi mkdefsinc.c defsincdate \ opt-homedir.texi see-also-note.texi specify-user-id.texi \ gpgv.texi yat2m.c ChangeLog-2011 whats-new-in-2.1.txt \ - trust-values.texi + trust-values.texi keyformat.txt BUILT_SOURCES = gnupg-module-overview.png gnupg-module-overview.pdf \ gnupg-card-architecture.png gnupg-card-architecture.pdf \ diff --git a/agent/keyformat.txt b/doc/keyformat.txt similarity index 100% rename from agent/keyformat.txt rename to doc/keyformat.txt From 172d53d63689dee780b03d60f19f53114f6c4283 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 11 Apr 2024 15:21:42 +0900 Subject: [PATCH 430/869] agent: Fix PQC decryption. * agent/pkdecrypt.c (agent_hybrid_pgp_kem_decrypt): Change the format of SEXP in the protocol for symmetric cipher algorithm identifier. -- GnuPG-bug-id: 7014 Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 24ba1fd64..8f1614292 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -177,7 +177,8 @@ reverse_buffer (unsigned char *buffer, unsigned int length) First keygrip is for ECC, second keygrip is for PQC. CIPHERTEXT should follow the format of: - (enc-val(pqc(e%m)(k%m)(s%m)(fixed-info&))) + (enc-val(pqc(c%u)(e%m)(k%m)(s%m)(fixed-info&))) + c: cipher identifier (symmetric) e: ECDH ciphertext k: ML-KEM ciphertext s: encrypted session key @@ -199,6 +200,7 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *p; size_t len; + int algo; gcry_mpi_t encrypted_sessionkey_mpi = NULL; const unsigned char *encrypted_sessionkey; size_t encrypted_sessionkey_len; @@ -250,41 +252,20 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, /* Here assumes no smartcard, but private keys */ - gcry_sexp_extract_param (s_cipher, NULL, "/eks&'fixed-info'", - &ecc_ct_mpi, - &mlkem_ct_mpi, - &encrypted_sessionkey_mpi, - &fixed_info, NULL); + gcry_sexp_extract_param (s_cipher, NULL, "%uc/eks&'fixed-info'", + &algo, &ecc_ct_mpi, &mlkem_ct_mpi, + &encrypted_sessionkey_mpi, &fixed_info, NULL); if (err) goto leave; + len = gcry_cipher_get_algo_keylen (algo); encrypted_sessionkey = gcry_mpi_get_opaque (encrypted_sessionkey_mpi, &nbits); encrypted_sessionkey_len = (nbits+7)/8; - if (encrypted_sessionkey_len < 1+1+8) - { - /* Fixme: This is a basic check but we should better test - * against the expected length and something which - * is required to avoid an underflow. */ - err = gpg_error (GPG_ERR_INV_DATA); - goto leave; - } - - encrypted_sessionkey_len--; - if (encrypted_sessionkey[0] != encrypted_sessionkey_len) + if (len == 0 || encrypted_sessionkey_len != len + 8) { err = gpg_error (GPG_ERR_INV_DATA); goto leave; } - encrypted_sessionkey++; /* Skip the length. */ - - if (encrypted_sessionkey[0] != CIPHER_ALGO_AES256) - { - err = gpg_error (GPG_ERR_INV_DATA); - goto leave; - } - - encrypted_sessionkey_len--; - encrypted_sessionkey++; /* Skip the sym algo */ /* Fistly, ECC part. FIXME: For now, we assume X25519. */ curve = gcry_sexp_find_token (s_skey0, "curve", 0); @@ -301,7 +282,7 @@ agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, goto leave; } - err = gcry_sexp_extract_param (s_skey0, NULL, "/q/d", + err = gcry_sexp_extract_param (s_skey0, NULL, "/qd", &ecc_pk_mpi, &ecc_sk_mpi, NULL); if (err) goto leave; From f2fd4f1a9eaf68eba206858ebd8ce6006a762c9e Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 11 Apr 2024 15:26:08 +0900 Subject: [PATCH 431/869] agent: Rename the function using the word "composite" * agent/pkdecrypt.c (composite_pgp_kem_decrypt): Rename. -- Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 8f1614292..79d832520 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -173,7 +173,7 @@ reverse_buffer (unsigned char *buffer, unsigned int length) } } -/* For hybrid PGP KEM (ECC+ML-KEM), decrypt CIPHERTEXT using KEM API. +/* For composite PGP KEM (ECC+ML-KEM), decrypt CIPHERTEXT using KEM API. First keygrip is for ECC, second keygrip is for PQC. CIPHERTEXT should follow the format of: @@ -187,8 +187,8 @@ reverse_buffer (unsigned char *buffer, unsigned int length) FIXME: For now, possible keys on smartcard are not supported. */ static gpg_error_t -agent_hybrid_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, - gcry_sexp_t s_cipher, membuf_t *outbuf) +composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, + gcry_sexp_t s_cipher, membuf_t *outbuf) { #if GCRYPT_VERSION_NUMBER >= 0x010b00 gcry_sexp_t s_skey0 = NULL; @@ -453,7 +453,7 @@ agent_kem_decrypt (ctrl_t ctrl, const char *desc_text, int kemid, if (!ctrl->have_keygrip1) { - log_error ("hybrid KEM requires two KEYGRIPs\n"); + log_error ("Composite KEM requires two KEYGRIPs\n"); return gpg_error (GPG_ERR_NO_SECKEY); } @@ -471,7 +471,7 @@ agent_kem_decrypt (ctrl_t ctrl, const char *desc_text, int kemid, log_printhex (ciphertext, ciphertextlen, "cipher: "); } - err = agent_hybrid_pgp_kem_decrypt (ctrl, desc_text, s_cipher, outbuf); + err = composite_pgp_kem_decrypt (ctrl, desc_text, s_cipher, outbuf); gcry_sexp_release (s_cipher); return err; From 869d1df270c0ccc3a9f792167b96d678a932b37e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 Apr 2024 11:33:29 +0200 Subject: [PATCH 432/869] indent: Re-indent a function -- --- g10/keylist.c | 341 +++++++++++++++++++++++++------------------------- 1 file changed, 170 insertions(+), 171 deletions(-) diff --git a/g10/keylist.c b/g10/keylist.c index 3d43d9e63..7fb5eff72 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1280,185 +1280,184 @@ static void list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node, struct keylist_context *listctx, PKT_public_key *lastpk) { - /* (extra indentation to keep the diff history short) */ - PKT_signature *sig = node->pkt->pkt.signature; - int rc, sigrc; - char *sigstr; - char *reason_text = NULL; - char *reason_comment = NULL; - size_t reason_commentlen; - int reason_code = 0; + PKT_signature *sig = node->pkt->pkt.signature; + int rc, sigrc; + char *sigstr; + char *reason_text = NULL; + char *reason_comment = NULL; + size_t reason_commentlen; + int reason_code = 0; - if (listctx->check_sigs) - { - rc = check_key_signature (ctrl, keyblock, node, NULL); - switch (gpg_err_code (rc)) - { - case 0: - listctx->good_sigs++; - sigrc = '!'; - break; - case GPG_ERR_BAD_SIGNATURE: - listctx->inv_sigs++; - sigrc = '-'; - break; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_UNUSABLE_PUBKEY: - listctx->no_key++; - return; - case GPG_ERR_DIGEST_ALGO: - case GPG_ERR_PUBKEY_ALGO: - if (!(opt.list_options & LIST_SHOW_UNUSABLE_SIGS)) - return; - /* fallthru. */ - default: - listctx->oth_err++; - sigrc = '%'; - break; - } + if (listctx->check_sigs) + { + rc = check_key_signature (ctrl, keyblock, node, NULL); + switch (gpg_err_code (rc)) + { + case 0: + listctx->good_sigs++; + sigrc = '!'; + break; + case GPG_ERR_BAD_SIGNATURE: + listctx->inv_sigs++; + sigrc = '-'; + break; + case GPG_ERR_NO_PUBKEY: + case GPG_ERR_UNUSABLE_PUBKEY: + listctx->no_key++; + return; + case GPG_ERR_DIGEST_ALGO: + case GPG_ERR_PUBKEY_ALGO: + if (!(opt.list_options & LIST_SHOW_UNUSABLE_SIGS)) + return; + /* fallthru. */ + default: + listctx->oth_err++; + sigrc = '%'; + break; + } - /* TODO: Make sure a cached sig record here still has - the pk that issued it. See also - keyedit.c:print_and_check_one_sig */ - } - else - { - if (!(opt.list_options & LIST_SHOW_UNUSABLE_SIGS) - && (gpg_err_code (openpgp_pk_test_algo (sig->pubkey_algo) - == GPG_ERR_PUBKEY_ALGO) - || gpg_err_code (openpgp_md_test_algo (sig->digest_algo) - == GPG_ERR_DIGEST_ALGO) - || (sig->digest_algo == DIGEST_ALGO_SHA1 - && !(node->flag & NODFLG_MARK_B) /*no selfsig*/ - && !opt.flags.allow_weak_key_signatures))) - return; - rc = 0; - sigrc = ' '; - } + /* TODO: Make sure a cached sig record here still has + the pk that issued it. See also + keyedit.c:print_and_check_one_sig */ + } + else + { + if (!(opt.list_options & LIST_SHOW_UNUSABLE_SIGS) + && (gpg_err_code (openpgp_pk_test_algo (sig->pubkey_algo) + == GPG_ERR_PUBKEY_ALGO) + || gpg_err_code (openpgp_md_test_algo (sig->digest_algo) + == GPG_ERR_DIGEST_ALGO) + || (sig->digest_algo == DIGEST_ALGO_SHA1 + && !(node->flag & NODFLG_MARK_B) /*no selfsig*/ + && !opt.flags.allow_weak_key_signatures))) + return; + rc = 0; + sigrc = ' '; + } - if (IS_KEY_REV (sig) || IS_SUBKEY_REV (sig) || IS_UID_REV (sig)) + if (IS_KEY_REV (sig) || IS_SUBKEY_REV (sig) || IS_UID_REV (sig)) + { + sigstr = "rev"; + reason_code = get_revocation_reason (sig, &reason_text, + &reason_comment, + &reason_commentlen); + } + else if (IS_UID_SIG (sig)) + sigstr = "sig"; + else if (IS_SUBKEY_SIG (sig)) + sigstr = "sig"; + else if (IS_KEY_SIG (sig)) + sigstr = "sig"; + else + { + es_fprintf (es_stdout, "sig " + "[unexpected signature class 0x%02x]\n", + sig->sig_class); + return; + } + + es_fputs (sigstr, es_stdout); + es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s", + sigrc, (sig->sig_class - 0x10 > 0 && + sig->sig_class - 0x10 < + 4) ? '0' + sig->sig_class - 0x10 : ' ', + sig->flags.exportable ? ' ' : 'L', + sig->flags.revocable ? ' ' : 'R', + sig->flags.policy_url ? 'P' : ' ', + sig->flags.notation ? 'N' : ' ', + sig->flags.expired ? 'X' : ' ', + (sig->trust_depth > 9) ? 'T' : (sig->trust_depth > + 0) ? '0' + + sig->trust_depth : ' ', keystr (sig->keyid), + datestr_from_sig (sig)); + if (opt.list_options & LIST_SHOW_SIG_EXPIRE) + es_fprintf (es_stdout, " %s", expirestr_from_sig (sig)); + es_fprintf (es_stdout, " "); + if (sigrc == '%') + es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc)); + else if (sigrc == '?') + ; + else if ((node->flag & NODFLG_MARK_B)) + es_fputs (_("[self-signature]"), es_stdout); + else if (!opt.fast_list_mode ) + { + size_t n; + char *p = get_user_id (ctrl, sig->keyid, &n, NULL); + print_utf8_buffer (es_stdout, p, n); + xfree (p); + } + es_putc ('\n', es_stdout); + + if (sig->flags.policy_url + && (opt.list_options & LIST_SHOW_POLICY_URLS)) + show_policy_url (sig, 3, 0); + + if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS)) + show_notation (sig, 3, 0, + ((opt. + list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) + + + ((opt. + list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : + 0)); + + if (sig->flags.notation + && (opt.list_options + & (LIST_SHOW_X509_NOTATIONS|LIST_STORE_X509_NOTATIONS))) + { + struct notation *nots; + + if ((IS_KEY_SIG (sig) || IS_SUBKEY_SIG (sig)) + && (nots = search_sig_notations (sig, + "x509certificate@pgp.com"))) + { + if ((opt.list_options & LIST_STORE_X509_NOTATIONS)) + print_x509_notations (nots, lastpk); + else + print_x509_notations (nots, NULL); + free_notation (nots); + } + } + + if (sig->flags.pref_ks + && (opt.list_options & LIST_SHOW_KEYSERVER_URLS)) + show_keyserver_url (sig, 3, 0); + + if (reason_text && (reason_code || reason_comment)) + { + es_fprintf (es_stdout, " %s%s\n", + _("reason for revocation: "), reason_text); + if (reason_comment) + { + const byte *s, *s_lf; + size_t n, n_lf; + + s = reason_comment; + n = reason_commentlen; + s_lf = NULL; + do { - sigstr = "rev"; - reason_code = get_revocation_reason (sig, &reason_text, - &reason_comment, - &reason_commentlen); - } - else if (IS_UID_SIG (sig)) - sigstr = "sig"; - else if (IS_SUBKEY_SIG (sig)) - sigstr = "sig"; - else if (IS_KEY_SIG (sig)) - sigstr = "sig"; - else - { - es_fprintf (es_stdout, "sig " - "[unexpected signature class 0x%02x]\n", - sig->sig_class); - return; - } - - es_fputs (sigstr, es_stdout); - es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s", - sigrc, (sig->sig_class - 0x10 > 0 && - sig->sig_class - 0x10 < - 4) ? '0' + sig->sig_class - 0x10 : ' ', - sig->flags.exportable ? ' ' : 'L', - sig->flags.revocable ? ' ' : 'R', - sig->flags.policy_url ? 'P' : ' ', - sig->flags.notation ? 'N' : ' ', - sig->flags.expired ? 'X' : ' ', - (sig->trust_depth > 9) ? 'T' : (sig->trust_depth > - 0) ? '0' + - sig->trust_depth : ' ', keystr (sig->keyid), - datestr_from_sig (sig)); - if (opt.list_options & LIST_SHOW_SIG_EXPIRE) - es_fprintf (es_stdout, " %s", expirestr_from_sig (sig)); - es_fprintf (es_stdout, " "); - if (sigrc == '%') - es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc)); - else if (sigrc == '?') - ; - else if ((node->flag & NODFLG_MARK_B)) - es_fputs (_("[self-signature]"), es_stdout); - else if (!opt.fast_list_mode ) - { - size_t n; - char *p = get_user_id (ctrl, sig->keyid, &n, NULL); - print_utf8_buffer (es_stdout, p, n); - xfree (p); - } - es_putc ('\n', es_stdout); - - if (sig->flags.policy_url - && (opt.list_options & LIST_SHOW_POLICY_URLS)) - show_policy_url (sig, 3, 0); - - if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS)) - show_notation (sig, 3, 0, - ((opt. - list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) - + - ((opt. - list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : - 0)); - - if (sig->flags.notation - && (opt.list_options - & (LIST_SHOW_X509_NOTATIONS|LIST_STORE_X509_NOTATIONS))) - { - struct notation *nots; - - if ((IS_KEY_SIG (sig) || IS_SUBKEY_SIG (sig)) - && (nots = search_sig_notations (sig, - "x509certificate@pgp.com"))) + /* We don't want any empty lines, so we skip them. */ + for (;n && *s == '\n'; s++, n--) + ; + if (n) { - if ((opt.list_options & LIST_STORE_X509_NOTATIONS)) - print_x509_notations (nots, lastpk); - else - print_x509_notations (nots, NULL); - free_notation (nots); + s_lf = memchr (s, '\n', n); + n_lf = s_lf? s_lf - s : n; + es_fprintf (es_stdout, " %s", + _("revocation comment: ")); + es_write_sanitized (es_stdout, s, n_lf, NULL, NULL); + es_putc ('\n', es_stdout); + s += n_lf; n -= n_lf; } - } + } while (s_lf); + } + } - if (sig->flags.pref_ks - && (opt.list_options & LIST_SHOW_KEYSERVER_URLS)) - show_keyserver_url (sig, 3, 0); + xfree (reason_text); + xfree (reason_comment); - if (reason_text && (reason_code || reason_comment)) - { - es_fprintf (es_stdout, " %s%s\n", - _("reason for revocation: "), reason_text); - if (reason_comment) - { - const byte *s, *s_lf; - size_t n, n_lf; - - s = reason_comment; - n = reason_commentlen; - s_lf = NULL; - do - { - /* We don't want any empty lines, so we skip them. */ - for (;n && *s == '\n'; s++, n--) - ; - if (n) - { - s_lf = memchr (s, '\n', n); - n_lf = s_lf? s_lf - s : n; - es_fprintf (es_stdout, " %s", - _("revocation comment: ")); - es_write_sanitized (es_stdout, s, n_lf, NULL, NULL); - es_putc ('\n', es_stdout); - s += n_lf; n -= n_lf; - } - } while (s_lf); - } - } - - xfree (reason_text); - xfree (reason_comment); - - /* fixme: check or list other sigs here */ + /* fixme: check or list other sigs here */ } From 61717fb0a775ca006efeb856b86eea1ab98c76cb Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 Apr 2024 15:48:16 +0200 Subject: [PATCH 433/869] agent: Add more diagnostics to PQC decryption. * agent/pkdecrypt.c (composite_pgp_kem_decrypt): Use %d for correctness. Add error diagnostics and one extra check. -- GnuPG-bug-id: 7014 --- .git-blame-ignore-revs | 2 + agent/pkdecrypt.c | 85 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index ec5aae1c7..1313cbe04 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -2,3 +2,5 @@ 6a80d6f9206eae2c867c45daa5cd3e7d6c6ad114 # doc: Fix spelling errors found by lintian. 2ed1f68b48db7b5503045386de0500fddf70077e +# indent: Re-indent a function +869d1df270c0ccc3a9f792167b96d678a932b37e diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 79d832520..ba42a265d 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -177,7 +177,7 @@ reverse_buffer (unsigned char *buffer, unsigned int length) First keygrip is for ECC, second keygrip is for PQC. CIPHERTEXT should follow the format of: - (enc-val(pqc(c%u)(e%m)(k%m)(s%m)(fixed-info&))) + (enc-val(pqc(c%d)(e%m)(k%m)(s%m)(fixed-info&))) c: cipher identifier (symmetric) e: ECDH ciphertext k: ML-KEM ciphertext @@ -252,17 +252,25 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, /* Here assumes no smartcard, but private keys */ - gcry_sexp_extract_param (s_cipher, NULL, "%uc/eks&'fixed-info'", - &algo, &ecc_ct_mpi, &mlkem_ct_mpi, - &encrypted_sessionkey_mpi, &fixed_info, NULL); + err = gcry_sexp_extract_param (s_cipher, NULL, "%dc/eks&'fixed-info'", + &algo, &ecc_ct_mpi, &mlkem_ct_mpi, + &encrypted_sessionkey_mpi, &fixed_info, NULL); if (err) - goto leave; + { + if (opt.verbose) + log_info ("%s: extracting parameters failed\n", __func__); + goto leave; + } len = gcry_cipher_get_algo_keylen (algo); encrypted_sessionkey = gcry_mpi_get_opaque (encrypted_sessionkey_mpi, &nbits); encrypted_sessionkey_len = (nbits+7)/8; if (len == 0 || encrypted_sessionkey_len != len + 8) { + if (opt.verbose) + log_info ("%s: encrypted session key length %zu" + " does not match the length for algo %d\n", + __func__, encrypted_sessionkey_len, algo); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } @@ -271,6 +279,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, curve = gcry_sexp_find_token (s_skey0, "curve", 0); if (!curve) { + if (opt.verbose) + log_info ("%s: no curve given\n", __func__); err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; } @@ -278,6 +288,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, curve_name = gcry_sexp_nth_data (curve, 1, &len); if (len != 10 || memcmp (curve_name, "Curve25519", len)) { + if (opt.verbose) + log_info ("%s: curve '%s' not supported\n", __func__, curve_name); err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; } @@ -285,22 +297,36 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, err = gcry_sexp_extract_param (s_skey0, NULL, "/qd", &ecc_pk_mpi, &ecc_sk_mpi, NULL); if (err) - goto leave; + { + if (opt.verbose) + log_info ("%s: extracting q and d from ECC key failed\n", __func__); + goto leave; + } p = gcry_mpi_get_opaque (ecc_pk_mpi, &nbits); len = (nbits+7)/8; + if (len != 33) + { + if (opt.verbose) + log_info ("%s: ECC public key length invalid (%zu)\n", __func__, len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } memcpy (ecc_pk, p+1, 32); /* Remove the 0x40 prefix */ + mpi_release (ecc_pk_mpi); + p = gcry_mpi_get_opaque (ecc_sk_mpi, &nbits); len = (nbits+7)/8; if (len > 32) { + if (opt.verbose) + log_info ("%s: ECC secret key too long (%zu)\n", __func__, len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } memset (ecc_sk, 0, 32); memcpy (ecc_sk + 32 - len, p, len); reverse_buffer (ecc_sk, 32); - mpi_release (ecc_pk_mpi); mpi_release (ecc_sk_mpi); ecc_pk_mpi = NULL; ecc_sk_mpi = NULL; @@ -309,6 +335,9 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, ecc_ct_len = (nbits+7)/8; if (ecc_ct_len != 32) { + if (opt.verbose) + log_info ("%s: ECC cipher text length invalid (%zu)\n", + __func__, ecc_ct_len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } @@ -316,19 +345,35 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, err = gcry_kem_decap (GCRY_KEM_RAW_X25519, ecc_sk, 32, ecc_ct, ecc_ct_len, ecc_ecdh, 32, NULL, 0); if (err) - goto leave; + { + if (opt.verbose) + log_info ("%s: gcry_kem_decap for ECC failed\n", __func__); + goto leave; + } err = gnupg_ecc_kem_kdf (ecc_ss, 32, GCRY_MD_SHA3_256, ecc_ecdh, 32, ecc_ct, 32, ecc_pk, 32); if (err) - goto leave; + { + if (opt.verbose) + log_info ("%s: kdf for ECC failed\n", __func__); + goto leave; + } /* Secondly, PQC part. For now, we assume ML-KEM. */ - gcry_sexp_extract_param (s_skey1, NULL, "/s", &mlkem_sk_mpi, NULL); + err = gcry_sexp_extract_param (s_skey1, NULL, "/s", &mlkem_sk_mpi, NULL); + if (err) + { + if (opt.verbose) + log_info ("%s: extracting s from PQ key failed\n", __func__); + goto leave; + } mlkem_sk = gcry_mpi_get_opaque (mlkem_sk_mpi, &nbits); len = (nbits+7)/8; if (len != GCRY_KEM_MLKEM768_SECKEY_LEN) { + if (opt.verbose) + log_info ("%s: PQ key length invalid (%zu)\n", __func__, len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } @@ -336,6 +381,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, len = (nbits+7)/8; if (len != GCRY_KEM_MLKEM768_CIPHER_LEN) { + if (opt.verbose) + log_info ("%s: PQ cipher text length invalid (%zu)\n", __func__, len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } @@ -345,7 +392,11 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, mlkem_ss, GCRY_KEM_MLKEM768_SHARED_LEN, NULL, 0); if (err) - goto leave; + { + if (opt.verbose) + log_info ("%s: gcry_kem_decap for PQ failed\n", __func__); + goto leave; + } mpi_release (mlkem_sk_mpi); mlkem_sk_mpi = NULL; @@ -358,7 +409,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, fixed_info.data, fixed_info.size); if (err) { - log_error ("KEM combiner failed: %s\n", gpg_strerror (err)); + if (opt.verbose) + log_info ("%s: KEM combiner failed\n", __func__); goto leave; } @@ -376,8 +428,9 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, GCRY_CIPHER_MODE_AESWRAP, 0); if (err) { - log_error ("ecdh failed to initialize AESWRAP: %s\n", - gpg_strerror (err)); + if (opt.verbose) + log_error ("ecdh failed to initialize AESWRAP: %s\n", + gpg_strerror (err)); goto leave; } @@ -466,9 +519,9 @@ agent_kem_decrypt (ctrl_t ctrl, const char *desc_text, int kemid, if (DBG_CRYPTO) { - log_printhex (ctrl->keygrip, 20, "keygrip:"); + log_printhex (ctrl->keygrip, 20, "keygrip0:"); log_printhex (ctrl->keygrip1, 20, "keygrip1:"); - log_printhex (ciphertext, ciphertextlen, "cipher: "); + gcry_log_debugsxp ("cipher", s_cipher); } err = composite_pgp_kem_decrypt (ctrl, desc_text, s_cipher, outbuf); From 813f8d1b8e4b6c4365f0bd2a5305bdbe1e049d05 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 11 Apr 2024 15:56:21 +0200 Subject: [PATCH 434/869] gpg: Changed internal data format for Kyber. * g10/packet.h (PKT_pubkey_enc): Add field seskey_algo. (struct pubkey_enc_list): Ditto. * g10/misc.c (pubkey_get_nenc): Change value for Kyber from 4 to 3. * g10/parse-packet.c (parse_pubkeyenc): Store the Kyber algo in the new field and adjust data. Do not store the length byte in data[2]. * g10/build-packet.c (do_pubkey_enc): Take the session algo for Kyber from the new field. * g10/encrypt.c (write_pubkey_enc): Ses the seskey_algo. * g10/mainproc.c (proc_pubkey_enc): Copy it. * g10/pubkey-enc.c (get_it): Support Kyber decryption. * g10/seskey.c (encode_session_key): Handle Kyber different from ECDH. -- Having always the single byte in the packet data than to store and retrieve it from an MPI is much easier. Thus this patch changes the original internal format. With this chnages decryption of the slighly modified test data works now. See the bug tracker for test data. GnuPG-bug-id: 6815 --- g10/build-packet.c | 5 +++ g10/encrypt.c | 1 + g10/mainproc.c | 1 + g10/misc.c | 2 +- g10/packet.h | 3 ++ g10/parse-packet.c | 20 ++++++---- g10/pubkey-enc.c | 94 +++++++++++++++++++++++++++++++--------------- g10/seskey.c | 20 ++++++++-- 8 files changed, 104 insertions(+), 42 deletions(-) diff --git a/g10/build-packet.c b/g10/build-packet.c index 78828c8dc..fd315b313 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -982,6 +982,11 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) for (i=0; i < n && !rc ; i++ ) { + /* For Kyber we need to insert the algo before the final data + * element because it is not stored in the data array. */ + if (enc->pubkey_algo == PUBKEY_ALGO_KYBER && i == 2) + iobuf_put (a, enc->seskey_algo); + if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1) rc = gpg_mpi_write_opaque_nohdr (a, enc->data[i]); else if (enc->pubkey_algo == PUBKEY_ALGO_ECDH) diff --git a/g10/encrypt.c b/g10/encrypt.c index aa0c3c6dd..f416cde53 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -1122,6 +1122,7 @@ write_pubkey_enc (ctrl_t ctrl, enc->pubkey_algo = pk->pubkey_algo; keyid_from_pk( pk, enc->keyid ); enc->throw_keyid = throw_keyid; + enc->seskey_algo = dek->algo; /* (Used only by PUBKEY_ALGO_KYBER.) */ /* Okay, what's going on: We have the session key somewhere in * the structure DEK and want to encode this session key in an diff --git a/g10/mainproc.c b/g10/mainproc.c index 6f3254e88..48bc463c5 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -529,6 +529,7 @@ proc_pubkey_enc (CTX c, PACKET *pkt) x->keyid[1] = enc->keyid[1]; x->pubkey_algo = enc->pubkey_algo; x->result = -1; + x->seskey_algo = enc->seskey_algo; x->data[0] = x->data[1] = x->data[2] = x->data[3] = NULL; if (enc->data[0]) { diff --git a/g10/misc.c b/g10/misc.c index ce0c04b3b..1359987d2 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1786,7 +1786,7 @@ pubkey_get_nenc (pubkey_algo_t algo) case PUBKEY_ALGO_ECDSA: return 0; case PUBKEY_ALGO_ELGAMAL: return 2; case PUBKEY_ALGO_EDDSA: return 0; - case PUBKEY_ALGO_KYBER: return 4; + case PUBKEY_ALGO_KYBER: return 3; default: return 0; } } diff --git a/g10/packet.h b/g10/packet.h index 40e5051c0..459e38dda 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -137,6 +137,8 @@ typedef struct { byte version; /* The algorithm used for the public key encryption scheme. */ byte pubkey_algo; + /* The session key algorithm used by some pubkey algos. */ + byte seskey_algo; /* Whether to hide the key id. This value is not directly serialized. */ byte throw_keyid; @@ -151,6 +153,7 @@ struct pubkey_enc_list struct pubkey_enc_list *next; u32 keyid[2]; int pubkey_algo; + int seskey_algo; int result; gcry_mpi_t data[PUBKEY_MAX_NENC]; }; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index c55bb1b71..8bd283b4b 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1513,7 +1513,7 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } else if (k->pubkey_algo == PUBKEY_ALGO_KYBER) { - log_assert (ndata == 4); + log_assert (ndata == 3); /* Get the ephemeral public key. */ n = pktlen; k->data[0] = sos_read (inp, &n, 0); @@ -1527,12 +1527,16 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, rc = read_octet_string (inp, &pktlen, 4, 0, 0, k->data + 1); if (rc) goto leave; - /* Get the algorithm id. */ - rc = read_octet_string (inp, &pktlen, 0, 1, 0, k->data + 2); - if (rc) - goto leave; - /* Get the wrapped symmetric key. */ - rc = read_sized_octet_string (inp, &pktlen, k->data + 3); + /* Get the algorithm id for the session key. */ + if (!pktlen) + { + rc = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + k->seskey_algo = iobuf_get_noeof (inp); + pktlen--; + /* Get the encrypted symmetric key. */ + rc = read_octet_string (inp, &pktlen, 1, 0, 0, k->data + 2); if (rc) goto leave; } @@ -1551,6 +1555,8 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } if (list_mode) { + if (k->seskey_algo) + es_fprintf (listfp, "\tsession key algo: %d\n", k->seskey_algo); for (i = 0; i < ndata; i++) { es_fprintf (listfp, "\tdata: "); diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 873b864b5..da32ebc7b 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -194,7 +194,7 @@ get_it (ctrl_t ctrl, { gpg_error_t err; byte *frame = NULL; - unsigned int n; + unsigned int frameidx; size_t nframe; u16 csum, csum2; int padding; @@ -240,13 +240,15 @@ get_it (ctrl_t ctrl, } else if (sk->pubkey_algo == PUBKEY_ALGO_KYBER) { - if (!enc->data[0] || !enc->data[1] || !enc->data[2] || !enc->data[3]) + log_debug ("seskey_algo: %d\n", enc->seskey_algo); + if (!enc->data[0] || !enc->data[1] || !enc->data[2]) err = gpg_error (GPG_ERR_BAD_MPI); else err = gcry_sexp_build (&s_data, NULL, - "(enc-val(pqc(e%m)(k%m)(s%m)(fixed-info%s)))", - enc->data[0], enc->data[1], enc->data[3], - "\x1d" /*PUBKEY_ALGO_KYBER*/); + "(enc-val(pqc(e%m)(k%m)(s%m)(c%d)(fixed-info%s)))", + enc->data[0], enc->data[1], enc->data[2], + enc->seskey_algo, + "\x69"); } else err = gpg_error (GPG_ERR_BUG); @@ -287,9 +289,22 @@ get_it (ctrl_t ctrl, */ if (DBG_CRYPTO) log_printhex (frame, nframe, "DEK frame:"); - n = 0; + frameidx = 0; - if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) + if (sk->pubkey_algo == PUBKEY_ALGO_KYBER) + { + /* We expect a 32 byte session key. We should not see this + * error here because due to the KEM mode the agent_pkdecrypt + * should have already failed. */ + if (nframe != 32) + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } + dek->keylen = nframe; + dek->algo = enc->seskey_algo; + } + else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) { gcry_mpi_t decoded; @@ -313,13 +328,21 @@ get_it (ctrl_t ctrl, goto leave; } nframe -= frame[nframe-1]; /* Remove padding. */ - log_assert (!n); /* (used just below) */ + if (4 > nframe) + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } + + dek->keylen = nframe - 3; + dek->algo = frame[0]; + frameidx = 1; } else { if (padding) { - if (n + 7 > nframe) + if (7 > nframe) { err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; @@ -331,34 +354,38 @@ get_it (ctrl_t ctrl, * using a Smartcard we are doing it the right way and * therefore we have to skip the zero. This should be fixed * in gpg-agent of course. */ - if (!frame[n]) - n++; + frameidx = 0; + if (!frame[frameidx]) + frameidx++; - if (frame[n] == 1 && frame[nframe - 1] == 2) + if (frame[frameidx] == 1 && frame[nframe - 1] == 2) { log_info (_("old encoding of the DEK is not supported\n")); err = gpg_error (GPG_ERR_CIPHER_ALGO); goto leave; } - if (frame[n] != 2) /* Something went wrong. */ + if (frame[frameidx] != 2) /* Something went wrong. */ { err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } - for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ + /* Skip the random bytes. */ + for (frameidx++; frameidx < nframe && frame[frameidx]; frameidx++) ; - n++; /* Skip the zero byte. */ + frameidx++; /* Skip the zero byte. */ } + + if (frameidx + 4 > nframe) + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } + + dek->keylen = nframe - (frameidx + 1) - 2; + dek->algo = frame[frameidx++]; } - if (n + 4 > nframe) - { - err = gpg_error (GPG_ERR_WRONG_SECKEY); - goto leave; - } - - dek->keylen = nframe - (n + 1) - 2; - dek->algo = frame[n++]; + /* Check whether we support the ago. */ err = openpgp_cipher_test_algo (dek->algo); if (err) { @@ -377,16 +404,21 @@ get_it (ctrl_t ctrl, goto leave; } - /* Copy the key to DEK and compare the checksum. */ - csum = buf16_to_u16 (frame+nframe-2); - memcpy (dek->key, frame + n, dek->keylen); - for (csum2 = 0, n = 0; n < dek->keylen; n++) - csum2 += dek->key[n]; - if (csum != csum2) + /* Copy the key to DEK and compare the checksum if needed. */ + /* We use the frameidx as flag for the need of a checksum. */ + memcpy (dek->key, frame + frameidx, dek->keylen); + if (frameidx) { - err = gpg_error (GPG_ERR_WRONG_SECKEY); - goto leave; + csum = buf16_to_u16 (frame+nframe-2); + for (csum2 = 0, frameidx = 0; frameidx < dek->keylen; frameidx++) + csum2 += dek->key[frameidx]; + if (csum != csum2) + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } } + if (DBG_CLOCK) log_clock ("decryption ready"); if (DBG_CRYPTO) diff --git a/g10/seskey.c b/g10/seskey.c index e5397080d..2fe8e9de7 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -86,15 +86,29 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) if (DBG_CRYPTO) log_debug ("encode_session_key: encoding %d byte DEK", dek->keylen); + if (openpgp_pk_algo == PUBKEY_ALGO_KYBER) + { + /* Straightforward encoding w/o extra checksum as used by ECDH. */ + nframe = dek->keylen; + log_assert (nframe > 4); /*(for the log_debug)*/ + frame = xmalloc_secure (nframe); + memcpy (frame, dek->key, nframe); + if (DBG_CRYPTO) + log_debug ("encode_session_key: " + "[%d] %02x %02x %02x ... %02x %02x %02x\n", + (int) dek->keylen, frame[0], frame[1], frame[2], + frame[nframe-3], frame[nframe-2], frame[nframe-1]); + + return gcry_mpi_set_opaque (NULL, frame, 8*nframe); + } + csum = 0; for (p = dek->key, i=0; i < dek->keylen; i++) csum += *p++; /* Shortcut for ECDH. It's padding is minimal to simply make the output be a multiple of 8 bytes. */ - /* FIXME: We use the ECDH also for Kyber for now. */ - if (openpgp_pk_algo == PUBKEY_ALGO_ECDH - || openpgp_pk_algo == PUBKEY_ALGO_KYBER) + if (openpgp_pk_algo == PUBKEY_ALGO_ECDH) { /* Pad to 8 byte granularity; the padding byte is the number of * padded bytes. From 6f94fe01a9e187512300f272ae61ecc0a34454e2 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 12 Apr 2024 10:43:12 +0200 Subject: [PATCH 435/869] gpg: Simplify the pk_encrypt function interface. * g10/pkglue.c (pk_encrypt): Remove superfluous arguments and reanem variable rc to err. * g10/encrypt.c (write_pubkey_enc): Adjust for this change. -- We used to pass PK as well as information which could be taken directly from PK. Using ERR instead of RC is just for more uniform naming of variables. --- g10/encrypt.c | 2 +- g10/pkglue.c | 64 +++++++++++++++++++++++++++------------------------ g10/pkglue.h | 4 ++-- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/g10/encrypt.c b/g10/encrypt.c index f416cde53..f9818622e 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -1138,7 +1138,7 @@ write_pubkey_enc (ctrl_t ctrl, * build_packet(). */ frame = encode_session_key (pk->pubkey_algo, dek, pubkey_nbits (pk->pubkey_algo, pk->pkey)); - rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk, pk->pkey); + rc = pk_encrypt (pk, frame, enc->data); gcry_mpi_release (frame); if (rc) log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) ); diff --git a/g10/pkglue.c b/g10/pkglue.c index 037e97a14..64b5f2a06 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -417,65 +417,69 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, -/**************** +/* * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - * PK is only required to compute the fingerprint for ECDH. + * change the internal design to directly fit to libgcrypt. PK is is + * the OpenPGP public key packet, DATA is an MPI with the to be + * encrypted data, and RESARR receives the encrypted data. RESARRAY + * is expected to be an two item array which will be filled with newly + * allocated MPIs. */ -int -pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, - PKT_public_key *pk, gcry_mpi_t *pkey) +gpg_error_t +pk_encrypt (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr) { + pubkey_algo_t algo = pk->pubkey_algo; + gcry_mpi_t *pkey = pk->pkey; gcry_sexp_t s_ciph = NULL; gcry_sexp_t s_data = NULL; gcry_sexp_t s_pkey = NULL; - int rc; + gpg_error_t err; /* Make a sexp from pkey. */ if (algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E) { - rc = gcry_sexp_build (&s_pkey, NULL, + err = gcry_sexp_build (&s_pkey, NULL, "(public-key(elg(p%m)(g%m)(y%m)))", pkey[0], pkey[1], pkey[2]); /* Put DATA into a simplified S-expression. */ - if (!rc) - rc = gcry_sexp_build (&s_data, NULL, "%m", data); + if (!err) + err = gcry_sexp_build (&s_data, NULL, "%m", data); } else if (algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_E) { - rc = gcry_sexp_build (&s_pkey, NULL, + err = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); /* Put DATA into a simplified S-expression. */ - if (!rc) - rc = gcry_sexp_build (&s_data, NULL, "%m", data); + if (!err) + err = gcry_sexp_build (&s_data, NULL, "%m", data); } else if (algo == PUBKEY_ALGO_ECDH) { gcry_mpi_t k; - rc = pk_ecdh_generate_ephemeral_key (pkey, &k); - if (!rc) + err = pk_ecdh_generate_ephemeral_key (pkey, &k); + if (!err) { char *curve; curve = openpgp_oid_to_str (pkey[0]); if (!curve) - rc = gpg_error_from_syserror (); + err = gpg_error_from_syserror (); else { int with_djb_tweak_flag = openpgp_oid_is_cv25519 (pkey[0]); /* Now use the ephemeral secret to compute the shared point. */ - rc = gcry_sexp_build (&s_pkey, NULL, + err = gcry_sexp_build (&s_pkey, NULL, with_djb_tweak_flag ? "(public-key(ecdh(curve%s)(flags djb-tweak)(q%m)))" : "(public-key(ecdh(curve%s)(q%m)))", curve, pkey[1]); xfree (curve); /* Put K into a simplified S-expression. */ - if (!rc) - rc = gcry_sexp_build (&s_data, NULL, "%m", k); + if (!err) + err = gcry_sexp_build (&s_data, NULL, "%m", k); } gcry_mpi_release (k); } @@ -483,19 +487,19 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, else if (algo == PUBKEY_ALGO_KYBER) { log_debug ("Implement Kyber encryption\n"); - rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); } else - rc = gpg_error (GPG_ERR_PUBKEY_ALGO); + err = gpg_error (GPG_ERR_PUBKEY_ALGO); /* Pass it to libgcrypt. */ - if (!rc) - rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); + if (!err) + err = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); gcry_sexp_release (s_data); gcry_sexp_release (s_pkey); - if (rc) + if (err) ; else if (algo == PUBKEY_ALGO_ECDH) { @@ -508,10 +512,10 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, shared = get_data_from_sexp (s_ciph, "s", &nshared); if (!shared) { - rc = gpg_error_from_syserror (); + err = gpg_error_from_syserror (); goto leave; } - rc = sexp_extract_param_sos (s_ciph, "e", &public); + err = sexp_extract_param_sos (s_ciph, "e", &public); gcry_sexp_release (s_ciph); s_ciph = NULL; if (DBG_CRYPTO) @@ -524,15 +528,15 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, result = NULL; fingerprint_from_pk (pk, fp, NULL); - if (!rc) + if (!err) { unsigned int nbits; byte *p = gcry_mpi_get_opaque (data, &nbits); - rc = pk_ecdh_encrypt_with_shared_point (shared, nshared, fp, p, + err = pk_ecdh_encrypt_with_shared_point (shared, nshared, fp, p, (nbits+7)/8, pkey, &result); } xfree (shared); - if (!rc) + if (!err) { resarr[0] = public; resarr[1] = result; @@ -553,7 +557,7 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, leave: gcry_sexp_release (s_ciph); - return rc; + return err; } diff --git a/g10/pkglue.h b/g10/pkglue.h index abeddb811..609c17b49 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -31,8 +31,8 @@ gpg_error_t sexp_extract_param_sos_nlz (gcry_sexp_t sexp, const char *param, int pk_verify (pubkey_algo_t algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey); -int pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, - PKT_public_key *pk, gcry_mpi_t *pkey); +gpg_error_t pk_encrypt (PKT_public_key *pk, gcry_mpi_t data, + gcry_mpi_t *resarr); int pk_check_secret_key (pubkey_algo_t algo, gcry_mpi_t *skey); From b48476bbefa70cf56ba48089b0dbdfd09cccc917 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 12 Apr 2024 11:31:01 +0200 Subject: [PATCH 436/869] gpg: Prepare to use the fingerprint as fixed-info for Kyber. * g10/pubkey-enc.c (get_it): Use algo and fingerprint for the fixed-info. Keep a testing mode. * g10/options.h (COMPAT_T7014_OLD): New. * g10/gpg.c (compatibility_flags): Add "t71014-old" flag. -- GnuPG-bug-id: 6815 --- g10/gpg.c | 1 + g10/options.h | 5 ++--- g10/pubkey-enc.c | 24 +++++++++++++++++++----- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/g10/gpg.c b/g10/gpg.c index 2afcd91ad..0c80a558b 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1034,6 +1034,7 @@ static struct debug_flags_s debug_flags [] = static struct compatibility_flags_s compatibility_flags [] = { { COMPAT_PARALLELIZED, "parallelized" }, + { COMPAT_T7014_OLD, "t7014-old" }, { 0, NULL } }; diff --git a/g10/options.h b/g10/options.h index ed8e122a3..e810adfb9 100644 --- a/g10/options.h +++ b/g10/options.h @@ -378,9 +378,8 @@ EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode; EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; /* Compatibility flags */ -#define COMPAT_PARALLELIZED 1 - -/* #define COMPAT_FOO 2 */ +#define COMPAT_PARALLELIZED 1 /* Use threaded hashing for signatures. */ +#define COMPAT_T7014_OLD 2 /* Use initial T7014 test data. */ /* Compliance test macors. */ diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index da32ebc7b..470525a95 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -240,15 +240,29 @@ get_it (ctrl_t ctrl, } else if (sk->pubkey_algo == PUBKEY_ALGO_KYBER) { - log_debug ("seskey_algo: %d\n", enc->seskey_algo); + char fixedinfo[1+MAX_FINGERPRINT_LEN]; + int fixedlen; + + if ((opt.compat_flags & COMPAT_T7014_OLD)) + { + /* Temporary use for tests with original test vectors. */ + fixedinfo[0] = 0x69; + fixedlen = 1; + } + else + { + fixedinfo[0] = enc->seskey_algo; + v5_fingerprint_from_pk (sk, fixedinfo+1, NULL); + fixedlen = 33; + } + if (!enc->data[0] || !enc->data[1] || !enc->data[2]) err = gpg_error (GPG_ERR_BAD_MPI); else err = gcry_sexp_build (&s_data, NULL, - "(enc-val(pqc(e%m)(k%m)(s%m)(c%d)(fixed-info%s)))", - enc->data[0], enc->data[1], enc->data[2], - enc->seskey_algo, - "\x69"); + "(enc-val(pqc(e%m)(k%m)(s%m)(c%d)(fixed-info%b)))", + enc->data[0], enc->data[1], enc->data[2], + enc->seskey_algo, fixedlen, fixedinfo); } else err = gpg_error (GPG_ERR_BUG); From 35ef87d8d9db42c3077996317781986a692552cc Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 15 Apr 2024 10:23:25 +0900 Subject: [PATCH 437/869] scd:openpgp: Robust Data Object handling for constructed case. * scd/app-openpgp.c (get_cached_data): When it comes with its tag and length for the constructed Data Object, remove them. -- GnuPG-bug-id: 7058 Signed-off-by: NIIBE Yutaka --- scd/app-openpgp.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 26ac91ea2..c2a8d5ffe 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -410,6 +410,10 @@ get_cached_data (app_t app, int tag, size_t len; struct cache_s *c; int exmode; + int do_constructed = 0; + + if ((tag < 0x0100 && (tag & 0x20)) || (tag >= 0x0100 && (tag & 0x2000))) + do_constructed = 1; *result = NULL; *resultlen = 0; @@ -452,6 +456,52 @@ get_cached_data (app_t app, int tag, err = iso7816_get_data (app_get_slot (app), exmode, tag, &p, &len); if (err) return err; + + /* When Data Object is constructed, when it comes with its tag and + length, remove them before storing it into the cache, because + it's redundant and takes space. This handling also works well + with the card implementation which doesn't include its tag and + length for the DO value returned by GET DATA. */ + if (do_constructed) + { + if (len && tag < 0x0100 && p[0] == tag) + { + if (len >= 2 && p[1] < 0x80 && p[1] == len - 2) + { + len -= 2; + memmove (p, p+2, len); + } + else if (len >= 3 && p[1] == 0x81 && p[2] == len - 3) + { + len -= 3; + memmove (p, p+3, len); + } + else if (len >= 4 && p[1] == 0x82 && ((p[2] << 8) | p[3]) == len - 4) + { + len -= 4; + memmove (p, p+4, len); + } + } + else if (len >= 2 && tag >= 0x0100 && ((p[0] << 8) | p[1]) == tag) + { + if (len >= 3 && p[2] < 0x80 && p[2] == len - 2) + { + len -= 3; + memmove (p, p+3, len); + } + else if (len >= 4 && p[2] == 0x81 && p[3] == len - 3) + { + len -= 4; + memmove (p, p+4, len); + } + else if (len >= 5 && p[2] == 0x82 && ((p[3] << 8) | p[4]) == len - 4) + { + len -= 5; + memmove (p, p+5, len); + } + } + } + if (len) *result = p; *resultlen = len; From 4c20d2d2739547298a04022947559d4f63541679 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 15 Apr 2024 09:23:16 +0200 Subject: [PATCH 438/869] gpg: Add arg session_algo to pk_decrypt. * common/kem.c: Move constants to the top. Add some documentation. * g10/pkglue.c (pk_encrypt): Add arguments session_key and factor code out to ... (do_encrypt_rsa_elg): here, (do_encrypt_ecdh): and here, (do_encrypt_kem): and here. * g10/encrypt.c (write_pubkey_enc): Call with session key algorithm. -- This makes it easier to review the code. --- common/kem.c | 32 ++++-- g10/encrypt.c | 2 +- g10/pkglue.c | 286 ++++++++++++++++++++++++++++---------------------- g10/pkglue.h | 2 +- 4 files changed, 188 insertions(+), 134 deletions(-) diff --git a/common/kem.c b/common/kem.c index c5de8b102..7227898d1 100644 --- a/common/kem.c +++ b/common/kem.c @@ -23,9 +23,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copies of the GNU General Public License + * You should have received copies of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, see . + * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later) */ #include @@ -35,7 +36,18 @@ #include #include "mischelp.h" + +/* domSeperation as per *PGP specs. */ +#define KMAC_KEY "OpenPGPCompositeKeyDerivationFunction" + +/* customizationString as per *PGP specs. */ +#define KMAC_CUSTOM "KDF" + +/* The blocksize used for Keccak by compute_kmac256. */ #define KECCAK512_BLOCKSIZE 136 + + + static gpg_error_t compute_kmac256 (void *digest, size_t digestlen, const void *key, size_t keylen, @@ -163,14 +175,16 @@ gnupg_ecc_kem_kdf (void *kek, size_t kek_len, return 0; } - -/* domSeperation */ -#define KMAC_KEY "OpenPGPCompositeKeyDerivationFunction" - -/* customizationString */ -#define KMAC_CUSTOM "KDF" - -/* Compute KEK by combining two KEMs. */ +/* Compute KEK by combining two KEMs. The caller provides a buffer + * KEK allocated with size KEK_LEN which will receive the computed + * KEK. (ECC_SS, ECC_SS_LEN) is the shared secret of the first key. + * (ECC_CT, ECC_CT_LEN) is the ciphertext of the first key. + * (MLKEM_SS, ECC_SS_LEN) is the shared secret of the second key. + * (MLKEM_CT, MLKEM_CT_LEN) is the ciphertext of the second key. + * (FIXEDINFO, FIXEDINFO_LEN) is an octet string used to bind the KEK + * to a the key; for PGP we use the concatenation of the session key's + * algorithm id and the v5 fingerprint of the key. + */ gpg_error_t gnupg_kem_combiner (void *kek, size_t kek_len, const void *ecc_ss, size_t ecc_ss_len, diff --git a/g10/encrypt.c b/g10/encrypt.c index f9818622e..8ce6164ce 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -1138,7 +1138,7 @@ write_pubkey_enc (ctrl_t ctrl, * build_packet(). */ frame = encode_session_key (pk->pubkey_algo, dek, pubkey_nbits (pk->pubkey_algo, pk->pkey)); - rc = pk_encrypt (pk, frame, enc->data); + rc = pk_encrypt (pk, frame, dek->algo, enc->data); gcry_mpi_release (frame); if (rc) log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) ); diff --git a/g10/pkglue.c b/g10/pkglue.c index 64b5f2a06..52d8c1012 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -1,6 +1,7 @@ /* pkglue.c - public key operations glue code * Copyright (C) 2000, 2003, 2010 Free Software Foundation, Inc. * Copyright (C) 2014 Werner Koch + * Copyright (C) 2024 g10 Code GmbH. * * This file is part of GnuPG. * @@ -16,6 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . + * SPDX-License-Identifier: GPL-3.0-or-later */ #include @@ -415,18 +417,120 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, } +/* Core of the encryption for KEM algorithms. See pk_decrypt for a + * description of the arguments. */ +static gpg_error_t +do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, + gcry_mpi_t *resarr) +{ + + log_debug ("Implement Kyber encryption\n"); + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} -/* - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. PK is is - * the OpenPGP public key packet, DATA is an MPI with the to be - * encrypted data, and RESARR receives the encrypted data. RESARRAY - * is expected to be an two item array which will be filled with newly - * allocated MPIs. - */ -gpg_error_t -pk_encrypt (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr) +/* Core of the encryption for the ECDH algorithms. See pk_decrypt for + * a description of the arguments. */ +static gpg_error_t +do_encrypt_ecdh (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr) +{ + gcry_mpi_t *pkey = pk->pkey; + gcry_sexp_t s_ciph = NULL; + gcry_sexp_t s_data = NULL; + gcry_sexp_t s_pkey = NULL; + gpg_error_t err; + gcry_mpi_t k = NULL; + char *curve = NULL; + int with_djb_tweak_flag; + gcry_mpi_t public = NULL; + gcry_mpi_t result = NULL; + byte fp[MAX_FINGERPRINT_LEN]; + byte *shared = NULL; + byte *p; + size_t nshared; + unsigned int nbits; + + err = pk_ecdh_generate_ephemeral_key (pkey, &k); + if (err) + goto leave; + + curve = openpgp_oid_to_str (pkey[0]); + if (!curve) + { + err = gpg_error_from_syserror (); + goto leave; + } + + with_djb_tweak_flag = openpgp_oid_is_cv25519 (pkey[0]); + + /* Now use the ephemeral secret to compute the shared point. */ + err = gcry_sexp_build (&s_pkey, NULL, + with_djb_tweak_flag ? + "(public-key(ecdh(curve%s)(flags djb-tweak)(q%m)))" + : "(public-key(ecdh(curve%s)(q%m)))", + curve, pkey[1]); + if (err) + goto leave; + + /* Put K into a simplified S-expression. */ + err = gcry_sexp_build (&s_data, NULL, "%m", k); + if (err) + goto leave; + + /* Run encryption. */ + err = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); + if (err) + goto leave; + + gcry_sexp_release (s_data); s_data = NULL; + gcry_sexp_release (s_pkey); s_pkey = NULL; + + + /* Get the shared point and the ephemeral public key. */ + shared = get_data_from_sexp (s_ciph, "s", &nshared); + if (!shared) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = sexp_extract_param_sos (s_ciph, "e", &public); + gcry_sexp_release (s_ciph); s_ciph = NULL; + if (DBG_CRYPTO) + { + log_debug ("ECDH ephemeral key:"); + gcry_mpi_dump (public); + log_printf ("\n"); + } + + fingerprint_from_pk (pk, fp, NULL); + + p = gcry_mpi_get_opaque (data, &nbits); + result = NULL; + err = pk_ecdh_encrypt_with_shared_point (shared, nshared, fp, p, + (nbits+7)/8, pkey, &result); + if (err) + goto leave; + + resarr[0] = public; public = NULL; + resarr[1] = result; result = NULL; + + leave: + gcry_mpi_release (public); + gcry_mpi_release (result); + xfree (shared); + gcry_sexp_release (s_ciph); + gcry_sexp_release (s_data); + gcry_sexp_release (s_pkey); + xfree (curve); + gcry_mpi_release (k); + return err; +} + + +/* Core of the encryption for RSA and Elgamal algorithms. See + * pk_decrypt for a description of the arguments. */ +static gpg_error_t +do_encrypt_rsa_elg (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr) { pubkey_algo_t algo = pk->pubkey_algo; gcry_mpi_t *pkey = pk->pkey; @@ -435,132 +539,68 @@ pk_encrypt (PKT_public_key *pk, gcry_mpi_t data, gcry_mpi_t *resarr) gcry_sexp_t s_pkey = NULL; gpg_error_t err; - /* Make a sexp from pkey. */ if (algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E) - { - err = gcry_sexp_build (&s_pkey, NULL, - "(public-key(elg(p%m)(g%m)(y%m)))", - pkey[0], pkey[1], pkey[2]); - /* Put DATA into a simplified S-expression. */ - if (!err) - err = gcry_sexp_build (&s_data, NULL, "%m", data); - } - else if (algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_E) - { - err = gcry_sexp_build (&s_pkey, NULL, - "(public-key(rsa(n%m)(e%m)))", - pkey[0], pkey[1]); - /* Put DATA into a simplified S-expression. */ - if (!err) - err = gcry_sexp_build (&s_data, NULL, "%m", data); - } - else if (algo == PUBKEY_ALGO_ECDH) - { - gcry_mpi_t k; - - err = pk_ecdh_generate_ephemeral_key (pkey, &k); - if (!err) - { - char *curve; - - curve = openpgp_oid_to_str (pkey[0]); - if (!curve) - err = gpg_error_from_syserror (); - else - { - int with_djb_tweak_flag = openpgp_oid_is_cv25519 (pkey[0]); - - /* Now use the ephemeral secret to compute the shared point. */ - err = gcry_sexp_build (&s_pkey, NULL, - with_djb_tweak_flag ? - "(public-key(ecdh(curve%s)(flags djb-tweak)(q%m)))" - : "(public-key(ecdh(curve%s)(q%m)))", - curve, pkey[1]); - xfree (curve); - /* Put K into a simplified S-expression. */ - if (!err) - err = gcry_sexp_build (&s_data, NULL, "%m", k); - } - gcry_mpi_release (k); - } - } - else if (algo == PUBKEY_ALGO_KYBER) - { - log_debug ("Implement Kyber encryption\n"); - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - } + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(elg(p%m)(g%m)(y%m)))", + pkey[0], pkey[1], pkey[2]); else - err = gpg_error (GPG_ERR_PUBKEY_ALGO); - - /* Pass it to libgcrypt. */ - if (!err) - err = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); - - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(rsa(n%m)(e%m)))", + pkey[0], pkey[1]); if (err) - ; - else if (algo == PUBKEY_ALGO_ECDH) - { - gcry_mpi_t public, result; - byte fp[MAX_FINGERPRINT_LEN]; - byte *shared; - size_t nshared; + goto leave; - /* Get the shared point and the ephemeral public key. */ - shared = get_data_from_sexp (s_ciph, "s", &nshared); - if (!shared) - { - err = gpg_error_from_syserror (); - goto leave; - } - err = sexp_extract_param_sos (s_ciph, "e", &public); - gcry_sexp_release (s_ciph); - s_ciph = NULL; - if (DBG_CRYPTO) - { - log_debug ("ECDH ephemeral key:"); - gcry_mpi_dump (public); - log_printf ("\n"); - } + err = gcry_sexp_build (&s_data, NULL, "%m", data); + if (err) + goto leave; - result = NULL; - fingerprint_from_pk (pk, fp, NULL); + err = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); + if (err) + goto leave; - if (!err) - { - unsigned int nbits; - byte *p = gcry_mpi_get_opaque (data, &nbits); - err = pk_ecdh_encrypt_with_shared_point (shared, nshared, fp, p, - (nbits+7)/8, pkey, &result); - } - xfree (shared); - if (!err) - { - resarr[0] = public; - resarr[1] = result; - } - else - { - gcry_mpi_release (public); - gcry_mpi_release (result); - } - } - else /* Elgamal or RSA case. */ - { /* Fixme: Add better error handling or make gnupg use - S-expressions directly. */ - resarr[0] = get_mpi_from_sexp (s_ciph, "a", GCRYMPI_FMT_USG); - if (!is_RSA (algo)) - resarr[1] = get_mpi_from_sexp (s_ciph, "b", GCRYMPI_FMT_USG); - } + gcry_sexp_release (s_data); s_data = NULL; + gcry_sexp_release (s_pkey); s_pkey = NULL; + + resarr[0] = get_mpi_from_sexp (s_ciph, "a", GCRYMPI_FMT_USG); + if (!is_RSA (algo)) + resarr[1] = get_mpi_from_sexp (s_ciph, "b", GCRYMPI_FMT_USG); leave: + gcry_sexp_release (s_data); + gcry_sexp_release (s_pkey); gcry_sexp_release (s_ciph); return err; } +/* + * Emulate our old PK interface here - sometime in the future we might + * change the internal design to directly fit to libgcrypt. PK is is + * the OpenPGP public key packet, DATA is an MPI with the to be + * encrypted data, and RESARR receives the encrypted data. RESARRAY + * is expected to be an two item array which will be filled with newly + * allocated MPIs. SESKEY_ALGO is required for public key algorithms + * which do not encode it in DATA. + */ +gpg_error_t +pk_encrypt (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, + gcry_mpi_t *resarr) +{ + pubkey_algo_t algo = pk->pubkey_algo; + + if (algo == PUBKEY_ALGO_KYBER) + return do_encrypt_kem (pk, data, seskey_algo, resarr); + else if (algo == PUBKEY_ALGO_ECDH) + return do_encrypt_ecdh (pk, data, resarr); + else if (algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E) + return do_encrypt_rsa_elg (pk, data, resarr); + else if (algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_E) + return do_encrypt_rsa_elg (pk, data, resarr); + else + return gpg_error (GPG_ERR_PUBKEY_ALGO); +} + + /* Check whether SKEY is a suitable secret key. */ int pk_check_secret_key (pubkey_algo_t pkalgo, gcry_mpi_t *skey) diff --git a/g10/pkglue.h b/g10/pkglue.h index 609c17b49..2b5c8b143 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -31,7 +31,7 @@ gpg_error_t sexp_extract_param_sos_nlz (gcry_sexp_t sexp, const char *param, int pk_verify (pubkey_algo_t algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey); -gpg_error_t pk_encrypt (PKT_public_key *pk, gcry_mpi_t data, +gpg_error_t pk_encrypt (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, gcry_mpi_t *resarr); int pk_check_secret_key (pubkey_algo_t algo, gcry_mpi_t *skey); From c736052e9ccaca8fc4662af43820090910e88122 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 15 Apr 2024 12:16:40 +0200 Subject: [PATCH 439/869] gpg: Implement Kyber encryption. * g10/build-packet.c (do_pubkey_enc): Support Kyber. * g10/pkglue.c (do_encrypt_kem): Implement. -- Note that the code does only work for ky768_cv25519 for now. GnuPG-bug-id: 6815 --- g10/build-packet.c | 9 +- g10/pkglue.c | 209 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 214 insertions(+), 4 deletions(-) diff --git a/g10/build-packet.c b/g10/build-packet.c index fd315b313..606c5c2d8 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -987,9 +987,14 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) if (enc->pubkey_algo == PUBKEY_ALGO_KYBER && i == 2) iobuf_put (a, enc->seskey_algo); - if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1) + if (i == 1 && enc->pubkey_algo == PUBKEY_ALGO_ECDH) rc = gpg_mpi_write_opaque_nohdr (a, enc->data[i]); - else if (enc->pubkey_algo == PUBKEY_ALGO_ECDH) + else if (i == 1 && enc->pubkey_algo == PUBKEY_ALGO_KYBER) + rc = gpg_mpi_write_opaque_32 (a, enc->data[i], NULL); + else if (i == 2 && enc->pubkey_algo == PUBKEY_ALGO_KYBER) + rc = gpg_mpi_write_opaque_nohdr (a, enc->data[i]); + else if (enc->pubkey_algo == PUBKEY_ALGO_ECDH + || enc->pubkey_algo == PUBKEY_ALGO_KYBER) rc = sos_write (a, enc->data[i], NULL); else rc = gpg_mpi_write (a, enc->data[i], NULL); diff --git a/g10/pkglue.c b/g10/pkglue.c index 52d8c1012..0167e80e3 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -423,9 +423,214 @@ static gpg_error_t do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, gcry_mpi_t *resarr) { + gpg_error_t err; + int i; + unsigned int nbits, n; + gcry_sexp_t s_data = NULL; + gcry_cipher_hd_t hd = NULL; - log_debug ("Implement Kyber encryption\n"); - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + const unsigned char *ecc_pubkey; + size_t ecc_pubkey_len; + const unsigned char *kyber_pubkey; + size_t kyber_pubkey_len; + const unsigned char *seskey; + size_t seskey_len; + unsigned char *enc_seskey = NULL; + size_t enc_seskey_len; + + unsigned char ecc_ct[GCRY_KEM_ECC_X25519_ENCAPS_LEN]; + size_t ecc_ct_len = GCRY_KEM_ECC_X25519_ENCAPS_LEN; + unsigned char ecc_ecdh[GCRY_KEM_RAW_X25519_SHARED_LEN]; + size_t ecc_ecdh_len = GCRY_KEM_RAW_X25519_SHARED_LEN; + unsigned char ecc_ss[GCRY_KEM_RAW_X25519_SHARED_LEN]; + size_t ecc_ss_len = GCRY_KEM_RAW_X25519_SHARED_LEN; + + unsigned char kyber_ct[GCRY_KEM_MLKEM768_ENCAPS_LEN]; + size_t kyber_ct_len = GCRY_KEM_MLKEM768_ENCAPS_LEN; + unsigned char kyber_ss[GCRY_KEM_MLKEM768_SHARED_LEN]; + size_t kyber_ss_len = GCRY_KEM_MLKEM768_SHARED_LEN; + + char fixedinfo[1+MAX_FINGERPRINT_LEN]; + int fixedlen; + + unsigned char kek[32]; /* AES-256 is mandatory. */ + size_t kek_len = 32; + + /* For later error checking we make sure the array is cleared. */ + resarr[0] = resarr[1] = resarr[2] = NULL; + + /* As of now we use KEM only for the combined Kyber and thus a + * second public key is expected. Right now we take the keys + * directly from the PK->data elements. */ + + /* FIXME: This is only for cv25519 */ + ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits); + ecc_pubkey_len = (nbits+7)/8; + if (ecc_pubkey_len != 33) + { + if (opt.verbose) + log_info ("%s: ECC public key length invalid (%zu)\n", + __func__, ecc_pubkey_len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + ecc_pubkey++; /* Remove the 0x40 prefix. */ + ecc_pubkey_len--; + if (DBG_CRYPTO) + log_printhex (ecc_pubkey, ecc_pubkey_len, "ECC pubkey:"); + + err = gcry_kem_encap (GCRY_KEM_RAW_X25519, + ecc_pubkey, ecc_pubkey_len, + ecc_ct, ecc_ct_len, + ecc_ecdh, ecc_ecdh_len, + NULL, 0); + if (err) + { + if (opt.verbose) + log_info ("%s: gcry_kem_encap for ECC failed\n", __func__); + goto leave; + } + if (DBG_CRYPTO) + { + log_printhex (ecc_ct, ecc_ct_len, "ECC ephem:"); + log_printhex (ecc_ecdh, ecc_ecdh_len, "ECC ecdh:"); + } + err = gnupg_ecc_kem_kdf (ecc_ss, ecc_ss_len, + GCRY_MD_SHA3_256, + ecc_ecdh, ecc_ecdh_len, + ecc_ct, ecc_ct_len, + ecc_pubkey, ecc_pubkey_len); + if (err) + { + if (opt.verbose) + log_info ("%s: kdf for ECC failed\n", __func__); + goto leave; + } + if (DBG_CRYPTO) + log_printhex (ecc_ss, ecc_ss_len, "ECC shared:"); + + /* FIXME: This is only for kyber768 */ + kyber_pubkey = gcry_mpi_get_opaque (pk->pkey[2], &nbits); + kyber_pubkey_len = (nbits+7)/8; + if (kyber_pubkey_len != GCRY_KEM_MLKEM768_PUBKEY_LEN) + { + if (opt.verbose) + log_info ("%s: Kyber public key length invalid (%zu)\n", + __func__, kyber_pubkey_len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + if (DBG_CRYPTO) + log_printhex (kyber_pubkey, kyber_pubkey_len, "|!trunc|Kyber pubkey:"); + + err = gcry_kem_encap (GCRY_KEM_MLKEM768, + kyber_pubkey, kyber_pubkey_len, + kyber_ct, kyber_ct_len, + kyber_ss, kyber_ss_len, + NULL, 0); + if (err) + { + if (opt.verbose) + log_info ("%s: gcry_kem_encap for ECC failed\n", __func__); + goto leave; + } + + if (DBG_CRYPTO) + { + log_printhex (kyber_ct, kyber_ct_len, "|!trunc|Kyber ephem:"); + log_printhex (kyber_ss, kyber_ss_len, "Kyber shared:"); + } + + + fixedinfo[0] = seskey_algo; + v5_fingerprint_from_pk (pk, fixedinfo+1, NULL); + fixedlen = 33; + + err = gnupg_kem_combiner (kek, kek_len, + ecc_ss, ecc_ss_len, ecc_ct, ecc_ct_len, + kyber_ss, kyber_ss_len, kyber_ct, kyber_ct_len, + fixedinfo, fixedlen); + if (err) + { + if (opt.verbose) + log_info ("%s: KEM combiner failed\n", __func__); + goto leave; + } + if (DBG_CRYPTO) + log_printhex (kek, kek_len, "KEK:"); + + err = gcry_cipher_open (&hd, GCRY_CIPHER_AES256, + GCRY_CIPHER_MODE_AESWRAP, 0); + if (!err) + err = gcry_cipher_setkey (hd, kek, kek_len); + if (err) + { + if (opt.verbose) + log_error ("%s: failed to initialize AESWRAP: %s\n", __func__, + gpg_strerror (err)); + goto leave; + } + + err = gcry_sexp_build (&s_data, NULL, "%m", data); + if (err) + goto leave; + + n = gcry_cipher_get_algo_keylen (seskey_algo); + seskey = gcry_mpi_get_opaque (data, &nbits); + seskey_len = (nbits+7)/8; + if (seskey_len != n) + { + if (opt.verbose) + log_info ("%s: session key length %zu" + " does not match the length for algo %d\n", + __func__, seskey_len, seskey_algo); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + if (DBG_CRYPTO) + log_printhex (seskey, seskey_len, "seskey:"); + + enc_seskey_len = 1 + seskey_len + 8; + enc_seskey = xtrymalloc (enc_seskey_len); + if (!enc_seskey || enc_seskey_len > 254) + { + err = gpg_error_from_syserror (); + goto leave; + } + + enc_seskey[0] = enc_seskey_len - 1; + err = gcry_cipher_encrypt (hd, enc_seskey+1, enc_seskey_len-1, + seskey, seskey_len); + if (err) + { + log_error ("%s: wrapping session key failed\n", __func__); + goto leave; + } + if (DBG_CRYPTO) + log_printhex (enc_seskey, enc_seskey_len, "enc_seskey:"); + + resarr[0] = gcry_mpi_set_opaque_copy (NULL, ecc_ct, 8 * ecc_ct_len); + if (resarr[0]) + resarr[1] = gcry_mpi_set_opaque_copy (NULL, kyber_ct, 8 * kyber_ct_len); + if (resarr[1]) + resarr[2] = gcry_mpi_set_opaque_copy (NULL, enc_seskey, 8 * enc_seskey_len); + if (!resarr[0] || !resarr[1] || !resarr[2]) + { + err = gpg_error_from_syserror (); + for (i=0; i < 3; i++) + gcry_mpi_release (resarr[i]), resarr[i] = NULL; + } + + leave: + wipememory (ecc_ct, ecc_ct_len); + wipememory (ecc_ecdh, ecc_ecdh_len); + wipememory (ecc_ss, ecc_ss_len); + wipememory (kyber_ct, kyber_ct_len); + wipememory (kyber_ss, kyber_ss_len); + wipememory (kek, kek_len); + xfree (enc_seskey); + gcry_cipher_close (hd); + return err; } From 4e32ff209d5b74603dca44ec953b848bbe1e4eaf Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 15 Apr 2024 13:25:07 +0200 Subject: [PATCH 440/869] gpg: Fix minor Kyber display things. * common/compliance.c (gnupg_pk_is_compliant): Make Kyber known. * g10/misc.c (openpgp_pk_algo_name): Add "Kyber". --- common/compliance.c | 10 +++++++++- g10/misc.c | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/common/compliance.c b/common/compliance.c index 84449af25..2df10d2e2 100644 --- a/common/compliance.c +++ b/common/compliance.c @@ -139,7 +139,7 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo, gcry_mpi_t key[], unsigned int keylength, const char *curvename) { - enum { is_rsa, is_dsa, is_elg, is_ecc } algotype; + enum { is_rsa, is_dsa, is_elg, is_ecc, is_kem } algotype; int result = 0; if (! initialized) @@ -173,6 +173,10 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo, case PUBKEY_ALGO_ELGAMAL: return 0; /* Signing with Elgamal is not at all supported. */ + case PUBKEY_ALGO_KYBER: + algotype = is_kem; + break; + default: /* Unknown. */ return 0; } @@ -227,6 +231,10 @@ gnupg_pk_is_compliant (enum gnupg_compliance_mode compliance, int algo, || !strcmp (curvename, "brainpoolP512r1"))); break; + case is_kem: + result = 0; + break; + default: result = 0; } diff --git a/g10/misc.c b/g10/misc.c index 1359987d2..c52091830 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -836,6 +836,7 @@ openpgp_pk_algo_name (pubkey_algo_t algo) case PUBKEY_ALGO_ECDH: return "ECDH"; case PUBKEY_ALGO_ECDSA: return "ECDSA"; case PUBKEY_ALGO_EDDSA: return "EDDSA"; + case PUBKEY_ALGO_KYBER: return "Kyber"; default: return "?"; } } From 2a71c3cf97c44ab7531f8128cb66bf697eb78035 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Apr 2024 18:31:29 +0200 Subject: [PATCH 441/869] gpg: Make --with-subkey-fingerprint the default. * g10/gpg.c (oWithoutSubkeyFingerprint): New. (opts): Add "without-subkey-fingerprint". (main): Make --with-subkey-fingerprint the default. Implementation the without option. -- Given that the default for the keyid format is none, the subkey fingerprints are important to do anything with a subkey. Thus we make the old option the default and provide a new option to revert it. --- doc/gpg.texi | 7 +++++-- g10/gpg.c | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 2ddc16342..f5a6fdd4d 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2893,12 +2893,15 @@ Same as the command @option{--fingerprint} but changes only the format of the output and may be used together with another command. @item --with-subkey-fingerprint +@itemx --without-subkey-fingerprint @opindex with-subkey-fingerprint +@opindex without-subkey-fingerprint If a fingerprint is printed for the primary key, this option forces printing of the fingerprint for all subkeys. This could also be achieved by using the @option{--with-fingerprint} twice but by using -this option along with keyid-format "none" a compact fingerprint is -printed. +this option along with the default keyid-format "none" a compact +fingerprint is printed. Since version 2.6.0 this option is active by +default; use the ``without'' variant to disable it. @item --with-v5-fingerprint @opindex with-v5-fingerprint diff --git a/g10/gpg.c b/g10/gpg.c index 0c80a558b..e8894ab4a 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -206,6 +206,7 @@ enum cmd_and_opt_values oWithV5Fingerprint, oWithFingerprint, oWithSubkeyFingerprint, + oWithoutSubkeyFingerprint, oWithICAOSpelling, oWithKeygrip, oWithKeyScreening, @@ -824,6 +825,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"), ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprint", "@"), ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"), + ARGPARSE_s_n (oWithoutSubkeyFingerprint, "without-subkey-fingerprint", "@"), ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"), ARGPARSE_s_n (oWithKeygrip, "with-keygrip", "@"), ARGPARSE_s_n (oWithKeyScreening,"with-key-screening", "@"), @@ -2503,6 +2505,7 @@ main (int argc, char **argv) opt.passphrase_repeat = 1; opt.emit_version = 0; opt.weak_digests = NULL; + opt.with_subkey_fingerprint = 1; opt.compliance = CO_GNUPG; /* Check special options given on the command line. */ @@ -2909,6 +2912,9 @@ main (int argc, char **argv) case oWithSubkeyFingerprint: opt.with_subkey_fingerprint = 1; break; + case oWithoutSubkeyFingerprint: + opt.with_subkey_fingerprint = 0; + break; case oWithICAOSpelling: opt.with_icao_spelling = 1; break; From 21f7ad563d9bcb6d295e8f313f29b14238e7481f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 Apr 2024 11:42:20 +0200 Subject: [PATCH 442/869] gpg: New command --quick-set-ownertrust. * g10/gpg.c (aQuickSetOwnertrust): New. (opts): Add new command. (main): Implement it. * g10/keyedit.c (keyedit_quick_set_ownertrust): New. --- doc/gpg.texi | 9 +++++- g10/gpg.c | 13 ++++++++ g10/keyedit.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++- g10/keyedit.h | 2 ++ 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index f5a6fdd4d..2fe6a8448 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1223,12 +1223,19 @@ all affected self-signatures is set one second ahead. This command updates the preference list of the key to the current default value (either built-in or set via @option{--default-preference-list}). This is the unattended version -of of using "setpref" in the @option{--key-edit} menu without giving a +of using "setpref" in the @option{--key-edit} menu without giving a list. Note that you can show the preferences in a key listing by using @option{--list-options show-pref} or @option{--list-options show-pref-verbose}. You should also re-distribute updated keys to your peers. +@item --quick-set-ownertrust @var{user-id} @var{value} +@opindex quick-set-ownertrust +This command sets the ownertrust of a key and can also be used to set +the disable flag of a key. This is the unattended version of using +"trust", "disable", or "enable" in the @option{--key-edit} menu. + + @item --change-passphrase @var{user-id} @opindex change-passphrase @itemx --passwd @var{user-id} diff --git a/g10/gpg.c b/g10/gpg.c index e8894ab4a..7cb83c443 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -136,6 +136,7 @@ enum cmd_and_opt_values aQuickSetExpire, aQuickSetPrimaryUid, aQuickUpdatePref, + aQuickSetOwnertrust, aListConfig, aListGcryptConfig, aGPGConfList, @@ -504,6 +505,7 @@ static gpgrt_opt_t opts[] = { N_("quickly set a new expiration date")), ARGPARSE_c (aQuickSetPrimaryUid, "quick-set-primary-uid", "@"), ARGPARSE_c (aQuickUpdatePref, "quick-update-pref", "@"), + ARGPARSE_c (aQuickSetOwnertrust, "quick-set-ownertrust", "@"), ARGPARSE_c (aFullKeygen, "full-generate-key" , N_("full featured key pair generation")), ARGPARSE_c (aFullKeygen, "full-gen-key", "@"), @@ -2722,6 +2724,7 @@ main (int argc, char **argv) case aQuickSetExpire: case aQuickSetPrimaryUid: case aQuickUpdatePref: + case aQuickSetOwnertrust: case aExportOwnerTrust: case aImportOwnerTrust: case aRebuildKeydbCaches: @@ -4405,6 +4408,7 @@ main (int argc, char **argv) case aQuickRevUid: case aQuickSetPrimaryUid: case aQuickUpdatePref: + case aQuickSetOwnertrust: case aFullKeygen: case aKeygen: case aImport: @@ -4926,6 +4930,15 @@ main (int argc, char **argv) } break; + case aQuickSetOwnertrust: + { + if (argc != 2) + wrong_args ("--quick-set-ownertrust USER-ID" + " [enable|disable|full|...]"); + keyedit_quick_set_ownertrust (ctrl, argv[0], argv[1]); + } + break; + case aFastImport: opt.import_options |= IMPORT_FAST; /* fall through */ case aImport: diff --git a/g10/keyedit.c b/g10/keyedit.c index a09797a36..81ea06c24 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -2755,6 +2755,87 @@ keyedit_quick_update_pref (ctrl_t ctrl, const char *username) } +/* Unattended updating of the ownertrust or disable/enable state of a key + * USERNAME specifies the key. This is somewhat similar to + * gpg --edit-key trust save + * gpg --edit-key disable save + * + * VALUE is the new trust value which is one of: + * "undefined" - Ownertrust is set to undefined + * "never" - Ownertrust is set to never trust + * "marginal" - Ownertrust is set to marginal trust + * "full" - Ownertrust is set to full trust + * "ultimate" - Ownertrust is set to ultimate trust + * "enable" - The key is re-enabled. + * "disable" - The key is disabled. + * Trust settings do not change the ebable/disable state. + */ +void +keyedit_quick_set_ownertrust (ctrl_t ctrl, const char *username, + const char *value) +{ + gpg_error_t err; + KEYDB_HANDLE kdbhd = NULL; + kbnode_t keyblock = NULL; + PKT_public_key *pk; + unsigned int trust, newtrust; + int x; + int maybe_update_trust = 0; + +#ifdef HAVE_W32_SYSTEM + /* See keyedit_menu for why we need this. */ + check_trustdb_stale (ctrl); +#endif + + /* Search the key; we don't want the whole getkey stuff here. Note + * that we are looking for the public key here. */ + err = quick_find_keyblock (ctrl, username, 0, &kdbhd, &keyblock); + if (err) + goto leave; + log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY + || keyblock->pkt->pkttype == PKT_SECRET_KEY); + pk = keyblock->pkt->pkt.public_key; + + trust = newtrust = get_ownertrust (ctrl, pk); + + if (!ascii_strcasecmp (value, "enable")) + newtrust &= ~TRUST_FLAG_DISABLED; + else if (!ascii_strcasecmp (value, "disable")) + newtrust |= TRUST_FLAG_DISABLED; + else if ((x = string_to_trust_value (value)) >= 0) + { + newtrust = x; + newtrust &= TRUST_MASK; + newtrust |= (trust & ~TRUST_MASK); + maybe_update_trust = 1; + } + else + { + err = gpg_error (GPG_ERR_INV_ARG); + goto leave; + } + + if (trust != newtrust) + { + update_ownertrust (ctrl, pk, newtrust); + if (maybe_update_trust) + revalidation_mark (ctrl); + } + else if (opt.verbose) + log_info (_("Key not changed so no update needed.\n")); + + leave: + if (err) + { + log_error (_("setting the ownertrust to '%s' failed: %s\n"), + value, gpg_strerror (err)); + write_status_error ("keyedit.setownertrust", err); + } + release_kbnode (keyblock); + keydb_release (kdbhd); +} + + /* Find a keyblock by fingerprint because only this uniquely * identifies a key and may thus be used to select a key for * unattended subkey creation os key signing. */ @@ -2999,7 +3080,7 @@ keyedit_quick_revsig (ctrl_t ctrl, const char *username, const char *sigtorev, check_trustdb_stale (ctrl); #endif - /* Search the key; we don't want the whole getkey stuff here. Noet + /* Search the key; we don't want the whole getkey stuff here. Note * that we are looking for the public key here. */ err = quick_find_keyblock (ctrl, username, 0, &kdbhd, &keyblock); if (err) diff --git a/g10/keyedit.h b/g10/keyedit.h index abf7314af..7cb01268e 100644 --- a/g10/keyedit.h +++ b/g10/keyedit.h @@ -57,6 +57,8 @@ void keyedit_quick_set_expire (ctrl_t ctrl, void keyedit_quick_set_primary (ctrl_t ctrl, const char *username, const char *primaryuid); void keyedit_quick_update_pref (ctrl_t ctrl, const char *username); +void keyedit_quick_set_ownertrust (ctrl_t ctrl, const char *username, + const char *value); void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock, int print_sec); int keyedit_print_one_sig (ctrl_t ctrl, estream_t fp, int rc, kbnode_t keyblock, From 7d6ad2866722aaa27b33338d0fbb33c7b6b94808 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 Apr 2024 12:16:20 +0200 Subject: [PATCH 443/869] gpg: Mark disabled keys and add show-ownertrust list option. * g10/options.h (LIST_SHOW_OWNERTRUST): New. * g10/keylist.c (print_key_line): Show wonertrust and always show whether a key is disabled. * g10/gpg.c (parse_list_options): Add "show-ownertrust". * g10/gpgv.c (get_ownertrust_string): Add stub. * g10/test-stubs.c (get_ownertrust_string): Add stub. -- Note that in a --with-colons listing the ownertrust has always been emitted and the disabled state is marked in that listing with a special 'D' usage. --- doc/gpg.texi | 5 +++++ g10/gpg.c | 2 ++ g10/gpgv.c | 8 ++++++++ g10/keylist.c | 18 ++++++++---------- g10/options.h | 1 + g10/test-stubs.c | 9 +++++++++ 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 2fe6a8448..10a1937f6 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1403,6 +1403,11 @@ give the opposite meaning. The options are: key (@code{E}=encryption, @code{S}=signing, @code{C}=certification, @code{A}=authentication). Defaults to yes. + @item show-ownertrust + @opindex list-options:show-ownertrust + Show the ownertrust value for keys also in the standard key + listing. Defaults to no. + @item show-policy-urls @opindex list-options:show-policy-urls Show policy URLs in the @option{--check-signatures} diff --git a/g10/gpg.c b/g10/gpg.c index 7cb83c443..658fb7cf1 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2113,6 +2113,8 @@ parse_list_options(char *str) N_("show preferences")}, {"show-pref-verbose", LIST_SHOW_PREF_VERBOSE, NULL, N_("show preferences")}, + {"show-ownertrust", LIST_SHOW_OWNERTRUST, NULL, + N_("show ownertrust")}, {"show-only-fpr-mbox",LIST_SHOW_ONLY_FPR_MBOX, NULL, NULL}, {"sort-sigs", LIST_SORT_SIGS, NULL, diff --git a/g10/gpgv.c b/g10/gpgv.c index c3b09f752..50ec3917a 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -426,6 +426,14 @@ get_ownertrust (ctrl_t ctrl, PKT_public_key *pk) return TRUST_UNKNOWN; } +const char * +get_ownertrust_string (ctrl_t ctrl, PKT_public_key *pk, int no_create) +{ + (void)ctrl; + (void)pk; + (void)no_create; + return ""; +} /* Stubs: * Because we only work with trusted keys, it does not make sense to diff --git a/g10/keylist.c b/g10/keylist.c index 7fb5eff72..7717ca563 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -2600,6 +2600,11 @@ print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret) tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0)); } + if (pk->flags.primary && (opt.list_options & LIST_SHOW_OWNERTRUST)) + { + tty_fprintf (fp, " [%s]", get_ownertrust_string (ctrl, pk, 0)); + } + if (pk->flags.revoked) { tty_fprintf (fp, " ["); @@ -2619,21 +2624,14 @@ print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret) tty_fprintf (fp, "]"); } -#if 0 - /* I need to think about this some more. It's easy enough to - include, but it looks sort of confusing in the listing... */ - if (opt.list_options & LIST_SHOW_VALIDITY) - { - int validity = get_validity (ctrl, pk, NULL, NULL, 0); - tty_fprintf (fp, " [%s]", trust_value_to_string (validity)); - } -#endif - if (pk->pubkey_algo >= 100) tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo); tty_fprintf (fp, "\n"); + if (pk->flags.primary && pk_is_disabled (pk)) + es_fprintf (es_stdout, " *** %s\n", _("This key has been disabled")); + /* if the user hasn't explicitly asked for human-readable fingerprints, show compact fpr of primary key: */ if (pk->flags.primary && diff --git a/g10/options.h b/g10/options.h index e810adfb9..2fe4f5bbf 100644 --- a/g10/options.h +++ b/g10/options.h @@ -445,6 +445,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define LIST_SHOW_UNUSABLE_SIGS (1<<16) #define LIST_SHOW_X509_NOTATIONS (1<<17) #define LIST_STORE_X509_NOTATIONS (1<<18) +#define LIST_SHOW_OWNERTRUST (1<<19) #define VERIFY_SHOW_PHOTOS (1<<0) #define VERIFY_SHOW_POLICY_URLS (1<<1) diff --git a/g10/test-stubs.c b/g10/test-stubs.c index d9bead754..00145c12b 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -155,6 +155,15 @@ get_ownertrust_info (ctrl_t ctrl, PKT_public_key *pk, int no_create) return '?'; } +const char * +get_ownertrust_string (ctrl_t ctrl, PKT_public_key *pk, int no_create) +{ + (void)ctrl; + (void)pk; + (void)no_create; + return ""; +} + unsigned int get_ownertrust (ctrl_t ctrl, PKT_public_key *pk) { From 967678d9728cdc0627ab6d7861608d0e44f02890 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 Apr 2024 11:42:20 +0200 Subject: [PATCH 444/869] gpg: New command --quick-set-ownertrust. * g10/gpg.c (aQuickSetOwnertrust): New. (opts): Add new command. (main): Implement it. * g10/keyedit.c (keyedit_quick_set_ownertrust): New. --- doc/gpg.texi | 9 +++++- g10/gpg.c | 13 ++++++++ g10/keyedit.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++- g10/keyedit.h | 2 ++ 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 1d1c38cd9..ae1db9f92 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1223,12 +1223,19 @@ all affected self-signatures is set one second ahead. This command updates the preference list of the key to the current default value (either built-in or set via @option{--default-preference-list}). This is the unattended version -of of using "setpref" in the @option{--key-edit} menu without giving a +of using "setpref" in the @option{--key-edit} menu without giving a list. Note that you can show the preferences in a key listing by using @option{--list-options show-pref} or @option{--list-options show-pref-verbose}. You should also re-distribute updated keys to your peers. +@item --quick-set-ownertrust @var{user-id} @var{value} +@opindex quick-set-ownertrust +This command sets the ownertrust of a key and can also be used to set +the disable flag of a key. This is the unattended version of using +"trust", "disable", or "enable" in the @option{--key-edit} menu. + + @item --change-passphrase @var{user-id} @opindex change-passphrase @itemx --passwd @var{user-id} diff --git a/g10/gpg.c b/g10/gpg.c index 80cb2f38b..29b7eb55d 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -136,6 +136,7 @@ enum cmd_and_opt_values aQuickSetExpire, aQuickSetPrimaryUid, aQuickUpdatePref, + aQuickSetOwnertrust, aListConfig, aListGcryptConfig, aGPGConfList, @@ -502,6 +503,7 @@ static gpgrt_opt_t opts[] = { N_("quickly set a new expiration date")), ARGPARSE_c (aQuickSetPrimaryUid, "quick-set-primary-uid", "@"), ARGPARSE_c (aQuickUpdatePref, "quick-update-pref", "@"), + ARGPARSE_c (aQuickSetOwnertrust, "quick-set-ownertrust", "@"), ARGPARSE_c (aFullKeygen, "full-generate-key" , N_("full featured key pair generation")), ARGPARSE_c (aFullKeygen, "full-gen-key", "@"), @@ -2717,6 +2719,7 @@ main (int argc, char **argv) case aQuickSetExpire: case aQuickSetPrimaryUid: case aQuickUpdatePref: + case aQuickSetOwnertrust: case aExportOwnerTrust: case aImportOwnerTrust: case aRebuildKeydbCaches: @@ -4393,6 +4396,7 @@ main (int argc, char **argv) case aQuickRevUid: case aQuickSetPrimaryUid: case aQuickUpdatePref: + case aQuickSetOwnertrust: case aFullKeygen: case aKeygen: case aImport: @@ -4912,6 +4916,15 @@ main (int argc, char **argv) } break; + case aQuickSetOwnertrust: + { + if (argc != 2) + wrong_args ("--quick-set-ownertrust USER-ID" + " [enable|disable|full|...]"); + keyedit_quick_set_ownertrust (ctrl, argv[0], argv[1]); + } + break; + case aFastImport: opt.import_options |= IMPORT_FAST; /* fall through */ case aImport: diff --git a/g10/keyedit.c b/g10/keyedit.c index 7523a1a62..f4f59de03 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -2754,6 +2754,87 @@ keyedit_quick_update_pref (ctrl_t ctrl, const char *username) } +/* Unattended updating of the ownertrust or disable/enable state of a key + * USERNAME specifies the key. This is somewhat similar to + * gpg --edit-key trust save + * gpg --edit-key disable save + * + * VALUE is the new trust value which is one of: + * "undefined" - Ownertrust is set to undefined + * "never" - Ownertrust is set to never trust + * "marginal" - Ownertrust is set to marginal trust + * "full" - Ownertrust is set to full trust + * "ultimate" - Ownertrust is set to ultimate trust + * "enable" - The key is re-enabled. + * "disable" - The key is disabled. + * Trust settings do not change the ebable/disable state. + */ +void +keyedit_quick_set_ownertrust (ctrl_t ctrl, const char *username, + const char *value) +{ + gpg_error_t err; + KEYDB_HANDLE kdbhd = NULL; + kbnode_t keyblock = NULL; + PKT_public_key *pk; + unsigned int trust, newtrust; + int x; + int maybe_update_trust = 0; + +#ifdef HAVE_W32_SYSTEM + /* See keyedit_menu for why we need this. */ + check_trustdb_stale (ctrl); +#endif + + /* Search the key; we don't want the whole getkey stuff here. Note + * that we are looking for the public key here. */ + err = quick_find_keyblock (ctrl, username, 0, &kdbhd, &keyblock); + if (err) + goto leave; + log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY + || keyblock->pkt->pkttype == PKT_SECRET_KEY); + pk = keyblock->pkt->pkt.public_key; + + trust = newtrust = get_ownertrust (ctrl, pk); + + if (!ascii_strcasecmp (value, "enable")) + newtrust &= ~TRUST_FLAG_DISABLED; + else if (!ascii_strcasecmp (value, "disable")) + newtrust |= TRUST_FLAG_DISABLED; + else if ((x = string_to_trust_value (value)) >= 0) + { + newtrust = x; + newtrust &= TRUST_MASK; + newtrust |= (trust & ~TRUST_MASK); + maybe_update_trust = 1; + } + else + { + err = gpg_error (GPG_ERR_INV_ARG); + goto leave; + } + + if (trust != newtrust) + { + update_ownertrust (ctrl, pk, newtrust); + if (maybe_update_trust) + revalidation_mark (ctrl); + } + else if (opt.verbose) + log_info (_("Key not changed so no update needed.\n")); + + leave: + if (err) + { + log_error (_("setting the ownertrust to '%s' failed: %s\n"), + value, gpg_strerror (err)); + write_status_error ("keyedit.setownertrust", err); + } + release_kbnode (keyblock); + keydb_release (kdbhd); +} + + /* Find a keyblock by fingerprint because only this uniquely * identifies a key and may thus be used to select a key for * unattended subkey creation os key signing. */ @@ -2998,7 +3079,7 @@ keyedit_quick_revsig (ctrl_t ctrl, const char *username, const char *sigtorev, check_trustdb_stale (ctrl); #endif - /* Search the key; we don't want the whole getkey stuff here. Noet + /* Search the key; we don't want the whole getkey stuff here. Note * that we are looking for the public key here. */ err = quick_find_keyblock (ctrl, username, 0, &kdbhd, &keyblock); if (err) diff --git a/g10/keyedit.h b/g10/keyedit.h index abf7314af..7cb01268e 100644 --- a/g10/keyedit.h +++ b/g10/keyedit.h @@ -57,6 +57,8 @@ void keyedit_quick_set_expire (ctrl_t ctrl, void keyedit_quick_set_primary (ctrl_t ctrl, const char *username, const char *primaryuid); void keyedit_quick_update_pref (ctrl_t ctrl, const char *username); +void keyedit_quick_set_ownertrust (ctrl_t ctrl, const char *username, + const char *value); void show_basic_key_info (ctrl_t ctrl, kbnode_t keyblock, int print_sec); int keyedit_print_one_sig (ctrl_t ctrl, estream_t fp, int rc, kbnode_t keyblock, From 2a0a706eb2133bf58d78a8fefe780fe904fa2e62 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 Apr 2024 12:16:20 +0200 Subject: [PATCH 445/869] gpg: Mark disabled keys and add show-ownertrust list option. * g10/options.h (LIST_SHOW_OWNERTRUST): New. * g10/keylist.c (print_key_line): Show wonertrust and always show whether a key is disabled. * g10/gpg.c (parse_list_options): Add "show-ownertrust". * g10/gpgv.c (get_ownertrust_string): Add stub. * g10/test-stubs.c (get_ownertrust_string): Add stub. -- Note that in a --with-colons listing the ownertrust has always been emitted and the disabled state is marked in that listing with a special 'D' usage. --- doc/gpg.texi | 5 +++++ g10/gpg.c | 2 ++ g10/gpgv.c | 8 ++++++++ g10/keylist.c | 18 ++++++++---------- g10/options.h | 1 + g10/test-stubs.c | 9 +++++++++ 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index ae1db9f92..8755b9455 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1403,6 +1403,11 @@ give the opposite meaning. The options are: key (@code{E}=encryption, @code{S}=signing, @code{C}=certification, @code{A}=authentication). Defaults to yes. + @item show-ownertrust + @opindex list-options:show-ownertrust + Show the ownertrust value for keys also in the standard key + listing. Defaults to no. + @item show-policy-urls @opindex list-options:show-policy-urls Show policy URLs in the @option{--check-signatures} diff --git a/g10/gpg.c b/g10/gpg.c index 29b7eb55d..bba486aea 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2109,6 +2109,8 @@ parse_list_options(char *str) N_("show preferences")}, {"show-pref-verbose", LIST_SHOW_PREF_VERBOSE, NULL, N_("show preferences")}, + {"show-ownertrust", LIST_SHOW_OWNERTRUST, NULL, + N_("show ownertrust")}, {"show-only-fpr-mbox",LIST_SHOW_ONLY_FPR_MBOX, NULL, NULL}, {"sort-sigs", LIST_SORT_SIGS, NULL, diff --git a/g10/gpgv.c b/g10/gpgv.c index c3b09f752..50ec3917a 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -426,6 +426,14 @@ get_ownertrust (ctrl_t ctrl, PKT_public_key *pk) return TRUST_UNKNOWN; } +const char * +get_ownertrust_string (ctrl_t ctrl, PKT_public_key *pk, int no_create) +{ + (void)ctrl; + (void)pk; + (void)no_create; + return ""; +} /* Stubs: * Because we only work with trusted keys, it does not make sense to diff --git a/g10/keylist.c b/g10/keylist.c index d0ebfc86f..cc1e23d7f 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -2520,6 +2520,11 @@ print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret) tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0)); } + if (pk->flags.primary && (opt.list_options & LIST_SHOW_OWNERTRUST)) + { + tty_fprintf (fp, " [%s]", get_ownertrust_string (ctrl, pk, 0)); + } + if (pk->flags.revoked) { tty_fprintf (fp, " ["); @@ -2539,21 +2544,14 @@ print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret) tty_fprintf (fp, "]"); } -#if 0 - /* I need to think about this some more. It's easy enough to - include, but it looks sort of confusing in the listing... */ - if (opt.list_options & LIST_SHOW_VALIDITY) - { - int validity = get_validity (ctrl, pk, NULL, NULL, 0); - tty_fprintf (fp, " [%s]", trust_value_to_string (validity)); - } -#endif - if (pk->pubkey_algo >= 100) tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo); tty_fprintf (fp, "\n"); + if (pk->flags.primary && pk_is_disabled (pk)) + es_fprintf (es_stdout, " *** %s\n", _("This key has been disabled")); + /* if the user hasn't explicitly asked for human-readable fingerprints, show compact fpr of primary key: */ if (pk->flags.primary && diff --git a/g10/options.h b/g10/options.h index 458180c7a..50fa4ad86 100644 --- a/g10/options.h +++ b/g10/options.h @@ -442,6 +442,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define LIST_SHOW_PREF (1<<14) #define LIST_SHOW_PREF_VERBOSE (1<<15) #define LIST_SHOW_UNUSABLE_SIGS (1<<16) +#define LIST_SHOW_OWNERTRUST (1<<19) #define VERIFY_SHOW_PHOTOS (1<<0) #define VERIFY_SHOW_POLICY_URLS (1<<1) diff --git a/g10/test-stubs.c b/g10/test-stubs.c index d9bead754..00145c12b 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -155,6 +155,15 @@ get_ownertrust_info (ctrl_t ctrl, PKT_public_key *pk, int no_create) return '?'; } +const char * +get_ownertrust_string (ctrl_t ctrl, PKT_public_key *pk, int no_create) +{ + (void)ctrl; + (void)pk; + (void)no_create; + return ""; +} + unsigned int get_ownertrust (ctrl_t ctrl, PKT_public_key *pk) { From ba3c873934c920d18399fd194f07e0159ee31ec3 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 18 Apr 2024 14:37:40 +0200 Subject: [PATCH 446/869] gpg: Prepare Kyber encryption code for more variants. * common/openpgp-oid.c (oidtable): Add field kem_algo. (openpgp_oid_to_kem_algo): New. * g10/pkglue.c (do_encrypt_kem): Add support for Kyber1024. -- GnuPG-bug-id: 6815 --- common/openpgp-oid.c | 28 +++++++++++++- common/util.h | 1 + g10/pkglue.c | 90 +++++++++++++++++++++++++++++++++----------- 3 files changed, 94 insertions(+), 25 deletions(-) diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index 4b59c1aeb..74541a03f 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -45,14 +45,15 @@ static struct { const char *alias; /* NULL or alternative name of the curve. */ const char *abbr; /* NULL or abbreviated name of the curve. */ int pubkey_algo; /* Required OpenPGP algo or 0 for ECDSA/ECDH. */ + enum gcry_kem_algos kem_algo; /* 0 or the KEM algorithm for PQC. */ } oidtable[] = { { "Curve25519", "1.3.6.1.4.1.3029.1.5.1", 255, "cv25519", NULL, - PUBKEY_ALGO_ECDH }, + PUBKEY_ALGO_ECDH, GCRY_KEM_RAW_X25519 /* only during development */}, { "Ed25519", "1.3.6.1.4.1.11591.15.1", 255, "ed25519", NULL, PUBKEY_ALGO_EDDSA }, { "Curve25519", "1.3.101.110", 255, "cv25519", NULL, - PUBKEY_ALGO_ECDH }, + PUBKEY_ALGO_ECDH, GCRY_KEM_RAW_X25519 }, { "Ed25519", "1.3.101.112", 255, "ed25519", NULL, PUBKEY_ALGO_EDDSA }, { "X448", "1.3.101.111", 448, "cv448", NULL, @@ -542,6 +543,29 @@ openpgp_oid_or_name_to_curve (const char *oidname, int canon) } +/* Return the KEM algorithm id for the curve with OIDNAME. */ +enum gcry_kem_algos +openpgp_oid_to_kem_algo (const char *oidname) +{ + int i; + + if (!oidname) + return 0; + + for (i=0; oidtable[i].name; i++) + if (!strcmp (oidtable[i].oidstr, oidname)) + return oidtable[i].kem_algo; + + for (i=0; oidtable[i].name; i++) + if (!ascii_strcasecmp (oidtable[i].name, oidname) + || (oidtable[i].alias + && !ascii_strcasecmp (oidtable[i].alias, oidname))) + return oidtable[i].kem_algo; + + return 0; +} + + /* Return true if the curve with NAME is supported. */ static int curve_supported_p (const char *name) diff --git a/common/util.h b/common/util.h index 5c953a8a1..238b8f1bc 100644 --- a/common/util.h +++ b/common/util.h @@ -227,6 +227,7 @@ int openpgp_oidbuf_is_cv25519 (const void *buf, size_t len); int openpgp_oid_is_cv25519 (gcry_mpi_t a); int openpgp_oid_is_cv448 (gcry_mpi_t a); int openpgp_oid_is_ed448 (gcry_mpi_t a); +enum gcry_kem_algos openpgp_oid_to_kem_algo (const char *oidname); const char *openpgp_curve_to_oid (const char *name, unsigned int *r_nbits, int *r_algo); const char *openpgp_oid_to_curve (const char *oid, int mode); diff --git a/g10/pkglue.c b/g10/pkglue.c index 0167e80e3..2de0e80ab 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -417,6 +417,11 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, } +#if GCRY_KEM_MLKEM1024_ENCAPS_LEN < GCRY_KEM_MLKEM768_ENCAPS_LEN \ + || GCRY_KEM_MLKEM1024_SHARED_LEN < GCRY_KEM_MLKEM768_SHARED_LEN +# error Bad Kyber constants in Libgcrypt +#endif + /* Core of the encryption for KEM algorithms. See pk_decrypt for a * description of the arguments. */ static gpg_error_t @@ -428,6 +433,8 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, unsigned int nbits, n; gcry_sexp_t s_data = NULL; gcry_cipher_hd_t hd = NULL; + char *ecc_oid = NULL; + enum gcry_kem_algos kyber_algo, ecc_algo; const unsigned char *ecc_pubkey; size_t ecc_pubkey_len; @@ -445,10 +452,9 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, unsigned char ecc_ss[GCRY_KEM_RAW_X25519_SHARED_LEN]; size_t ecc_ss_len = GCRY_KEM_RAW_X25519_SHARED_LEN; - unsigned char kyber_ct[GCRY_KEM_MLKEM768_ENCAPS_LEN]; - size_t kyber_ct_len = GCRY_KEM_MLKEM768_ENCAPS_LEN; - unsigned char kyber_ss[GCRY_KEM_MLKEM768_SHARED_LEN]; - size_t kyber_ss_len = GCRY_KEM_MLKEM768_SHARED_LEN; + unsigned char kyber_ct[GCRY_KEM_MLKEM1024_ENCAPS_LEN]; + unsigned char kyber_ss[GCRY_KEM_MLKEM1024_SHARED_LEN]; + size_t kyber_ct_len, kyber_ss_len; char fixedinfo[1+MAX_FINGERPRINT_LEN]; int fixedlen; @@ -463,23 +469,48 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, * second public key is expected. Right now we take the keys * directly from the PK->data elements. */ - /* FIXME: This is only for cv25519 */ - ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits); - ecc_pubkey_len = (nbits+7)/8; - if (ecc_pubkey_len != 33) + ecc_oid = openpgp_oid_to_str (pk->pkey[0]); + if (!ecc_oid) + { + err = gpg_error_from_syserror (); + log_error ("%s: error getting OID for ECC key\n", __func__); + goto leave; + } + ecc_algo = openpgp_oid_to_kem_algo (ecc_oid); + if (ecc_algo == GCRY_KEM_RAW_X25519) + { + if (!strcmp (ecc_oid, "1.3.6.1.4.1.3029.1.5.1")) + log_info ("Warning: " + "legacy OID for cv25519 accepted during develpment\n"); + ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits); + ecc_pubkey_len = (nbits+7)/8; + if (ecc_pubkey_len != 33) + { + if (opt.verbose) + log_info ("%s: ECC public key length invalid (%zu)\n", + __func__, ecc_pubkey_len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + ecc_pubkey++; /* Remove the 0x40 prefix. */ + ecc_pubkey_len--; + } + else { if (opt.verbose) - log_info ("%s: ECC public key length invalid (%zu)\n", - __func__, ecc_pubkey_len); + log_info ("%s: ECC curve %s not supported\n", __func__, ecc_oid); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } - ecc_pubkey++; /* Remove the 0x40 prefix. */ - ecc_pubkey_len--; - if (DBG_CRYPTO) - log_printhex (ecc_pubkey, ecc_pubkey_len, "ECC pubkey:"); - err = gcry_kem_encap (GCRY_KEM_RAW_X25519, + + if (DBG_CRYPTO) + { + log_debug ("ECC curve: %s\n", ecc_oid); + log_printhex (ecc_pubkey, ecc_pubkey_len, "ECC pubkey:"); + } + + err = gcry_kem_encap (ecc_algo, ecc_pubkey, ecc_pubkey_len, ecc_ct, ecc_ct_len, ecc_ecdh, ecc_ecdh_len, @@ -487,7 +518,8 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, if (err) { if (opt.verbose) - log_info ("%s: gcry_kem_encap for ECC failed\n", __func__); + log_info ("%s: gcry_kem_encap for ECC (%s) failed\n", + __func__, ecc_oid); goto leave; } if (DBG_CRYPTO) @@ -509,21 +541,32 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, if (DBG_CRYPTO) log_printhex (ecc_ss, ecc_ss_len, "ECC shared:"); - /* FIXME: This is only for kyber768 */ kyber_pubkey = gcry_mpi_get_opaque (pk->pkey[2], &nbits); kyber_pubkey_len = (nbits+7)/8; - if (kyber_pubkey_len != GCRY_KEM_MLKEM768_PUBKEY_LEN) + if (kyber_pubkey_len == GCRY_KEM_MLKEM768_PUBKEY_LEN) + { + kyber_algo = GCRY_KEM_MLKEM768; + kyber_ct_len = GCRY_KEM_MLKEM768_ENCAPS_LEN; + kyber_ss_len = GCRY_KEM_MLKEM768_SHARED_LEN; + } + else if (kyber_pubkey_len == GCRY_KEM_MLKEM1024_PUBKEY_LEN) + { + kyber_algo = GCRY_KEM_MLKEM1024; + kyber_ct_len = GCRY_KEM_MLKEM1024_ENCAPS_LEN; + kyber_ss_len = GCRY_KEM_MLKEM1024_SHARED_LEN; + } + else { if (opt.verbose) - log_info ("%s: Kyber public key length invalid (%zu)\n", - __func__, kyber_pubkey_len); + log_info ("%s: Kyber public key length invalid (%zu)\n", + __func__, kyber_pubkey_len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } if (DBG_CRYPTO) log_printhex (kyber_pubkey, kyber_pubkey_len, "|!trunc|Kyber pubkey:"); - err = gcry_kem_encap (GCRY_KEM_MLKEM768, + err = gcry_kem_encap (kyber_algo, kyber_pubkey, kyber_pubkey_len, kyber_ct, kyber_ct_len, kyber_ss, kyber_ss_len, @@ -625,11 +668,12 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, wipememory (ecc_ct, ecc_ct_len); wipememory (ecc_ecdh, ecc_ecdh_len); wipememory (ecc_ss, ecc_ss_len); - wipememory (kyber_ct, kyber_ct_len); - wipememory (kyber_ss, kyber_ss_len); + wipememory (kyber_ct, sizeof kyber_ct); + wipememory (kyber_ss, sizeof kyber_ss); wipememory (kek, kek_len); xfree (enc_seskey); gcry_cipher_close (hd); + xfree (ecc_oid); return err; } From f119444e644280288ff05f46b7147481f594490f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Apr 2024 08:04:27 +0200 Subject: [PATCH 447/869] tests: Avoid new C23 keyword true. * tests/asschk.c (eval_boolean): s/true/tru/ -- GnuPG-bug-is: 7093 --- tests/asschk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/asschk.c b/tests/asschk.c index c77fd7c23..e278069bf 100644 --- a/tests/asschk.c +++ b/tests/asschk.c @@ -656,13 +656,13 @@ expand_line (char *buffer) static int eval_boolean (const char *cond) { - int true = 1; + int tru = 1; for ( ; *cond == '!'; cond++) - true = !true; + tru = !tru; if (!*cond || (*cond == '0' && !cond[1])) - return !true; - return true; + return !tru; + return tru; } From 7728a179e0b7b788fb525e4de794b92360f70e66 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Apr 2024 08:04:27 +0200 Subject: [PATCH 448/869] tests: Avoid new C23 keyword true. * tests/asschk.c (eval_boolean): s/true/tru/ -- GnuPG-bug-is: 7093 --- tests/asschk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/asschk.c b/tests/asschk.c index c77fd7c23..e278069bf 100644 --- a/tests/asschk.c +++ b/tests/asschk.c @@ -656,13 +656,13 @@ expand_line (char *buffer) static int eval_boolean (const char *cond) { - int true = 1; + int tru = 1; for ( ; *cond == '!'; cond++) - true = !true; + tru = !tru; if (!*cond || (*cond == '0' && !cond[1])) - return !true; - return true; + return !tru; + return tru; } From aa15272ba1a01bc666093655c13fc683a6bc2956 Mon Sep 17 00:00:00 2001 From: Daniel Cerqueira Date: Fri, 19 Apr 2024 16:19:16 +0100 Subject: [PATCH 449/869] po: Update Portuguese Translation. Signed-off-by: Daniel Cerqueira --- po/pt.po | 47 +++++++++-------------------------------------- 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/po/pt.po b/po/pt.po index 31f3fbec8..9244dc9a0 100644 --- a/po/pt.po +++ b/po/pt.po @@ -63,7 +63,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"PO-Revision-Date: 2023-11-29 13:11+0000\n" +"PO-Revision-Date: 2024-04-19 16:10+0100\n" "Last-Translator: Daniel Cerqueira \n" "Language-Team: pt \n" "Language: pt\n" @@ -881,28 +881,8 @@ msgid "waiting for process %d to terminate failed: %s\n" msgstr "falha ao aguardar pelo encerramento do processo %d: %s\n" #, c-format -msgid "error running '%s': probably not installed\n" -msgstr "" - -#, fuzzy, c-format -#| msgid "error accessing '%s': http status %u\n" -msgid "error running '%s': exit status %d\n" -msgstr "erro ao aceder '%s': status http %u\n" - -#, fuzzy, c-format -#| msgid "error opening '%s': %s\n" -msgid "error running '%s': terminated\n" -msgstr "erro ao abrir '%s': %s\n" - -#, fuzzy, c-format -#| msgid "waiting for process %d to terminate failed: %s\n" -msgid "waiting for processes to terminate failed: %s\n" -msgstr "falha ao aguardar pelo encerramento do processo %d: %s\n" - -#, fuzzy, c-format -#| msgid "error getting list of cards: %s\n" -msgid "error getting exit code of process %d: %s\n" -msgstr "erro ao obter a lista de cartões: %s\n" +msgid "waiting for process to terminate failed: ec=%d\n" +msgstr "falha ao esperar que o processo terminasse: ec=%d\n" #, c-format msgid "can't connect to '%s': %s\n" @@ -2157,6 +2137,9 @@ msgstr "criar saída blindada ASCII" msgid "|FILE|write output to FILE" msgstr "|FILE|escrever saída em FILE" +msgid "use canonical text mode" +msgstr "usar modo de texto canónico" + msgid "|N|set compress level to N (0 disables)" msgstr "|N|definir nível de compressão para N (0 desabilita)" @@ -4758,7 +4741,7 @@ msgstr "chave pública é %s\n" #, c-format msgid "encrypted with %s key, ID %s, created %s\n" -msgstr "cifrado com chave %s, ID %s, criado em %s\n" +msgstr "cifrado com chave %s, ID %s, criada em %s\n" #, c-format msgid " \"%s\"\n" @@ -4924,7 +4907,7 @@ msgid "textmode" msgstr "modo de texto" msgid "unknown" -msgstr "desconhecido" +msgstr "desconhec." msgid ", key algorithm " msgstr ", algoritmo da chave " @@ -6723,9 +6706,7 @@ msgstr "o acesso aos comandos admin não está configurado\n" msgid "||Please enter the PIN" msgstr "||Introduza o PIN" -#, fuzzy -#| msgid "||Please enter the Reset Code for the card" -msgid "|R|Please enter the Reset Code for the card" +msgid "||Please enter the Reset Code for the card" msgstr "||Introduza o Código de Reset do cartão" #, c-format @@ -8987,18 +8968,8 @@ msgstr "armazenar um certificado em um objeto de dados" msgid "store a private key to a data object" msgstr "armazenar uma chave privada em um objeto de dados" -msgid "run various checks on the keys" -msgstr "" - msgid "Yubikey management commands" msgstr "comandos de gerir uma Yubikey" msgid "manage the command history" msgstr "gerir o histórico de comandos" - -#~ msgid "use canonical text mode" -#~ msgstr "usar modo de texto canónico" - -#, c-format -#~ msgid "waiting for process to terminate failed: ec=%d\n" -#~ msgstr "falha ao esperar que o processo terminasse: ec=%d\n" From d5c6b52e597491b30044b6eaef4d15af8182d654 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 23 Apr 2024 14:23:27 +0900 Subject: [PATCH 450/869] agent:kem: Support other ECC curves. * agent/pkdecrypt.c (ecc_table): New. (get_ecc_params): New. (composite_pgp_kem_decrypt): Support other curves. -- Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 126 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 105 insertions(+), 21 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index ba42a265d..4a93fd95f 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -173,6 +173,64 @@ reverse_buffer (unsigned char *buffer, unsigned int length) } } +struct ecc_params +{ + int name_len; + const char *curve; + size_t pubkey_len; /* Pubkey in the SEXP representation. */ + size_t scalar_len; + size_t point_len; + size_t shared_len; + int hash_algo; + int algo; + int scalar_reverse; +}; + +static const struct ecc_params ecc_table[] = + { + { + 10, "Curve25519", + 33, 32, 32, 32, + GCRY_MD_SHA3_256, GCRY_KEM_RAW_X25519, + 1 + }, + { + 4, "X448", + 56, 56, 56, 64, + GCRY_MD_SHA3_512, GCRY_KEM_RAW_X448, + 0 + }, + { + 15, "brainpoolP256r1", + 65, 32, 65, 32, + GCRY_MD_SHA3_256, GCRY_KEM_RAW_BP256, + 0 + }, + { + 15, "brainpoolP384r1", + 97, 48, 97, 64, + GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP384, + 0 + }, + { 0, NULL, 0, 0, 0, 0, 0, 0, 0 } +}; + +static const struct ecc_params * +get_ecc_params (const char *curve, size_t curve_len) +{ + int i, name_len; + + for (i = 0; (name_len = ecc_table[i].name_len); i++) + if (name_len == curve_len && !memcmp (ecc_table[i].curve, curve, name_len)) + return &ecc_table[i]; + + return NULL; +} + +#define ECC_SCALAR_LEN_MAX 64 +#define ECC_POINT_LEN_MAX (1+2*64) +#define ECC_HASH_LEN_MAX 64 + /* For composite PGP KEM (ECC+ML-KEM), decrypt CIPHERTEXT using KEM API. First keygrip is for ECC, second keygrip is for PQC. CIPHERTEXT should follow the format of: @@ -195,6 +253,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_sexp_t s_skey1 = NULL; unsigned char *shadow_info = NULL; gpg_error_t err = 0; + const struct ecc_params *ecc; unsigned int nbits; const unsigned char *p; @@ -206,14 +265,13 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, size_t encrypted_sessionkey_len; gcry_mpi_t ecc_sk_mpi = NULL; - unsigned char ecc_sk[32]; + unsigned char ecc_sk[ECC_SCALAR_LEN_MAX]; gcry_mpi_t ecc_pk_mpi = NULL; - unsigned char ecc_pk[32]; + unsigned char ecc_pk[ECC_POINT_LEN_MAX]; gcry_mpi_t ecc_ct_mpi = NULL; const unsigned char *ecc_ct; - size_t ecc_ct_len; - unsigned char ecc_ecdh[32]; - unsigned char ecc_ss[32]; + unsigned char ecc_ecdh[ECC_POINT_LEN_MAX]; + unsigned char ecc_ss[ECC_HASH_LEN_MAX]; gcry_mpi_t mlkem_sk_mpi = NULL; gcry_mpi_t mlkem_ct_mpi = NULL; @@ -275,7 +333,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, goto leave; } - /* Fistly, ECC part. FIXME: For now, we assume X25519. */ + /* Firstly, ECC part. */ curve = gcry_sexp_find_token (s_skey0, "curve", 0); if (!curve) { @@ -286,7 +344,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, } curve_name = gcry_sexp_nth_data (curve, 1, &len); - if (len != 10 || memcmp (curve_name, "Curve25519", len)) + ecc = get_ecc_params (curve_name, len); + if (!ecc) { if (opt.verbose) log_info ("%s: curve '%s' not supported\n", __func__, curve_name); @@ -305,45 +364,63 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, p = gcry_mpi_get_opaque (ecc_pk_mpi, &nbits); len = (nbits+7)/8; - if (len != 33) + if (len != ecc->pubkey_len) { if (opt.verbose) log_info ("%s: ECC public key length invalid (%zu)\n", __func__, len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } - memcpy (ecc_pk, p+1, 32); /* Remove the 0x40 prefix */ + else if (len == ecc->point_len) + memcpy (ecc_pk, p, ecc->point_len); + else if (len == ecc->point_len + 1 && p[0] == 0x40) + /* Remove the 0x40 prefix (for Curve25519) */ + memcpy (ecc_pk, p+1, ecc->point_len); + else + { + err = gpg_error (GPG_ERR_BAD_SECKEY); + goto leave; + } + mpi_release (ecc_pk_mpi); + ecc_pk_mpi = NULL; p = gcry_mpi_get_opaque (ecc_sk_mpi, &nbits); len = (nbits+7)/8; - if (len > 32) + if (len > ecc->scalar_len) { if (opt.verbose) log_info ("%s: ECC secret key too long (%zu)\n", __func__, len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } - memset (ecc_sk, 0, 32); - memcpy (ecc_sk + 32 - len, p, len); - reverse_buffer (ecc_sk, 32); + memset (ecc_sk, 0, ecc->scalar_len - len); + memcpy (ecc_sk + ecc->scalar_len - len, p, len); + if (ecc->scalar_reverse) + reverse_buffer (ecc_sk, ecc->scalar_len); mpi_release (ecc_sk_mpi); - ecc_pk_mpi = NULL; ecc_sk_mpi = NULL; ecc_ct = gcry_mpi_get_opaque (ecc_ct_mpi, &nbits); - ecc_ct_len = (nbits+7)/8; - if (ecc_ct_len != 32) + if (ecc->point_len != (nbits+7)/8) { if (opt.verbose) log_info ("%s: ECC cipher text length invalid (%zu)\n", - __func__, ecc_ct_len); + __func__, ecc->point_len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } - err = gcry_kem_decap (GCRY_KEM_RAW_X25519, ecc_sk, 32, ecc_ct, ecc_ct_len, - ecc_ecdh, 32, NULL, 0); + if (DBG_CRYPTO) + { + log_debug ("ECC curve: %s\n", curve_name); + log_printhex (ecc_pk, ecc->pubkey_len, "ECC pubkey:"); + log_printhex (ecc_sk, ecc->scalar_len, "ECC seckey:"); + log_printhex (ecc_ct, ecc->point_len, "ECC ephem:"); + } + + err = gcry_kem_decap (ecc->algo, ecc_sk, ecc->scalar_len, + ecc_ct, ecc->point_len, ecc_ecdh, ecc->point_len, NULL, 0); if (err) { if (opt.verbose) @@ -351,8 +428,12 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, goto leave; } - err = gnupg_ecc_kem_kdf (ecc_ss, 32, GCRY_MD_SHA3_256, - ecc_ecdh, 32, ecc_ct, 32, ecc_pk, 32); + if (DBG_CRYPTO) + log_printhex (ecc_ecdh, ecc->point_len, "ECC ecdh:"); + + err = gnupg_ecc_kem_kdf (ecc_ss, ecc->shared_len, ecc->hash_algo, + ecc_ecdh, ecc->scalar_len, ecc_ct, ecc->point_len, + ecc_pk, ecc->point_len); if (err) { if (opt.verbose) @@ -360,6 +441,9 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, goto leave; } + if (DBG_CRYPTO) + log_printhex (ecc_ss, ecc->shared_len, "ECC shared:"); + /* Secondly, PQC part. For now, we assume ML-KEM. */ err = gcry_sexp_extract_param (s_skey1, NULL, "/s", &mlkem_sk_mpi, NULL); if (err) From 65833eefb2b5374275a7d862db9fe0a634125a3f Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 23 Apr 2024 14:40:27 +0900 Subject: [PATCH 451/869] agent:kem: Support other ML-KEM variants. * agent/pkdecrypt.c (composite_pgp_kem_decrypt): Care about ML-KEM 512 and 1024. -- Co-authored-by: Werner Koch Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 51 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 4a93fd95f..cab1dbc5a 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -273,11 +273,15 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, unsigned char ecc_ecdh[ECC_POINT_LEN_MAX]; unsigned char ecc_ss[ECC_HASH_LEN_MAX]; + enum gcry_kem_algos mlkem_kem_algo; gcry_mpi_t mlkem_sk_mpi = NULL; gcry_mpi_t mlkem_ct_mpi = NULL; const unsigned char *mlkem_sk; + size_t mlkem_sk_len; const unsigned char *mlkem_ct; - unsigned char mlkem_ss[GCRY_KEM_MLKEM768_SHARED_LEN]; + size_t mlkem_ct_len; + unsigned char mlkem_ss[GCRY_KEM_MLKEM1024_SHARED_LEN]; + size_t mlkem_ss_len; unsigned char kek[32]; size_t kek_len = 32; /* AES-256 is mandatory */ @@ -453,27 +457,45 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, goto leave; } mlkem_sk = gcry_mpi_get_opaque (mlkem_sk_mpi, &nbits); - len = (nbits+7)/8; - if (len != GCRY_KEM_MLKEM768_SECKEY_LEN) + mlkem_sk_len = (nbits+7)/8; + if (mlkem_sk_len == GCRY_KEM_MLKEM512_SECKEY_LEN) + { + mlkem_kem_algo = GCRY_KEM_MLKEM512; + mlkem_ss_len = GCRY_KEM_MLKEM512_SHARED_LEN; + mlkem_ct_len = GCRY_KEM_MLKEM512_CIPHER_LEN; + } + else if (mlkem_sk_len == GCRY_KEM_MLKEM768_SECKEY_LEN) + { + mlkem_kem_algo = GCRY_KEM_MLKEM768; + mlkem_ss_len = GCRY_KEM_MLKEM768_SHARED_LEN; + mlkem_ct_len = GCRY_KEM_MLKEM768_CIPHER_LEN; + } + else if (mlkem_sk_len == GCRY_KEM_MLKEM1024_SECKEY_LEN) + { + mlkem_kem_algo = GCRY_KEM_MLKEM1024; + mlkem_ss_len = GCRY_KEM_MLKEM1024_SHARED_LEN; + mlkem_ct_len = GCRY_KEM_MLKEM1024_CIPHER_LEN; + } + else { if (opt.verbose) - log_info ("%s: PQ key length invalid (%zu)\n", __func__, len); + log_info ("%s: PQ key length invalid (%zu)\n", __func__, mlkem_sk_len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } + mlkem_ct = gcry_mpi_get_opaque (mlkem_ct_mpi, &nbits); len = (nbits+7)/8; - if (len != GCRY_KEM_MLKEM768_CIPHER_LEN) + if (len != mlkem_ct_len) { if (opt.verbose) - log_info ("%s: PQ cipher text length invalid (%zu)\n", __func__, len); + log_info ("%s: PQ cipher text length invalid (%zu)\n", + __func__, mlkem_ct_len); err = gpg_error (GPG_ERR_INV_DATA); goto leave; } - err = gcry_kem_decap (GCRY_KEM_MLKEM768, - mlkem_sk, GCRY_KEM_MLKEM768_SECKEY_LEN, - mlkem_ct, GCRY_KEM_MLKEM768_CIPHER_LEN, - mlkem_ss, GCRY_KEM_MLKEM768_SHARED_LEN, + err = gcry_kem_decap (mlkem_kem_algo, mlkem_sk, mlkem_sk_len, + mlkem_ct, mlkem_ct_len, mlkem_ss, mlkem_ss_len, NULL, 0); if (err) { @@ -499,8 +521,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, } mpi_release (ecc_ct_mpi); - mpi_release (mlkem_ct_mpi); ecc_ct_mpi = NULL; + mpi_release (mlkem_ct_mpi); mlkem_ct_mpi = NULL; if (DBG_CRYPTO) @@ -540,6 +562,13 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, put_membuf (outbuf, ")", 2); leave: + wipememory (ecc_sk, sizeof ecc_sk); + wipememory (ecc_ecdh, sizeof ecc_ecdh); + wipememory (ecc_ss, sizeof ecc_ss); + wipememory (mlkem_ss, sizeof mlkem_ss); + wipememory (kek, sizeof kek); + wipememory (sessionkey, sizeof sessionkey); + mpi_release (mlkem_sk_mpi); mpi_release (ecc_pk_mpi); mpi_release (ecc_sk_mpi); From af98a3e5faf135c2acd7968375aaaf8e72ced1d4 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 23 Apr 2024 16:09:02 +0900 Subject: [PATCH 452/869] agent:kem: More fix for PQC KEM with X448. * agent/pkdecrypt.c (struct ecc_params): Remove NAME_LEN field. (ecc_table): Update. (get_ecc_params): Use strcmp. (composite_pgp_kem_decrypt): Fix the call of gnupg_kem_combiner. -- Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index cab1dbc5a..a72b5d2d5 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -175,7 +175,6 @@ reverse_buffer (unsigned char *buffer, unsigned int length) struct ecc_params { - int name_len; const char *curve; size_t pubkey_len; /* Pubkey in the SEXP representation. */ size_t scalar_len; @@ -189,39 +188,39 @@ struct ecc_params static const struct ecc_params ecc_table[] = { { - 10, "Curve25519", + "Curve25519", 33, 32, 32, 32, GCRY_MD_SHA3_256, GCRY_KEM_RAW_X25519, 1 }, { - 4, "X448", + "X448", 56, 56, 56, 64, GCRY_MD_SHA3_512, GCRY_KEM_RAW_X448, 0 }, { - 15, "brainpoolP256r1", + "brainpoolP256r1", 65, 32, 65, 32, GCRY_MD_SHA3_256, GCRY_KEM_RAW_BP256, 0 }, { - 15, "brainpoolP384r1", + "brainpoolP384r1", 97, 48, 97, 64, GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP384, 0 }, - { 0, NULL, 0, 0, 0, 0, 0, 0, 0 } + { NULL, 0, 0, 0, 0, 0, 0, 0 } }; static const struct ecc_params * -get_ecc_params (const char *curve, size_t curve_len) +get_ecc_params (const char *curve) { - int i, name_len; + int i; - for (i = 0; (name_len = ecc_table[i].name_len); i++) - if (name_len == curve_len && !memcmp (ecc_table[i].curve, curve, name_len)) + for (i = 0; ecc_table[i].curve; i++) + if (!strcmp (ecc_table[i].curve, curve)) return &ecc_table[i]; return NULL; @@ -292,7 +291,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_buffer_t fixed_info = { 0, 0, 0, NULL }; gcry_sexp_t curve = NULL; - const char *curve_name; + char *curve_name = NULL; err = agent_key_from_file (ctrl, NULL, desc_text, ctrl->keygrip, &shadow_info, @@ -347,8 +346,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, goto leave; } - curve_name = gcry_sexp_nth_data (curve, 1, &len); - ecc = get_ecc_params (curve_name, len); + curve_name = gcry_sexp_nth_string (curve, 1); + ecc = get_ecc_params (curve_name); if (!ecc) { if (opt.verbose) @@ -436,7 +435,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, log_printhex (ecc_ecdh, ecc->point_len, "ECC ecdh:"); err = gnupg_ecc_kem_kdf (ecc_ss, ecc->shared_len, ecc->hash_algo, - ecc_ecdh, ecc->scalar_len, ecc_ct, ecc->point_len, + ecc_ecdh, ecc->point_len, ecc_ct, ecc->point_len, ecc_pk, ecc->point_len); if (err) { @@ -509,9 +508,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, /* Then, combine two shared secrets and ciphertexts into one KEK */ err = gnupg_kem_combiner (kek, kek_len, - ecc_ss, 32, ecc_ct, 32, - mlkem_ss, GCRY_KEM_MLKEM768_SHARED_LEN, - mlkem_ct, GCRY_KEM_MLKEM768_CIPHER_LEN, + ecc_ss, ecc->shared_len, ecc_ct, ecc->point_len, + mlkem_ss, mlkem_ss_len, mlkem_ct, mlkem_ct_len, fixed_info.data, fixed_info.size); if (err) { @@ -577,6 +575,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, mpi_release (encrypted_sessionkey_mpi); gcry_free (fixed_info.data); gcry_sexp_release (curve); + xfree (curve_name); gcry_sexp_release (s_skey0); gcry_sexp_release (s_skey1); return err; From f305e703d51079a17bcfc15d54f4c5f591dcff56 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Apr 2024 11:09:40 +0200 Subject: [PATCH 453/869] Require Libgcrypt 1.11.0 * configure.ac (NEED_LIBGCRYPT_VERSION): Set to 1.11.0 * agent/pkdecrypt.c (struct ecc_params): Move constants to the top. -- It does not make anymore sense to allow building with older Libgcrypt versions. After all PQ key support is a major feature and for this we need Libgcrypt. --- agent/pkdecrypt.c | 129 +++++++++++++++++++++++++--------------------- common/kem.c | 5 +- configure.ac | 2 +- 3 files changed, 71 insertions(+), 65 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index a72b5d2d5..10bd92152 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -29,6 +29,75 @@ #include "agent.h" #include "../common/openpgpdefs.h" + +/* Table with parameters for KEM decryption. Use get_ecc_parms to + * find an entry. */ +struct ecc_params +{ + const char *curve; /* Canonical name of the curve. */ + size_t pubkey_len; /* Pubkey in the SEXP representation. */ + size_t scalar_len; + size_t point_len; + size_t shared_len; + int hash_algo; + int algo; + int scalar_reverse; +}; + +static const struct ecc_params ecc_table[] = + { + { + "Curve25519", + 33, 32, 32, 32, + GCRY_MD_SHA3_256, GCRY_KEM_RAW_X25519, + 1 + }, + { + "X448", + 56, 56, 56, 64, + GCRY_MD_SHA3_512, GCRY_KEM_RAW_X448, + 0 + }, + { + "brainpoolP256r1", + 65, 32, 65, 32, + GCRY_MD_SHA3_256, GCRY_KEM_RAW_BP256, + 0 + }, + { + "brainpoolP384r1", + 97, 48, 97, 64, + GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP384, + 0 + }, + { NULL, 0, 0, 0, 0, 0, 0, 0 } +}; + + +/* Maximum buffer sizes required for ECC KEM. Keep this aligned to + * the ecc_table above. */ +#define ECC_SCALAR_LEN_MAX 64 +#define ECC_POINT_LEN_MAX (1+2*64) +#define ECC_HASH_LEN_MAX 64 + + + +/* Return the ECC parameters for CURVE. CURVE is expected to be the + * canonical name. */ +static const struct ecc_params * +get_ecc_params (const char *curve) +{ + int i; + + for (i = 0; ecc_table[i].curve; i++) + if (!strcmp (ecc_table[i].curve, curve)) + return &ecc_table[i]; + + return NULL; +} + + + /* DECRYPT the stuff in ciphertext which is expected to be a S-Exp. Try to get the key from CTRL and write the decoded stuff back to OUTFP. The padding information is stored at R_PADDING with -1 @@ -173,62 +242,6 @@ reverse_buffer (unsigned char *buffer, unsigned int length) } } -struct ecc_params -{ - const char *curve; - size_t pubkey_len; /* Pubkey in the SEXP representation. */ - size_t scalar_len; - size_t point_len; - size_t shared_len; - int hash_algo; - int algo; - int scalar_reverse; -}; - -static const struct ecc_params ecc_table[] = - { - { - "Curve25519", - 33, 32, 32, 32, - GCRY_MD_SHA3_256, GCRY_KEM_RAW_X25519, - 1 - }, - { - "X448", - 56, 56, 56, 64, - GCRY_MD_SHA3_512, GCRY_KEM_RAW_X448, - 0 - }, - { - "brainpoolP256r1", - 65, 32, 65, 32, - GCRY_MD_SHA3_256, GCRY_KEM_RAW_BP256, - 0 - }, - { - "brainpoolP384r1", - 97, 48, 97, 64, - GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP384, - 0 - }, - { NULL, 0, 0, 0, 0, 0, 0, 0 } -}; - -static const struct ecc_params * -get_ecc_params (const char *curve) -{ - int i; - - for (i = 0; ecc_table[i].curve; i++) - if (!strcmp (ecc_table[i].curve, curve)) - return &ecc_table[i]; - - return NULL; -} - -#define ECC_SCALAR_LEN_MAX 64 -#define ECC_POINT_LEN_MAX (1+2*64) -#define ECC_HASH_LEN_MAX 64 /* For composite PGP KEM (ECC+ML-KEM), decrypt CIPHERTEXT using KEM API. First keygrip is for ECC, second keygrip is for PQC. CIPHERTEXT @@ -247,7 +260,6 @@ static gpg_error_t composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_sexp_t s_cipher, membuf_t *outbuf) { -#if GCRYPT_VERSION_NUMBER >= 0x010b00 gcry_sexp_t s_skey0 = NULL; gcry_sexp_t s_skey1 = NULL; unsigned char *shadow_info = NULL; @@ -579,9 +591,6 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_sexp_release (s_skey0); gcry_sexp_release (s_skey1); return err; -#else - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); -#endif } /* DECRYPT the encrypted stuff (like encrypted session key) in diff --git a/common/kem.c b/common/kem.c index 7227898d1..0e498d37e 100644 --- a/common/kem.c +++ b/common/kem.c @@ -54,7 +54,6 @@ compute_kmac256 (void *digest, size_t digestlen, const void *custom, size_t customlen, gcry_buffer_t *data_iov, int data_iovlen) { -#if GCRYPT_VERSION_NUMBER >= 0x010b00 gpg_error_t err; gcry_buffer_t iov[20]; const unsigned char headPAD[2] = { 1, KECCAK512_BLOCKSIZE }; @@ -142,11 +141,9 @@ compute_kmac256 (void *digest, size_t digestlen, err = gcry_md_hash_buffers_ext (GCRY_MD_CSHAKE256, 0, digest, digestlen, iov, iovcnt); return err; -#else - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); -#endif } + /* Compute KEK (shared secret) for ECC with HASHALGO, ECDH result, ciphertext in ECC_CT, public key in ECC_PK. */ gpg_error_t diff --git a/configure.ac b/configure.ac index 0dfbe6193..1f0142140 100644 --- a/configure.ac +++ b/configure.ac @@ -58,7 +58,7 @@ AC_DEFINE_UNQUOTED(GNUPG_SWDB_TAG, "gnupg26", [swdb tag for this branch]) NEED_GPGRT_VERSION=1.46 NEED_LIBGCRYPT_API=1 -NEED_LIBGCRYPT_VERSION=1.9.1 +NEED_LIBGCRYPT_VERSION=1.11.0 NEED_LIBASSUAN_API=3 NEED_LIBASSUAN_VERSION=3.0.0 From e591fd25adc3c40561e9ebebb9d08abbaea0ad63 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Apr 2024 11:20:37 +0200 Subject: [PATCH 454/869] gpg: Support encryption with kyber_cv448. * g10/pkglue.c (do_encrypt_kem): Support cv25519 w/o 0x40 prefix. Support X448. (ECC_POINT_LEN_MAX): New. (ECC_HASH_LEN_MAX): New. * common/openpgp-oid.c (oidtable): Support X448 KEM. -- This needs more work. For example we should use a parameter table like what we do in agent/pkdecrypt.c. GnuPG-bug-id: 6815 --- common/openpgp-oid.c | 2 +- g10/pkglue.c | 53 +++++++++++++++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index 74541a03f..d54aff3a9 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -57,7 +57,7 @@ static struct { { "Ed25519", "1.3.101.112", 255, "ed25519", NULL, PUBKEY_ALGO_EDDSA }, { "X448", "1.3.101.111", 448, "cv448", NULL, - PUBKEY_ALGO_ECDH }, + PUBKEY_ALGO_ECDH, GCRY_KEM_RAW_X448 }, { "Ed448", "1.3.101.113", 456, "ed448", NULL, PUBKEY_ALGO_EDDSA }, diff --git a/g10/pkglue.c b/g10/pkglue.c index 2de0e80ab..fb39d5ba8 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -32,6 +32,12 @@ #include "main.h" #include "options.h" + +/* Maximum buffer sizes required for ECC KEM. */ +#define ECC_POINT_LEN_MAX (1+2*64) +#define ECC_HASH_LEN_MAX 64 + + /* FIXME: Better change the function name because mpi_ is used by gcrypt macros. */ gcry_mpi_t @@ -444,13 +450,12 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, size_t seskey_len; unsigned char *enc_seskey = NULL; size_t enc_seskey_len; + int ecc_hash_algo; - unsigned char ecc_ct[GCRY_KEM_ECC_X25519_ENCAPS_LEN]; - size_t ecc_ct_len = GCRY_KEM_ECC_X25519_ENCAPS_LEN; - unsigned char ecc_ecdh[GCRY_KEM_RAW_X25519_SHARED_LEN]; - size_t ecc_ecdh_len = GCRY_KEM_RAW_X25519_SHARED_LEN; - unsigned char ecc_ss[GCRY_KEM_RAW_X25519_SHARED_LEN]; - size_t ecc_ss_len = GCRY_KEM_RAW_X25519_SHARED_LEN; + unsigned char ecc_ct[ECC_POINT_LEN_MAX]; + unsigned char ecc_ecdh[ECC_POINT_LEN_MAX]; + unsigned char ecc_ss[ECC_HASH_LEN_MAX]; + size_t ecc_ct_len, ecc_ecdh_len, ecc_ss_len; unsigned char kyber_ct[GCRY_KEM_MLKEM1024_ENCAPS_LEN]; unsigned char kyber_ss[GCRY_KEM_MLKEM1024_SHARED_LEN]; @@ -484,7 +489,12 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, "legacy OID for cv25519 accepted during develpment\n"); ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits); ecc_pubkey_len = (nbits+7)/8; - if (ecc_pubkey_len != 33) + if (ecc_pubkey_len == 33 && *ecc_pubkey == 0x40) + { + ecc_pubkey++; /* Remove the 0x40 prefix. */ + ecc_pubkey_len--; + } + if (ecc_pubkey_len != 32) { if (opt.verbose) log_info ("%s: ECC public key length invalid (%zu)\n", @@ -492,8 +502,25 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, err = gpg_error (GPG_ERR_INV_DATA); goto leave; } - ecc_pubkey++; /* Remove the 0x40 prefix. */ - ecc_pubkey_len--; + ecc_ct_len = ecc_ecdh_len = 32; + ecc_ss_len = 32; + ecc_hash_algo = GCRY_MD_SHA3_256; + } + else if (ecc_algo == GCRY_KEM_RAW_X448) + { + ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits); + ecc_pubkey_len = (nbits+7)/8; + if (ecc_pubkey_len != 56) + { + if (opt.verbose) + log_info ("%s: ECC public key length invalid (%zu)\n", + __func__, ecc_pubkey_len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + ecc_ct_len = ecc_ecdh_len = 56; + ecc_ss_len = 64; + ecc_hash_algo = GCRY_MD_SHA3_512; } else { @@ -528,7 +555,7 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, log_printhex (ecc_ecdh, ecc_ecdh_len, "ECC ecdh:"); } err = gnupg_ecc_kem_kdf (ecc_ss, ecc_ss_len, - GCRY_MD_SHA3_256, + ecc_hash_algo, ecc_ecdh, ecc_ecdh_len, ecc_ct, ecc_ct_len, ecc_pubkey, ecc_pubkey_len); @@ -665,9 +692,9 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, } leave: - wipememory (ecc_ct, ecc_ct_len); - wipememory (ecc_ecdh, ecc_ecdh_len); - wipememory (ecc_ss, ecc_ss_len); + wipememory (ecc_ct, sizeof ecc_ct); + wipememory (ecc_ecdh, sizeof ecc_ecdh); + wipememory (ecc_ss, sizeof ecc_ss); wipememory (kyber_ct, sizeof kyber_ct); wipememory (kyber_ss, sizeof kyber_ss); wipememory (kek, kek_len); From f325d3277ec61ec97c3b2525772fb79d81113bd8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Apr 2024 14:03:54 +0200 Subject: [PATCH 455/869] tests: Add two Kyber sample keys and messages. -- GnuPG-bug-id: 6815 --- tests/openpgp/Makefile.am | 17 ++- ...4CD0990D56D41A74456668469E3139A7960CD4.key | 5 + ...2E1355C97C34E0AC1CBC9DFDF2526BFE8990A7.key | 104 +++++++++++++ ...9ABF3E5BBFC50D168DD524EB8F7263E7B33859.key | 5 + ...598F57316F7FEC3F946895E35A7D2EAE8D3A13.key | 137 ++++++++++++++++++ ...60E0AE48E0F14E8FD7C9C36E18C6651E99BA93.key | 5 + ...DB116462B7BD2FA83A4453C4DFA2AE8604FB59.key | 5 + tests/openpgp/samplekeys/README | 4 +- tests/openpgp/samplekeys/pqc-sample-1.key.asc | 46 ++++++ tests/openpgp/samplekeys/pqc-sample-2.key.asc | 55 +++++++ tests/openpgp/samplemsgs/pqc-sample-1.enc.asc | 81 +++++++++++ tests/openpgp/samplemsgs/pqc-sample-2.enc.asc | 102 +++++++++++++ 12 files changed, 562 insertions(+), 4 deletions(-) create mode 100644 tests/openpgp/privkeys/2F4CD0990D56D41A74456668469E3139A7960CD4.key create mode 100644 tests/openpgp/privkeys/8B2E1355C97C34E0AC1CBC9DFDF2526BFE8990A7.key create mode 100644 tests/openpgp/privkeys/8F9ABF3E5BBFC50D168DD524EB8F7263E7B33859.key create mode 100644 tests/openpgp/privkeys/A1598F57316F7FEC3F946895E35A7D2EAE8D3A13.key create mode 100644 tests/openpgp/privkeys/DC60E0AE48E0F14E8FD7C9C36E18C6651E99BA93.key create mode 100644 tests/openpgp/privkeys/F5DB116462B7BD2FA83A4453C4DFA2AE8604FB59.key create mode 100644 tests/openpgp/samplekeys/pqc-sample-1.key.asc create mode 100644 tests/openpgp/samplekeys/pqc-sample-2.key.asc create mode 100644 tests/openpgp/samplemsgs/pqc-sample-1.enc.asc create mode 100644 tests/openpgp/samplemsgs/pqc-sample-2.enc.asc diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index 7998d2ab9..e32ff3d17 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -212,7 +212,14 @@ priv_keys = privkeys/50B2D4FA4122C212611048BC5FC31BD44393626E.asc \ privkeys/C6A6390E9388CDBAD71EAEA698233FE5E04F001E.asc \ privkeys/D69102E0F5AC6B6DB8E4D16DA8E18CF46D88CAE3.asc \ privkeys/891067FFFC6D67D37BD4BFC399191C5F3989D1B5.key \ - privkeys/F27FC04CB01723A4CB6F5399F7B86CCD82C0169C.key + privkeys/F27FC04CB01723A4CB6F5399F7B86CCD82C0169C.key \ + privkeys/DC60E0AE48E0F14E8FD7C9C36E18C6651E99BA93.key \ + privkeys/2F4CD0990D56D41A74456668469E3139A7960CD4.key \ + privkeys/8B2E1355C97C34E0AC1CBC9DFDF2526BFE8990A7.key \ + privkeys/F5DB116462B7BD2FA83A4453C4DFA2AE8604FB59.key \ + privkeys/8F9ABF3E5BBFC50D168DD524EB8F7263E7B33859.key \ + privkeys/A1598F57316F7FEC3F946895E35A7D2EAE8D3A13.key + sample_keys = samplekeys/README \ samplekeys/ecc-sample-1-pub.asc \ @@ -239,7 +246,9 @@ sample_keys = samplekeys/README \ samplekeys/ssh-rsa.key \ samplekeys/issue2346.gpg \ samplekeys/authenticate-only.pub.asc \ - samplekeys/authenticate-only.sec.asc + samplekeys/authenticate-only.sec.asc \ + samplekeys/pqc-sample-1.key.asc \ + samplekeys/pqc-sample-2.key.asc sample_msgs = samplemsgs/clearsig-1-key-1.asc \ samplemsgs/clearsig-2-keys-1.asc \ @@ -272,7 +281,9 @@ sample_msgs = samplemsgs/clearsig-1-key-1.asc \ samplemsgs/signed-1-key-1.asc \ samplemsgs/signed-1-key-2.asc \ samplemsgs/signed-2-keys-1.asc \ - samplemsgs/signed-2-keys-2.asc + samplemsgs/signed-2-keys-2.asc \ + samplemsgs/pqc-sample-1.enc.asc \ + samplemsgs/pqc-sample-2.enc.asc EXTRA_DIST = defs.scm trust-pgp/common.scm $(XTESTS) $(TEST_FILES) \ mkdemodirs signdemokey $(priv_keys) $(sample_keys) \ diff --git a/tests/openpgp/privkeys/2F4CD0990D56D41A74456668469E3139A7960CD4.key b/tests/openpgp/privkeys/2F4CD0990D56D41A74456668469E3139A7960CD4.key new file mode 100644 index 000000000..b35c7377a --- /dev/null +++ b/tests/openpgp/privkeys/2F4CD0990D56D41A74456668469E3139A7960CD4.key @@ -0,0 +1,5 @@ +Created: 20240419T125003 +Key: (private-key (ecc (curve Curve25519)(flags djb-tweak)(q + #406438411B2E3EA2EA48B681860C2CA537978C69072CBD04A40069E122660F6F37#) + (d #7D295F7111BD111DB6685B451EF1FCFEA61F7777B8227194F97E093D6E508268#) + )) diff --git a/tests/openpgp/privkeys/8B2E1355C97C34E0AC1CBC9DFDF2526BFE8990A7.key b/tests/openpgp/privkeys/8B2E1355C97C34E0AC1CBC9DFDF2526BFE8990A7.key new file mode 100644 index 000000000..e0bc486b2 --- /dev/null +++ b/tests/openpgp/privkeys/8B2E1355C97C34E0AC1CBC9DFDF2526BFE8990A7.key @@ -0,0 +1,104 @@ +Created: 20240419T125003 +Key: (private-key (kyber768 (p #0DE94F420165B79701FB24A7669190CF2840ED7 + B96E4B088D45A9DB4512117E39B2FB23754175B64471CF95C0480078FD0A8611D19A15 + 9303B26063DEA88752C00200C8192A287C27ED707D6B830006D821F9C26F0501F85651 + 866C0CAEA481C7CE59D1FD04548E15C565C95DBE6BD0C32500AE9BC838050A073005F4 + C76D05B1780669F4C6B24F27769F76926543753CBF9B53441484120BA0FD1214FA4AD2 + 2E56D63BB1D0B004FC155CB5445ADEF258517D393894A4235221359789C06B649FDACB + 8D290B81EF82C7987638F42603C9B85C3613166591D384524485C07FC0C3DA957A2291 + 0743105B13E22BDC9989988192FF537B294D59601B97A21810051D580F1FCA453C240E + D198F6D3A6F185511CA99029859B5C17240EA443792533B6F63750A0336D1A1166FD29 + B7669999A025B938C304080C1D8B784AAE4703AE2459F7815F8EB4083B69B83276D548 + 26E00A690C82709423549634CC02F0429126B5CFFD29946752B122525C6610F4A3914B + AFC5E0CBB16507158FA5AC29463744F166A5C105C646399455682E8114F78208CBCC95 + 1C94B986BA20690710466547C70B35687FC6047F79C78715CB533C31040C8E34C95C4D + B220F10A8EF6CBCA6B0B5B7704339B430C0530DAEB37CD17C96D3821FDD331C001788A + 9068E913B1A697549D1E32C5D72215365CC9B4C59DC8093EE3482AD0C29EF19341214C + 50419408B2403E4830066D1009D55B14D569F65733D0DF5362030A424A5ABCF25C268C + B087591AD8DA4C6B8A80F11D14552671D71183383520152D2C44B3C76B3C875D5FC432 + BB46A7CE5833E91928AD55D30D7789718364BB43900C98FEE5315C8035DEB94387265C + C4EC48927158077125673CBB649E82B890A16E1E5025E598DD544510D5C133F7C0036E + 665AC2A5951C7A75299777EB8A8C44ABCA15339DE0388320067394321ADCC346C49926 + 487CBB2D9B0D130C53B1471D7A939FE1C323A62C1325690A5866702182F98F550AFD0A + 5551A2D01AC7E66038AD4E7682D642D4EA020939A7FC0E30FF228AADFF935F54CB02BB + 03D7C10A001E81ED1151DDBC77E912297D7F922E255A5AEF979172B218D6CB365222ED + CD6852A30ADEF0CAE5C0C7783493E7A9530FFCB7A490A69735ACB86563AF000C89B922 + D39F6C1F638AF1F0BA5E7B11961EB7FE8B631EB38AD60F2C09FACAB473A71AC391527C + 502BEE27B11115F9CA1869F6033A97590D984100E540AB9AC2744F921DE2C3D2A1B9CC + 58231B755C270BC29242C9693493D88701447AC50011374F8E87A1313415E512D77192 + AA2D084F65C6900E72D41D8826B7CB84C26720685C53F5A47FE0220CBE2CA95C827178 + CC677D1098741C767E55BF52B92D5152029EB30D83CC28ADB7E774B06D64A4C0E75424 + 51188B482778864ABEAC0645B07993F98A202642A59940AFE5161C0C535DEE6386AFC3 + AA98769B0D0927FCB85BB7951B5F76354570B24C93A1B277771FAB0C8ECB9326B070C5 + 124C946B3E53A669FC46FEED668CF2955C87974C0429BCCCC6A9C040B8A93CE49E40D4 + C607CB269087742B4D428819E434C41749708154AE8CB5C1C385B60C509008A8B6F15A + B7FC5BD20FB704939BEE164A180BCD2C0A901FA9F30356336576926E24E3516948A722 + 27672594EEA77AEE903#)(s #218B22DB8B1D760A1A070A26950BB1ACE8C5898C2A319 + 583E20A118A56A1E6BB3422B0BB9F466930B50B932780F9E00274590A13B60014E0B22 + D141D074134F577B15409AD58106AD3012C52329DB8E13BBB0B1A753CB79BE9A233557 + 142A60496E0BEAC54334B2394E7CA8B3175956D0CA2CA404FA1930DF36414EB4C776E7 + A041F3409F61384B1AB7B097729473520D18630ED050F0B3957A41C7E34089CB6029AE + E85A25BC3257E7A3EFCA3617D601735BCCD1CB73AF9BB79E90A248A249009D779F9945 + 0E3D82C5D56AEA8707DFF8410835A24DF37B411F3646D6684F11C1765A2C2BFE55F097 + 10467D62EB4AA0F90049AFFF09B1F66560382A7FA5C91CA1C0A696A2FB86CCB8E53480 + 0A4218FB81033E41DA544907A583BE8BC76321AA5D198C80CA295F5E55D98688D35267 + AC38A0822587A825CC90BC721695A9D4414710DFBA3E14332BC5C86A7A9970A624880B + 518749C959384365CA747D2867EC43343C1C61194D5311B555027ABA759F3602E57214 + 7E20C761125D2E86EE1693F80DB809D79138C0AB299712CAFD298209617DAD830EC3B0 + A70649A76F5BDD143476F951767FC1F6F204E434A604C723379837377C8B1A9067E500 + 34E79CC016F30C11FEBA0DB19C2BF42C3D6590C75E75B0271B02DD664402BA75635145 + BE38733C12DE5054759930F36252F5DB2CEF4587965D49B10A4765036C5D5E001700C0 + F9A813559409B72EB4B564C1EF77B28ADA3319DB98EF0183035C1ADF3445C46C320D44 + 31F8C48251893C7CB7421FF65117239547193A4A843019A70BCC42BBACFE9C5BB172DA + CC8AE5D2B15E8338F2EF58FFCA1191CE576A85B8AE5E99231E1156EC9815E499D260C3 + 1AE804FA983C1A996AD3B538386E4680D2067E64234AF0A055E14C818CC2A29524B056 + 03670393BA01642E99BBFA0BCC2681759116C4E1D705D78197EC3D0726DE2A5F9239F0 + 47089684508870B5C06C8715771A1F908923891BEF548194DE22E433C845B48B69D1A5 + A3A289F3FCA2F7032B6176225FA762C7DDCBE1000088D804CEB11BD03A712E7EA2AE96 + 33F9B8765465912E6B4222C64798AC51DE2E09BA4F9A46944256812ACA99A2B08F6AF9 + 205721C227637EC4DE5D4C001D126ED00CB4D8698F1B45E78079187425AF3086F716C3 + 4C72787132C472860AA7B1A547EE65085652106CAC1B48A0057C8CFCEE2C210D90CCCC + 3629D713C142046CA57BFBB738542E360BE6C1DF072CB425199D3915BBDFB0BE435436 + 7F7273ED0471E5129D8C691D7C66EBBE3ADEC86246C45CBC14C474401CEEA3A39AFE14 + 79051A2FE497C4054063508B3F908B00FE797C0A4C60D396B15920537423AECCA2D634 + 09878173D52B66AA4B6C6CA6020ED63BFD47BA85A196E0C66208C4A61E603B94965642 + 884A624309BD21903A0F5693167906DB315FB7B735D290C5A63B58CC8892A4C52C5BC6 + 0F026648B86B6CDE36E7EC68950E224679A2F29FA658B9B3E67560A8E10B5D5A3CB29C + 02743E66FC3E7C90B0973AFB2BCFE935A1277723993924225AC63A60B35314544A9542 + 2D48FFFB3A3927BACB168A72FCABF1664C3E0C91D73A89381AB6BF95A22ADB5C24E971 + 57A1A1D24BC52FD879E0DE94F420165B79701FB24A7669190CF2840ED7B96E4B088D45 + A9DB4512117E39B2FB23754175B64471CF95C0480078FD0A8611D19A159303B26063DE + A88752C00200C8192A287C27ED707D6B830006D821F9C26F0501F85651866C0CAEA481 + C7CE59D1FD04548E15C565C95DBE6BD0C32500AE9BC838050A073005F4C76D05B17806 + 69F4C6B24F27769F76926543753CBF9B53441484120BA0FD1214FA4AD22E56D63BB1D0 + B004FC155CB5445ADEF258517D393894A4235221359789C06B649FDACB8D290B81EF82 + C7987638F42603C9B85C3613166591D384524485C07FC0C3DA957A22910743105B13E2 + 2BDC9989988192FF537B294D59601B97A21810051D580F1FCA453C240ED198F6D3A6F1 + 85511CA99029859B5C17240EA443792533B6F63750A0336D1A1166FD29B7669999A025 + B938C304080C1D8B784AAE4703AE2459F7815F8EB4083B69B83276D54826E00A690C82 + 709423549634CC02F0429126B5CFFD29946752B122525C6610F4A3914BAFC5E0CBB165 + 07158FA5AC29463744F166A5C105C646399455682E8114F78208CBCC951C94B986BA20 + 690710466547C70B35687FC6047F79C78715CB533C31040C8E34C95C4DB220F10A8EF6 + CBCA6B0B5B7704339B430C0530DAEB37CD17C96D3821FDD331C001788A9068E913B1A6 + 97549D1E32C5D72215365CC9B4C59DC8093EE3482AD0C29EF19341214C50419408B240 + 3E4830066D1009D55B14D569F65733D0DF5362030A424A5ABCF25C268CB087591AD8DA + 4C6B8A80F11D14552671D71183383520152D2C44B3C76B3C875D5FC432BB46A7CE5833 + E91928AD55D30D7789718364BB43900C98FEE5315C8035DEB94387265CC4EC48927158 + 077125673CBB649E82B890A16E1E5025E598DD544510D5C133F7C0036E665AC2A5951C + 7A75299777EB8A8C44ABCA15339DE0388320067394321ADCC346C49926487CBB2D9B0D + 130C53B1471D7A939FE1C323A62C1325690A5866702182F98F550AFD0A5551A2D01AC7 + E66038AD4E7682D642D4EA020939A7FC0E30FF228AADFF935F54CB02BB03D7C10A001E + 81ED1151DDBC77E912297D7F922E255A5AEF979172B218D6CB365222EDCD6852A30ADE + F0CAE5C0C7783493E7A9530FFCB7A490A69735ACB86563AF000C89B922D39F6C1F638A + F1F0BA5E7B11961EB7FE8B631EB38AD60F2C09FACAB473A71AC391527C502BEE27B111 + 15F9CA1869F6033A97590D984100E540AB9AC2744F921DE2C3D2A1B9CC58231B755C27 + 0BC29242C9693493D88701447AC50011374F8E87A1313415E512D77192AA2D084F65C6 + 900E72D41D8826B7CB84C26720685C53F5A47FE0220CBE2CA95C827178CC677D109874 + 1C767E55BF52B92D5152029EB30D83CC28ADB7E774B06D64A4C0E7542451188B482778 + 864ABEAC0645B07993F98A202642A59940AFE5161C0C535DEE6386AFC3AA98769B0D09 + 27FCB85BB7951B5F76354570B24C93A1B277771FAB0C8ECB9326B070C5124C946B3E53 + A669FC46FEED668CF2955C87974C0429BCCCC6A9C040B8A93CE49E40D4C607CB269087 + 742B4D428819E434C41749708154AE8CB5C1C385B60C509008A8B6F15AB7FC5BD20FB7 + 04939BEE164A180BCD2C0A901FA9F30356336576926E24E3516948A72227672594EEA7 + 7AEE9037C525E6180138B80E2CA84C2BEEF3319A65284D35117FA4853E2E6DC7F2EADF + D9351CFC435F23FA9D2C91DD9EF3F8ABDB7784586949C248606273835C099D53A#))) diff --git a/tests/openpgp/privkeys/8F9ABF3E5BBFC50D168DD524EB8F7263E7B33859.key b/tests/openpgp/privkeys/8F9ABF3E5BBFC50D168DD524EB8F7263E7B33859.key new file mode 100644 index 000000000..8a047886b --- /dev/null +++ b/tests/openpgp/privkeys/8F9ABF3E5BBFC50D168DD524EB8F7263E7B33859.key @@ -0,0 +1,5 @@ +Created: 20240419T125051 +Key: (private-key (ecc (curve X448)(q #5E42BC08BE62F4D740196FC1888D18F1 + D1BD6D21DAC63C7265BE2897F1C2CE5E9E2140AA3B65620FE0EA2FB443952821AD0596 + 7A6D32D849#)(d #28FCD007DA2A8D37E94628291FD0BDCFE06F07D1586A1FEF914A12 + 092896727F260F49B6A80081A89603F10FF9B40719BF16D20F2E5DA6D2#))) diff --git a/tests/openpgp/privkeys/A1598F57316F7FEC3F946895E35A7D2EAE8D3A13.key b/tests/openpgp/privkeys/A1598F57316F7FEC3F946895E35A7D2EAE8D3A13.key new file mode 100644 index 000000000..6a86fe240 --- /dev/null +++ b/tests/openpgp/privkeys/A1598F57316F7FEC3F946895E35A7D2EAE8D3A13.key @@ -0,0 +1,137 @@ +Created: 20240419T125051 +Key: (private-key (kyber1024 (p #76E799415B04C5B048D8671C59439A7134263C + 18127971232947AA66D66DF13476E0AC5F81736316D38E8FC94E07144B32856A2F7725 + EA1C93A6D4C2668008F77BC41B16B479F313542ACAD6F248A340B9790880B3875D4777 + 6692EA64BC939F880482FE3A981FC88BB9CA36E339BD5175167E73948122AEF0555CFE + 736FA7FC4A36C4634B4502ADB454DA04584C8B1C8F531194A74B15391BBCCA8EDA75BA + C52A75ED11AA3832C7AC00D07A6C6F2238648A7056E3A11BDEA47DFBDB5C6DC55A33E2 + AC5D3826230993BCF960E2D82FAE7273518C1F4B21B8DD3175496987FC1768D8DA9778 + 6C219C054507636901656AE8F62A64B73C179CA5F55C9CD55B54452228408001AADA10 + 6A3C22F320B590C693B1891D82666BA04101810B140B52B20B783C0CA8B875958D75DC + 815805AE85B53501A683E5EB95DB4B61C29ABACF2B31320CB60200648BBA82CCC0A92C + 790583E12CC65643299C544A2219879C512783559851616AD7371C7A21A72BAE6D618A + 65BA32B8C24FEEF25191C5C85E08B4B854AA99A5A386058B9E56C4CB92906EBC811638 + 4ADF96673CC22063462D34D679FDFA632109B9917B2485E8BE80D8025CEA2AA61488B8 + 82B66811B24457C0B11BBD4759625EA290EC67B10C438D5112CDA20993B67C4AE71573 + 235023DC1BAB2D477F7EE882677A3FC7325349854C933AB863E36EF18AAC9A0376B89B + 3764058D7039A8987162C5B2A698B98A4BE4842C065520E253EFDCC0A460BBC1E753B3 + 3A77FE47837CB9B106B5B3737C5D1030CB8F27864E57C54D424A5C69B745E718D2871B + 9A9B7B5C73221FFC8879F4B23211A08A23CE33381EDB972E0BB710B9DC81D6B78BB4EC + 2D856AB14372C32C35BD4188B650F97B954A97736892D2B487F8756821FB308A7B1456 + B1A0C48090DD311AF6AC16FAC8CC4EF4BDFDD47C79E9829ABA0D91F82FE474B58D0049 + A8D15C0ED7ACF154CCBAF398E749B67FFCA176003E72FB00D33CC9E55C18C94C8B7C53 + 48267B9053FA89993AA693DC9291DC9F81E0422FD2BD19029D9BDB88C812A9953C9C9C + B44BA1E6B8470715BE365560B0841428AB11FBA77B9A5A9C442FE35B49481BBEC24657 + F4D20B36B466D1E85C29F2BFD2C784A3C661133C5B8578030D219F6AA9B62E1A6C60C3 + 093B63C8A3484DFFC32847B305F0889411D965EDF132F3B22106276288B44AA91019E6 + C161A472698E380AFC6635497890902CCF937340F73A4A79692700DBC65A4103D47810 + 3C6032668773C91AB63F8729CB897D2B4BAB14A5B6B669BC82162EBB33C752883F14E8 + 2122333B8A6C6C8C4C81610500F5E44F93F389BDD5C5F51AB8A18BCDE75B082E12A58F + 92482FF82E37A26849851C7B933218512794A3649A38B5881035594486B8B7C378D69A + FF18C62C64A27CB740ED1AA84216A796B874DE7CC0D9A4C230A35254829A8745CF523A + 59B5B873B2F03A16CA466876B08781167035863EBC2456C04DC37C8409373CB83ACBDE + DC85B41BADC1831A15A1405D503BE8ECA6B79964A4D186C8D9AC57366BB2A2300CF7A8 + 1B4C8188AB0355E46F28D60416E509F6F034C58056DD27A0A0ABB6A8AB9AEAB8047E57 + 60F7FC3B870A82FF22B408B647A7B497CE555BC632ADDFD1A1E547A06E581C54901695 + 7948F8A745EAC57DBDDAADDA376DD2C643F30366A7F913FFC89A3479C96A4725B8D58F + F4580B3BF5134E027DBA4C6E0F8C5C6E8270D7E1AF10AC7C0EB4A52FB8A0415A9AFE79 + 668F629BB140282781892E88037A84662EEB079A6B1927167DD27909C5188C9AAC1DE3 + 37C555807665C57C8F829DBB3BB74899A4AF831FB6316122989772A57ADE899F990407 + F7FCBC6704670238626A6249AD8665C8AA9302786904EA8ADBD21893246F817AAD0193 + 35E478B257975D39C60DF7AA080F26B37014ABA53C8E4F205BCD049512197200CA5FFF + 8B243E5546FB4A17250376238CB8B3535FB10B773A6CA6179936490ACB8280571A7C35 + 656CA35352279EDA55CD12816BA51C2AA072C2A628AF24CCA8BABD193757DD16615B34 + 09FDF045390C4346792A0D8B2399697BC485B9D8510316C9AF66B6A08E74B1301186E9 + 9ABA3ABB5DB68BC8172C8DF677B78FA60F247B45D3B14D39164592F53DE39AB6B4A96C + 7949964F204C919A576B515F4BF9BB6ABFCE4DD7B5969DB8ECE3DA32CE298B573793F3 + E45248B0CBCFF67D79#)(s #1A8B03F87A2BAACB60D8261B32AC2742BB83BA4014C7E2 + 6847613CF7A7BD44D1C428F4009AE4C42F12CF39E283A5DA2632B649F259ACAD157DFE + 9086B6F0CE919B6490499597AB809EBBA71DD55D6FCC61DF5067C78C8D1907745C703D + 1BE25F0E18057A496FB476C47C8C01CD656619C7213D61223A124B15D38B27F0686907 + 0D0D47476A756FE629C2F516A9F527044BA5931FB8B2EC23A415B9CD510C1233270A7E + C209F245CA82C93B7BF40C2CBB20213A8650EA6934D910B1D80BCCFC9B169704AF7ACA + 2038205CE193C931514865BF5629A901E0BFEFE78FC8657A16999AD4F14AB51648F329 + 08E8FA9A22A35C936888E03581588ABCAF016A1A920BFF394EBD3840EA47731E677E9D + E77CF30701EB805C1A91A5BE531BD400022D19C350E809288A9F6542C5EF391C61C48B + CED9079E691490E92EB60BA7088720873755B997A2A62A1665876CF91B3E4682200993 + 57F94A8B035699D19B64EB480E41074FC011A64508226C7A21B4F2348FE8151A47912B + E96454541CD54A3CE5D74C92643E4210C306F6A10CC890EE5A7575F0853123693211B6 + CE8CB16EB05BDE0933B850270C86B01B026B4F11A6DB12CFE06C79809A8F5357B2E749 + 530D584A76F13E3FEA98003390B56885B43C1BEF82A4E87AB07B19B47689B8D6C4ADAE + 2178886517BCC1C0642A944C426AE6C8540331B73D524DA449BA91F0CBD2558175A9CD + 693B3DC8545D68B97BD3D212D395B1BC4437D40C2AEB5013B829AA40EA7913737730B7 + 252C266E5AB011928BA68D681012BA066257A5DF8C41392970258B9FCDEB133D6C1A71 + DC2C23B52FB6BB8267951C25621ED620CF929517B6F3B233331E80365FAA06978247BC + 01573CFD592F39932B4076BFCFC23F28F2892724761DC02FFD722D795285653AC0B6D0 + 6341B45B980092BAAB270AF4AAAA8AAEFE0896B19B5190A6108205B999199ABFB1BD0C + 15A53CA723BE569BE3912E4C552973A45A356CC88208689C7847D4370456A59D5CB7B6 + 50E8A0C41141C3EC0999E31ED5E7A938C0031A112218E715EA387DA1F327D93B4134F8 + 0C32C960D211CAB173CFF3029E9A10A222985131398C528C6D2B644464590DCAB105B1 + BABAB97C33D2E77C41D417022940A31A72CA30AD9596AB998C5B26152A98685E991738 + E9A9228D1C859C899D76AA1F0C68568C83897751527B462F8842225C118B786CAE710A + 57AFB16577B7BDBBF19CD8B74C035162C5C6967712CF46EC8CE3CC817CBBB5D7B11F6C + 645A2B784A5E226CE2D522236C74CBC5A9CFE26CE4ACB08300826589B8F9B870582390 + 9E2930B5945342DCB592B56D80C13B54C3B1F84BA58E66C102A639E6B1A3C7B4202A6A + 98A1F82668F6C4D61BCF96B3AB8FB132E67A251407207BB467BFB02FD90B04C54809E1 + 12B347BBACFBBC5FA2D16627499AB8C8439D89299EA4C363F46474F8B568511ED3A614 + 797015BC4C25E41B3C3A674CE9A6241FDA07A9027608BB0248FA20671A8E6CF461A989 + 24F314CA7F37C03D397B2E760C9C101717E83064F198ED52098DC7B18D08CD06925C26 + 039536B57E82902CD6E33AEA0A65231A58BBB694FCC76D9985486938BDC8E61244114B + 7CE7C0D466907AF309FFF09A89203755843B4EB89FC7F5C357321BC79B0528941682BC + 2213CC8408552368158C73448EE71C67A40BC6B76251FE860AE08C7922E3CADDBC64F1 + B56000075293970906D848AF430F4B9186A4A50EE2505BEE0084F0A2923FF4A7938009 + 7670B422D2A10D083312329FB24B3F256B37DB05BB10FC464EC1BE48B4A61CE98D8FE7 + 667EFB10CBBB5300F3944CFA403C03CF83023640895A8BD859A4DAA9036450A79775D7 + F83B37CBAAB2454CC3158E8A5152F9E816DACC4693B34FBF238AFA43724637C83EDAAA + 608C36DC15026255CB0B8B4A17284086052C9B449B80D154EDC07A16D3AA0E2B9177F1 + 7D96AA6162D47828400939C22CCB019293528E06E947A8D8C7BB20A0BBA277B45AB677 + 0155CB14C0016B4E64E43F91E8CE660BAECD371512B5A29ED3B759F9C3813314241950 + BF9862079011F6B233C2897C75C63DFFE418759105D4CA1D5470389FC2C0B623412CD4 + A208530A1FDCB743717980926AAA928A55498C1ED4C183F37E26777F405CA949237BD9 + 793A025A8A27773976E799415B04C5B048D8671C59439A7134263C18127971232947AA + 66D66DF13476E0AC5F81736316D38E8FC94E07144B32856A2F7725EA1C93A6D4C26680 + 08F77BC41B16B479F313542ACAD6F248A340B9790880B3875D47776692EA64BC939F88 + 0482FE3A981FC88BB9CA36E339BD5175167E73948122AEF0555CFE736FA7FC4A36C463 + 4B4502ADB454DA04584C8B1C8F531194A74B15391BBCCA8EDA75BAC52A75ED11AA3832 + C7AC00D07A6C6F2238648A7056E3A11BDEA47DFBDB5C6DC55A33E2AC5D3826230993BC + F960E2D82FAE7273518C1F4B21B8DD3175496987FC1768D8DA97786C219C0545076369 + 01656AE8F62A64B73C179CA5F55C9CD55B54452228408001AADA106A3C22F320B590C6 + 93B1891D82666BA04101810B140B52B20B783C0CA8B875958D75DC815805AE85B53501 + A683E5EB95DB4B61C29ABACF2B31320CB60200648BBA82CCC0A92C790583E12CC65643 + 299C544A2219879C512783559851616AD7371C7A21A72BAE6D618A65BA32B8C24FEEF2 + 5191C5C85E08B4B854AA99A5A386058B9E56C4CB92906EBC8116384ADF96673CC22063 + 462D34D679FDFA632109B9917B2485E8BE80D8025CEA2AA61488B882B66811B24457C0 + B11BBD4759625EA290EC67B10C438D5112CDA20993B67C4AE71573235023DC1BAB2D47 + 7F7EE882677A3FC7325349854C933AB863E36EF18AAC9A0376B89B3764058D7039A898 + 7162C5B2A698B98A4BE4842C065520E253EFDCC0A460BBC1E753B33A77FE47837CB9B1 + 06B5B3737C5D1030CB8F27864E57C54D424A5C69B745E718D2871B9A9B7B5C73221FFC + 8879F4B23211A08A23CE33381EDB972E0BB710B9DC81D6B78BB4EC2D856AB14372C32C + 35BD4188B650F97B954A97736892D2B487F8756821FB308A7B1456B1A0C48090DD311A + F6AC16FAC8CC4EF4BDFDD47C79E9829ABA0D91F82FE474B58D0049A8D15C0ED7ACF154 + CCBAF398E749B67FFCA176003E72FB00D33CC9E55C18C94C8B7C5348267B9053FA8999 + 3AA693DC9291DC9F81E0422FD2BD19029D9BDB88C812A9953C9C9CB44BA1E6B8470715 + BE365560B0841428AB11FBA77B9A5A9C442FE35B49481BBEC24657F4D20B36B466D1E8 + 5C29F2BFD2C784A3C661133C5B8578030D219F6AA9B62E1A6C60C3093B63C8A3484DFF + C32847B305F0889411D965EDF132F3B22106276288B44AA91019E6C161A472698E380A + FC6635497890902CCF937340F73A4A79692700DBC65A4103D478103C6032668773C91A + B63F8729CB897D2B4BAB14A5B6B669BC82162EBB33C752883F14E82122333B8A6C6C8C + 4C81610500F5E44F93F389BDD5C5F51AB8A18BCDE75B082E12A58F92482FF82E37A268 + 49851C7B933218512794A3649A38B5881035594486B8B7C378D69AFF18C62C64A27CB7 + 40ED1AA84216A796B874DE7CC0D9A4C230A35254829A8745CF523A59B5B873B2F03A16 + CA466876B08781167035863EBC2456C04DC37C8409373CB83ACBDEDC85B41BADC1831A + 15A1405D503BE8ECA6B79964A4D186C8D9AC57366BB2A2300CF7A81B4C8188AB0355E4 + 6F28D60416E509F6F034C58056DD27A0A0ABB6A8AB9AEAB8047E5760F7FC3B870A82FF + 22B408B647A7B497CE555BC632ADDFD1A1E547A06E581C549016957948F8A745EAC57D + BDDAADDA376DD2C643F30366A7F913FFC89A3479C96A4725B8D58FF4580B3BF5134E02 + 7DBA4C6E0F8C5C6E8270D7E1AF10AC7C0EB4A52FB8A0415A9AFE79668F629BB1402827 + 81892E88037A84662EEB079A6B1927167DD27909C5188C9AAC1DE337C555807665C57C + 8F829DBB3BB74899A4AF831FB6316122989772A57ADE899F990407F7FCBC6704670238 + 626A6249AD8665C8AA9302786904EA8ADBD21893246F817AAD019335E478B257975D39 + C60DF7AA080F26B37014ABA53C8E4F205BCD049512197200CA5FFF8B243E5546FB4A17 + 250376238CB8B3535FB10B773A6CA6179936490ACB8280571A7C35656CA35352279EDA + 55CD12816BA51C2AA072C2A628AF24CCA8BABD193757DD16615B3409FDF045390C4346 + 792A0D8B2399697BC485B9D8510316C9AF66B6A08E74B1301186E99ABA3ABB5DB68BC8 + 172C8DF677B78FA60F247B45D3B14D39164592F53DE39AB6B4A96C7949964F204C919A + 576B515F4BF9BB6ABFCE4DD7B5969DB8ECE3DA32CE298B573793F3E45248B0CBCFF67D + 7994C02B6A67177C09FD8A3F3F2630D907A48ABB59A77AC1F75F344ED2846963561053 + B1E9F15F14583281F621DD991A24EA473FDA7C63FE59C80F5F49708EE520#))) diff --git a/tests/openpgp/privkeys/DC60E0AE48E0F14E8FD7C9C36E18C6651E99BA93.key b/tests/openpgp/privkeys/DC60E0AE48E0F14E8FD7C9C36E18C6651E99BA93.key new file mode 100644 index 000000000..7170d0ff2 --- /dev/null +++ b/tests/openpgp/privkeys/DC60E0AE48E0F14E8FD7C9C36E18C6651E99BA93.key @@ -0,0 +1,5 @@ +Created: 20240419T124916 +Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q + #405D1A8C6FB60828BEF043119A1DF97E3A6A408CF3E0CD56F74F9522A7BAACD51C#) + (d #ACF7F220B124A7C726F40DE83D07EFB9165814E9A42EFD9ECB53B27401D85BB3#) + )) diff --git a/tests/openpgp/privkeys/F5DB116462B7BD2FA83A4453C4DFA2AE8604FB59.key b/tests/openpgp/privkeys/F5DB116462B7BD2FA83A4453C4DFA2AE8604FB59.key new file mode 100644 index 000000000..7f51be489 --- /dev/null +++ b/tests/openpgp/privkeys/F5DB116462B7BD2FA83A4453C4DFA2AE8604FB59.key @@ -0,0 +1,5 @@ +Created: 20240419T125029 +Key: (private-key (ecc (curve Ed25519)(flags eddsa)(q + #40F0C11FA63250E08BD9D0E766417EA5F4E4366B7D60692A442F71E37CFB19EAE4#) + (d #A2319B2E7599FD1AA04578C01EFAECC82B1EDFA8FAB85928244BABB0733653B0#) + )) diff --git a/tests/openpgp/samplekeys/README b/tests/openpgp/samplekeys/README index 682dfc06e..8e8b598b3 100644 --- a/tests/openpgp/samplekeys/README +++ b/tests/openpgp/samplekeys/README @@ -23,10 +23,12 @@ rsa-primary-auth-only.pub.asc rsa2408 primary only, usage: cert,auth rsa-primary-auth-only.sec.asc Ditto but the secret keyblock. v5-sample-1-pub.asc A version 5 key (ed25519/cert,sign,v5+cv25519/v5) v5-sample-1-sec.asc Ditto, but the secret keyblock (unprotected). +pqc-sample-1.key.asc ky768_cv25519 public key. [*] +pqc-sample-2.key.asc ky1024_cv448 public key. [*] Notes: - +- A [*] marks public keys with their private parts in ../privkeys. - pgp-desktop-skr.asc is a secret keyblock without the uid and subkey binding signatures. When exporting a secret key from PGP desktop such a file is created which is then directly followed by a separate diff --git a/tests/openpgp/samplekeys/pqc-sample-1.key.asc b/tests/openpgp/samplekeys/pqc-sample-1.key.asc new file mode 100644 index 000000000..984495514 --- /dev/null +++ b/tests/openpgp/samplekeys/pqc-sample-1.key.asc @@ -0,0 +1,46 @@ +sec ed25519 2024-04-19 [SC] + 652B01FF34D43EA62C5DC897E47CC8B150A7A02E + Keygrip = DC60E0AE48E0F14E8FD7C9C36E18C6651E99BA93 +uid [ultimate] pqc-sample-1 +ssb ky768_cv25519 2024-04-19 [E] + CF06288CAAAA850A8B5B2927C8C14C7F0A8906AAEA320DE12A0A15F8E8746216 + Keygrip = 2F4CD0990D56D41A74456668469E3139A7960CD4, + 8B2E1355C97C34E0AC1CBC9DFDF2526BFE8990A7 + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEZiJoTBYJKwYBBAHaRw8BAQdAXRqMb7YIKL7wQxGaHfl+OmpAjPPgzVb3T5Ui +p7qs1Ry0DHBxYy1zYW1wbGUtMYiTBBMWCgA7AhsDBQsJCAcCAiICBhUKCQgLAgQW +AgMBAh4HAheAFiEEZSsB/zTUPqYsXciX5HzIsVCnoC4FAmYnnBwACgkQ5HzIsVCn +oC6AIQD/QRW5cK76Fmzo2L/a4BO8a/Ui2Euqp74iOLTYMTa0QikA/jz/8YWk+VJ8 +pFZkuPvkMpYFb8Mo+WtmTpyM7b26zQMEuQTVBWYiaHsdAAAEywMrZW4BB0BkOEEb +Lj6i6ki2gYYMLKU3l4xpByy9BKQAaeEiZg9vNwAABKAN6U9CAWW3lwH7JKdmkZDP +KEDte5bksIjUWp20USEX45svsjdUF1tkRxz5XASAB4/QqGEdGaFZMDsmBj3qiHUs +ACAMgZKih8J+1wfWuDAAbYIfnCbwUB+FZRhmwMrqSBx85Z0f0EVI4VxWXJXb5r0M +MlAK6byDgFCgcwBfTHbQWxeAZp9MayTyd2n3aSZUN1PL+bU0QUhBILoP0SFPpK0i +5W1jux0LAE/BVctURa3vJYUX05OJSkI1IhNZeJwGtkn9rLjSkLge+Cx5h2OPQmA8 +m4XDYTFmWR04RSRIXAf8DD2pV6IpEHQxBbE+Ir3JmJmIGS/1N7KU1ZYBuXohgQBR +1YDx/KRTwkDtGY9tOm8YVRHKmQKYWbXBckDqRDeSUztvY3UKAzbRoRZv0pt2aZma +AluTjDBAgMHYt4Sq5HA64kWfeBX460CDtpuDJ21Ugm4AppDIJwlCNUljTMAvBCkS +a1z/0plGdSsSJSXGYQ9KORS6/F4MuxZQcVj6WsKUY3RPFmpcEFxkY5lFVoLoEU94 +IIy8yVHJS5hrogaQcQRmVHxws1aH/GBH95x4cVy1M8MQQMjjTJXE2yIPEKjvbLym +sLW3cEM5tDDAUw2us3zRfJbTgh/dMxwAF4ipBo6ROxppdUnR4yxdciFTZcybTFnc +gJPuNIKtDCnvGTQSFMUEGUCLJAPkgwBm0QCdVbFNVp9lcz0N9TYgMKQkpavPJcJo +ywh1ka2NpMa4qA8R0UVSZx1xGDODUgFS0sRLPHazyHXV/EMrtGp85YM+kZKK1V0w +13iXGDZLtDkAyY/uUxXIA13rlDhyZcxOxIknFYB3ElZzy7ZJ6CuJChbh5QJeWY3V +RFENXBM/fAA25mWsKllRx6dSmXd+uKjESryhUzneA4gyAGc5QyGtzDRsSZJkh8uy +2bDRMMU7FHHXqTn+HDI6YsEyVpClhmcCGC+Y9VCv0KVVGi0BrH5mA4rU52gtZC1O +oCCTmn/A4w/yKKrf+TX1TLArsD18EKAB6B7RFR3bx36RIpfX+SLiVaWu+XkXKyGN +bLNlIi7c1oUqMK3vDK5cDHeDST56lTD/y3pJCmlzWsuGVjrwAMibki059sH2OK8f +C6XnsRlh63/otjHrOK1g8sCfrKtHOnGsORUnxQK+4nsREV+coYafYDOpdZDZhBAO +VAq5rCdE+SHeLD0qG5zFgjG3VcJwvCkkLJaTST2IcBRHrFABE3T46HoTE0FeUS13 +GSqi0IT2XGkA5y1B2IJrfLhMJnIGhcU/Wkf+AiDL4sqVyCcXjMZ30QmHQcdn5Vv1 +K5LVFSAp6zDYPMKK2353SwbWSkwOdUJFEYi0gneIZKvqwGRbB5k/mKICZCpZlAr+ +UWHAxTXe5jhq/Dqph2mw0JJ/y4W7eVG192NUVwskyTobJ3dx+rDI7LkyawcMUSTJ +RrPlOmafxG/u1mjPKVXIeXTAQpvMzGqcBAuKk85J5A1MYHyyaQh3QrTUKIGeQ0xB +dJcIFUroy1wcOFtgxQkAiotvFat/xb0g+3BJOb7hZKGAvNLAqQH6nzA1YzZXaSbi +TjUWlIpyInZyWU7qd67pA4h4BBgWCgAgFiEEZSsB/zTUPqYsXciX5HzIsVCnoC4F +AmYiaHsCGwwACgkQ5HzIsVCnoC4X2gD+K/GMuumoiRpDxEMHbzUfdc1lPBy55MNl +3CPRl3Xqoy8A+gIt6w5h3qWdP0DrrkdQub3uQ+XGhdp7GQTgkltOzfsC +=Zup3 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/openpgp/samplekeys/pqc-sample-2.key.asc b/tests/openpgp/samplekeys/pqc-sample-2.key.asc new file mode 100644 index 000000000..d803e0320 --- /dev/null +++ b/tests/openpgp/samplekeys/pqc-sample-2.key.asc @@ -0,0 +1,55 @@ +sec ed25519 2024-04-19 [SC] + 6BF41D6AC221F5223C2DEEE320E629089768AD93 + Keygrip = F5DB116462B7BD2FA83A4453C4DFA2AE8604FB59 +uid [ultimate] pqc-sample-2 +ssb ky1024_cv448 2024-04-19 [E] + 2D0F59CAFD12DBD9DF9EFD602D7E8F8C2121A5D1841174346D6C8FE8F9AA7683 + Keygrip = 8F9ABF3E5BBFC50D168DD524EB8F7263E7B33859, + A1598F57316F7FEC3F946895E35A7D2EAE8D3A13 + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEZiJolRYJKwYBBAHaRw8BAQdA8MEfpjJQ4IvZ0OdmQX6l9OQ2a31gaSpEL3Hj +fPsZ6uS0DHBxYy1zYW1wbGUtMoiTBBMWCgA7AhsDBQsJCAcCAiICBhUKCQgLAgQW +AgMBAh4HAheAFiEEa/QdasIh9SI8Le7jIOYpCJdorZMFAmYnnDgACgkQIOYpCJdo +rZNYHAD/WZ/YV3lqcLTOs3u6XSskKVlf4jxAI9/tzRfG8M7qXPkBAOHzfq/CWJss +Y7Vzh/ZT7/96gNhj3wzjJyjMZ2pSXlEFuQZsBWYiaKsdAAAGYgMrZW8Bv15CvAi+ +YvTXQBlvwYiNGPHRvW0h2sY8cmW+KJfxws5eniFAqjtlYg/g6i+0Q5UoIa0Flnpt +MthJAAAGIHbnmUFbBMWwSNhnHFlDmnE0JjwYEnlxIylHqmbWbfE0duCsX4FzYxbT +jo/JTgcUSzKFai93Jeock6bUwmaACPd7xBsWtHnzE1QqytbySKNAuXkIgLOHXUd3 +ZpLqZLyTn4gEgv46mB/Ii7nKNuM5vVF1Fn5zlIEirvBVXP5zb6f8SjbEY0tFAq20 +VNoEWEyLHI9TEZSnSxU5G7zKjtp1usUqde0Rqjgyx6wA0HpsbyI4ZIpwVuOhG96k +ffvbXG3FWjPirF04JiMJk7z5YOLYL65yc1GMH0shuN0xdUlph/wXaNjal3hsIZwF +RQdjaQFlauj2KmS3PBecpfVcnNVbVEUiKECAAaraEGo8IvMgtZDGk7GJHYJma6BB +AYELFAtSsgt4PAyouHWVjXXcgVgFroW1NQGmg+XrldtLYcKaus8rMTIMtgIAZIu6 +gszAqSx5BYPhLMZWQymcVEoiGYecUSeDVZhRYWrXNxx6Iacrrm1himW6MrjCT+7y +UZHFyF4ItLhUqpmlo4YFi55WxMuSkG68gRY4St+WZzzCIGNGLTTWef36YyEJuZF7 +JIXovoDYAlzqKqYUiLiCtmgRskRXwLEbvUdZYl6ikOxnsQxDjVESzaIJk7Z8SucV +cyNQI9wbqy1Hf37ogmd6P8cyU0mFTJM6uGPjbvGKrJoDdribN2QFjXA5qJhxYsWy +ppi5ikvkhCwGVSDiU+/cwKRgu8HnU7M6d/5Hg3y5sQa1s3N8XRAwy48nhk5XxU1C +Slxpt0XnGNKHG5qbe1xzIh/8iHn0sjIRoIojzjM4HtuXLgu3ELncgda3i7TsLYVq +sUNywyw1vUGItlD5e5VKl3NoktK0h/h1aCH7MIp7FFaxoMSAkN0xGvasFvrIzE70 +vf3UfHnpgpq6DZH4L+R0tY0ASajRXA7XrPFUzLrzmOdJtn/8oXYAPnL7ANM8yeVc +GMlMi3xTSCZ7kFP6iZk6ppPckpHcn4HgQi/SvRkCnZvbiMgSqZU8nJy0S6HmuEcH +Fb42VWCwhBQoqxH7p3uaWpxEL+NbSUgbvsJGV/TSCza0ZtHoXCnyv9LHhKPGYRM8 +W4V4Aw0hn2qpti4abGDDCTtjyKNITf/DKEezBfCIlBHZZe3xMvOyIQYnYoi0SqkQ +GebBYaRyaY44CvxmNUl4kJAsz5NzQPc6SnlpJwDbxlpBA9R4EDxgMmaHc8katj+H +KcuJfStLqxSltrZpvIIWLrszx1KIPxToISIzO4psbIxMgWEFAPXkT5Pzib3VxfUa +uKGLzedbCC4SpY+SSC/4LjeiaEmFHHuTMhhRJ5SjZJo4tYgQNVlEhri3w3jWmv8Y +xixkony3QO0aqEIWp5a4dN58wNmkwjCjUlSCmodFz1I6WbW4c7LwOhbKRmh2sIeB +FnA1hj68JFbATcN8hAk3PLg6y97chbQbrcGDGhWhQF1QO+jspreZZKTRhsjZrFc2 +a7KiMAz3qBtMgYirA1XkbyjWBBblCfbwNMWAVt0noKCrtqirmuq4BH5XYPf8O4cK +gv8itAi2R6e0l85VW8Yyrd/RoeVHoG5YHFSQFpV5SPinRerFfb3ardo3bdLGQ/MD +Zqf5E//ImjR5yWpHJbjVj/RYCzv1E04CfbpMbg+MXG6CcNfhrxCsfA60pS+4oEFa +mv55Zo9im7FAKCeBiS6IA3qEZi7rB5prGScWfdJ5CcUYjJqsHeM3xVWAdmXFfI+C +nbs7t0iZpK+DH7YxYSKYl3Klet6Jn5kEB/f8vGcEZwI4YmpiSa2GZciqkwJ4aQTq +itvSGJMkb4F6rQGTNeR4sleXXTnGDfeqCA8ms3AUq6U8jk8gW80ElRIZcgDKX/+L +JD5VRvtKFyUDdiOMuLNTX7ELdzpspheZNkkKy4KAVxp8NWVso1NSJ57aVc0SgWul +HCqgcsKmKK8kzKi6vRk3V90WYVs0Cf3wRTkMQ0Z5Kg2LI5lpe8SFudhRAxbJr2a2 +oI50sTARhumaujq7XbaLyBcsjfZ3t4+mDyR7RdOxTTkWRZL1PeOatrSpbHlJlk8g +TJGaV2tRX0v5u2q/zk3XtZaduOzj2jLOKYtXN5Pz5FJIsMvP9n15iHgEGBYKACAW +IQRr9B1qwiH1Ijwt7uMg5ikIl2itkwUCZiJoqwIbDAAKCRAg5ikIl2itk36RAQCk +efX2FiFvTEb/SmxMUxNdBXeWGGeAMH3nURRQ/Dz6wQEAlsPzv1lXH3zNLyuhoJrF +lUaDFf52BzCT6VOhK7yR8Ac= +=MDdc +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/openpgp/samplemsgs/pqc-sample-1.enc.asc b/tests/openpgp/samplemsgs/pqc-sample-1.enc.asc new file mode 100644 index 000000000..c07b46fb4 --- /dev/null +++ b/tests/openpgp/samplemsgs/pqc-sample-1.enc.asc @@ -0,0 +1,81 @@ +-----BEGIN PGP MESSAGE----- + +hQSaA88GKIyqqoUKHQEA0pRJ6Vj5C0XlgpwLd18OLgMMQJ9nw68AA2f/tCrZBVcA +AARAdHv1SfxOewaAWAp79c8vesQ1ToGOeM/2l8LXhbCB67f5RFkdJVl9yY1WyTpz +IHnlynbB53sNvoS2re+fKySS7fj9nE6n7+RF+NNkS3z7aSPUaJ71Yk3tYZDP+mLd +45g4eqj8O7hpwgS0bCq4a35Oq41dNS7g2S9psgdlC7BGRnzVwPh1v5jF7PTb9WdQ +2GCmvR4Mo87McT5YLv0GNg51aYbx6iD2clcuhBEKx85E+DMnU7+BWqC/Ly+It8d8 +/gPQha7y4ZMkfNlaHSJtcmOqS9gDek+auLYFUqfrvxo8Kmza7bdsRiN8OeP+o/06 +tPNnRkeOp94jbwUjoIbTlZn55qYD0w5FX7yfZPgfUYqEHT+R5zYU1ow3hmt+18zz +L0bpk+GsCEfSyNHlx9R7W5MTvhjP32Xki/UZKy/4WcqiqZQbqJ7KxpE9ATl9XE+/ +5BzmMbVzdaeOgulOJiLxsvZxFhXTVWYJJMtYExzC1jRw4sic8t/PWy1sPE6un9PZ +oBXOMSnbF2sVFueuFGH7thUI2ZI4oUBV9fM8SDUgHuw6oC3VCOtBuCJ5r6uA7ZaP +i8U0CULEHX0sS8SHoL+QIdfG6MHM0w9zNk1d6LhVvlwyGuyHuBDjNJRoJz3URnIc +UvUC2s60tytiuZLLuMZlUooxcDC+Fp5k2ejNP5AWfT1LQUMdV8vRGKiWaL1PbY1M +96PqA3NDZyd9MJn3o74MEA19HPRNTInTW0xwWejZty6hTLvrBMpZSaTxFwmUuUdb +81LES4AkeWH4SJxS8xse2dlD2JK2tYYZPGgkgj5BIAT3J4/Cy9hgdls5NFPZDNUe +cXxz1LRPvewWxjmv7X5H6niBeHCOHXYXYbUTHw8/acDt/HEjYo6yBu3C7MXn5Ga6 +FvC9XWZAQTiicU6cF7U6/TQWQqZWhrdPyWD9/x3iUr4mJsOl3RBBT3Koz7Tyo41H +RqweL+sCYf1tmgIUsLRVZBVOR1JNRkuW4PL0jBR/rsvDWBQShjFvWb8DiKXhm7pK +1DSpMhiuV2BQuVnMls3aw40V9TPaq/dxqj9U/LIRW2vR9sza3ulS7UWL0ZbgLMjz +hq0nU1XRqstTExGwlokt8TJGfsX15yIllLt6iajXD5kiTzhS2iuuXYq4Fx/LjRoQ +W1VglExBdfy0hjFWQMoKZ0f6SjfoIdqKDZDZ1ygKB4UJW0UE0Wmhq5imY1ih/Jb3 +CR5ksXqp4QDr1oCOo4ZtDANGDOyAWAGxsBW0tRMTqcS1J5LT8RKf6wsti14EFOtp +d/fNUvFz5RMYKdDkRb4V14iwgCsGCpShOyDorN+g4Lya3gEIKfG4Qlkg+J6N426L +jwE1Jxx4S+sMzFii7bUQr+Pu9efh95V2Vg6JbccurqCKsOF2ksqE+1AsZiLYFqIL +Qvj7OTbHwvKmNMBfWmCNOew/ggNeYXrXK5X4q9qQuHgFNrwJKNaSc4qft/0JJ0yF +wBctVCPMUvkdYeCCAvSTAhek9bpOiYJgrIl6Fa3UcwEJAhCQ0BoXGut4xmSZnufk +LZNiq7jAIbyXKcGjfUYJkv4ryEYfk+9fMM6HHXnz5wHKLb5xQMQCioJxQuZIY8ku +p2ioOSIHLnVQg9Q9KKdt4RNpvV59Ca+PDBUXGH8167Fp+oKkix7etYsMEamXnlPg +Hto= +=/vwC +-----END PGP MESSAGE----- + +Created with key: + +sec ed25519 2024-04-19 [SC] [expires: 2027-04-19] + 652B01FF34D43EA62C5DC897E47CC8B150A7A02E + Keygrip = DC60E0AE48E0F14E8FD7C9C36E18C6651E99BA93 +uid [ultimate] pqc-sample-1 +ssb ky768_cv25519 2024-04-19 [E] + CF06288CAAAA850A8B5B2927C8C14C7F0A8906AAEA320DE12A0A15F8E8746216 + Keygrip = 2F4CD0990D56D41A74456668469E3139A7960CD4,8B2E1355C97C34E0AC1CBC9DFDF2526BFE8990A7 + +Encryption with --debug=crypto diagnostics: + +DEK is: 85ae7493cfbafdd7282332dbf539ae7c54257c86de776fa29466378e92a110b2 +encode_session_key: encoding 32 byte DEK +encode_session_key: [32] 85 ae 74 ... a1 10 b2 +ECC curve: 1.3.101.110 +ECC pubkey: 6438411b2e3ea2ea48b681860c2ca537978c69072cbd04a40069e122660f6f37 +ecc_mul_point info: Montgomery/Standard +ecc_mul_point name: Curve25519 +ecc_mul_point p:+7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed +ecc_mul_point a:+01db41 +ecc_mul_point b:+01 +ecc_mul_point g.X:+09 +ecc_mul_point g.Y:+5f51e65e475f794b1fe122d388b72eb36dc2b28192839e4dd6163a5d81312c14 +ecc_mul_point g.Z:+01 +ecc_mul_point n:+1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed +ecc_mul_point h:+08 +ecc_mul_point info: Montgomery/Standard +ecc_mul_point name: Curve25519 +ecc_mul_point p:+7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed +ecc_mul_point a:+01db41 +ecc_mul_point b:+01 +ecc_mul_point g.X:+09 +ecc_mul_point g.Y:+5f51e65e475f794b1fe122d388b72eb36dc2b28192839e4dd6163a5d81312c14 +ecc_mul_point g.Z:+01 +ecc_mul_point n:+1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed +ecc_mul_point h:+08 +ECC ephem: d29449e958f90b45e5829c0b775f0e2e030c409f67c3af000367ffb42ad90557 +ECC ecdh: 2444b6e1183eae269c6d4d9f28cd6de1cfedf6bed90ce6dd7ea732d9503cb32b +ECC shared: 6648e8f006898d6407cc253f6a6c47b638f5ff00c5994580b6272611a8d9ad9e +Kyber pubkey: 0de94f420165b79701fb24a7669190cf2840ed7b96e4b088d45a9db4512117e3 … +Kyber ephem: 747bf549fc4e7b0680580a7bf5cf2f7ac4354e818e78cff697c2d785b081ebb7 … +Kyber shared: 0495e20570cd29d82a4933b8a133c09c39ec2a4e67aa6119cf7eccf2bf74ed40 +KEK: 4aee18ac1e35f67b8e3f5109695831fa77b426d85ed11b74390faed49f65da9e +seskey: 85ae7493cfbafdd7282332dbf539ae7c54257c86de776fa29466378e92a110b2 +enc_seskey: 28d692738a9fb7fd09274c85c0172d5423cc52f91d61e08202f4930217a4f5ba \ + 4e898260ac897a15ad +Kyber/AES256.OCB encrypted for: "CF06288CAAAA850A pqc-sample-1" diff --git a/tests/openpgp/samplemsgs/pqc-sample-2.enc.asc b/tests/openpgp/samplemsgs/pqc-sample-2.enc.asc new file mode 100644 index 000000000..c4233ab45 --- /dev/null +++ b/tests/openpgp/samplemsgs/pqc-sample-2.enc.asc @@ -0,0 +1,102 @@ +-----BEGIN PGP MESSAGE----- + +hQaSAy0PWcr9EtvZHQG9H3dPoDLcLQQVANcEAM6incJG2J35/unGxZiZbvEcAAXz +W31sr7tX24uIsc1x5YGx8cg4y1AHv1EAAAYgvys33VElGIEJLH3p7mfmneCLh/j2 +/KgS2tjUAAUXT1XODNVxfrUHS0b+vPU49bkhH3+qXv28HW/RCtFqI3jIlOxRX3s7 +vROEjDU63STly9zRMKs5hF/dOKQeXb93A4efSV18osEZsgatdNizoGaUUQs+KU1S +gKpfLJYSfAyTRkveDZrYVY4yW572h/whaYRCYhV/YEnGEBsRKPBj/MqJ0+VVxp39 +jmQlBnRAazZornih1yIuEyoFUGiqVjGvZOF1o1EUHT8gOlSOIGpbvT06G7MJP2yC +t9gO8VTSz2G/uhyL8atc5v37OOSDGI+4MFw4Fejy+taZIIqIUEAED+MWvNnqv9N1 +DtLk3FVgf0PvxLHFx2w/ERjJr80KZ2HtLSgmpC2Gu5qOHgKrPN+a/xb1Gw53TYfJ +9lmj1uNmpArvCRPnuT5g5Xa6mT6mVCd6XokYkJSwwYVyDcVxGIUlfey7vUXdH0Zg +OAb0lFi6phgclktzWbRMAV+oUwASQ11I3Pk5JLEXoFJS6yKHPcLIbEasQ5uaps8i +ZEyuO/vw8lCVdt8MVwwAjR5VilBnR9zZZRP8XkOAHTXk3XQpXhLvJVCwM5371c/o +XOEXR+k4kM1sd5fwahiH/tKIiSxhrgwBbgAlgCGNW1Oc/5uvwyZT/vv4sAi850wY ++Hg0dNSeIB1X8qo3sbj1wQxe3bF5FkW7y4OZZsyp2n57wra1Le5394DI+OxyOx4b +MggevEDSkdntIfQXlxfB4xKJWqB84vtChFrrGIKXN3W5hnwAoOTl318VtGz7Xauk +byPOj4MB+Ki2Q6K3XPZQVVWetiL5vaFzSeeC4Ek8TxZSQZ4EVgRxc/tNqgqoGepI +xb0dtMZv8bgA6I47pFutFItkC9R/d392vDmR4D7Ln9cixhphxoiT/PhSwQlbX2bx +UYybfi0YVw6gdEzOeVI0GQ/Z1gXD18JFHmMfBEsEI5fh0iNlVzzd12eIagl5uTo1 +lJ+EG7Szqwc5tSRdNzhZcFciGmlkfaOVRi3UdWXoNGd4H3X/8qyz+J3z9ErUXTu0 +yqCNP1rIGWZ4Fz3diMbT3uuruwQl5vy3hidKPAp1U1KHjrinQ7gHi9wOTOkyJ5u7 +KGpH+H37gIiejwNdHrQiyt30awaQ3nO8z42NVg74YJ+jZWw4iGzn8rZBHOmvqIMz +jrZN3SmXM9wSctKdDocMgRqwkQUe3fiEW9tZiR8tBK8EgHk7pyYNwbyKQY2qMmIP +OJUMu/5nSSQn9ik2LuIhgMi08pgQ8J9JejnqVl1qNheT59uTtHglvDCiiu+DYvtr +GZMn7UrG3XuTdN5TD+tukGLZ9bxsLTUq4f3QfqVQADz5AsIJeoNti2tH2AErGv0g ++DeDGrCnoHVZQTYoJ/e7OYCCLKaUtsFTiVVBMkwlSV1efQpt0FcYy0DwkdiKxHHf +CIiB4EAeBsN3l+EiWrwkyAD5FN+XR2rycEAEjL8fxoTQhQ+cnL72n92ukDCwXXT5 +36fnyXPuGEwaEES8Q70rXBfvmYHtysTAY+rDL7BRpZ1wMokrHe2N6MLnf5V/AAbF +oCqxJaexmycHLCJsYTDnyvDg9x+f4k8RgSMpEqFytf2ToSaemwJsfaU9SDO2dgWD +RROUaM4PzCzDXst/UgIbCvs30XWGuhAM2EGygciW5n7ZuM/wmcKlmJ4gs7Koi2mJ +3v3ZO5xN1yx/RVkR1EQTK50Q4u7Kcvf1hvghHZfqIM+jmzpOIG2b8Bos4kzPWxYL +aGdWnbgdxPlA6p9+Vmg30ykrjFKfuERg3RPPngB5a3MlNExQrOUQll+y9WVKRrzh +ZRay0PTba7moG2SOeS5tKyagItWkT85EMGcKNWSTFbQueps9kSXpEWdBKb3aueAi +5jjR9ITM1iGbo2JITTcNCIDG5sCOAQKNT+GjjP540bQge51KmeZE1smF8tSVQG/2 +kbiQrikcOGmws4aD2xbTkf/NoiW45OXdHjd+0zNOo8vKyUVywObOz3m8mq0LOObK +NlK7BGIEMNWB95OMCQkT8o9uuGDE+N4L8mUenHTn0rxQ0du6GYUhqgVCk9yfbDKF +WxtiMb3sAi9F5VUJKAk8KnUkX7JOFuKuS84i2lh3dxNqTNeU9mT7fTXUXnrmzTxa +gx74k3fUrQEJAhANgfbbcB8gLTkXAdHgU1FK0gjUeKaOVsKVIVonkO2lZL6fn0rz +WQecKUE5mDP4oj9B85RHsxxMCotW+GhUakgMh/Lprwr6uRDPi4vaczKZU83Os69f +YkXcdiJL1B5R6oEArn/p0Ig+vuiBIwQyzXK3lP6oCX8deMp8e03EuI4s1UD5iPsB +xSK9Foaw8uxlKMlgfdgD2eX/UGpVnvbFv/oEdHHACy5hiL56 +=fcr5 +-----END PGP MESSAGE----- + +Created with key: + +sec ed25519 2024-04-19 [SC] [expires: 2027-04-19] + 6BF41D6AC221F5223C2DEEE320E629089768AD93 + Keygrip = F5DB116462B7BD2FA83A4453C4DFA2AE8604FB59 +uid [ultimate] pqc-sample-2 +ssb ky1024_cv448 2024-04-19 [E] + 2D0F59CAFD12DBD9DF9EFD602D7E8F8C2121A5D1841174346D6C8FE8F9AA7683 + Keygrip = 8F9ABF3E5BBFC50D168DD524EB8F7263E7B33859,A1598F57316F7FEC3F946895E35A7D2EAE8D3A13 + +Encryption with --debug=crypto diagnostics: + +DEK is: 244ab936bd8c02d89486abe92a5c145fb502099445987ed21ca78fa42e7f45ea +encode_session_key: encoding 32 byte DEK +encode_session_key: [32] 24 4a b9 ... 7f 45 ea +ECC curve: 1.3.101.111 +ECC pubkey: 5e42bc08be62f4d740196fc1888d18f1d1bd6d21dac63c7265be2897f1c2ce5e \ + 9e2140aa3b65620fe0ea2fb443952821ad05967a6d32d849 +ecc_mul_point info: Montgomery/SafeCurve +ecc_mul_point name: X448 +ecc_mul_point p:+fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff \ + ffffffffffffffffffffffffffffffffffffffffffffffff +ecc_mul_point a:+98a9 +ecc_mul_point b:+01 +ecc_mul_point g.X:+05 +ecc_mul_point g.Y:+7d235d1295f5b1f66c98ab6e58326fcecbae5d34f55545d060f75dc28df3f6ed \ + b8027e2346430d211312c4b150677af76fd7223d457b5b1a +ecc_mul_point g.Z:+01 +ecc_mul_point n:+3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9 \ + c44edb49aed63690216cc2728dc58f552378c292ab5844f3 +ecc_mul_point h:+04 +ecc_mul_point info: Montgomery/SafeCurve +ecc_mul_point name: X448 +ecc_mul_point p:+fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff \ + ffffffffffffffffffffffffffffffffffffffffffffffff +ecc_mul_point a:+98a9 +ecc_mul_point b:+01 +ecc_mul_point g.X:+05 +ecc_mul_point g.Y:+7d235d1295f5b1f66c98ab6e58326fcecbae5d34f55545d060f75dc28df3f6ed \ + b8027e2346430d211312c4b150677af76fd7223d457b5b1a +ecc_mul_point g.Z:+01 +ecc_mul_point n:+3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9 \ + c44edb49aed63690216cc2728dc58f552378c292ab5844f3 +ecc_mul_point h:+04 +ECC ephem: 1f774fa032dc2d041500d70400cea29dc246d89df9fee9c6c598996ef11c0005 \ + f35b7d6cafbb57db8b88b1cd71e581b1f1c838cb5007bf51 +ECC ecdh: b8993bc015a983286618ff6ce866ef846d4cca616934afd8f1ffef9d25046620 \ + 81bb9d8316a3ae5199720f27dcf4ac72fa9e1d71db9b1745 +ECC shared: 634b233b4674df04158bf3b3eb287b50e10819aabaaaa9750e1c603c40b244e9 \ + a0dd353e8098adbacd277f9d79bf2bdfb4ba4401d71b871272d20c99ee3b02c1 +Kyber pubkey: 76e799415b04c5b048d8671c59439a7134263c18127971232947aa66d66df134 … +Kyber ephem: bf2b37dd51251881092c7de9ee67e69de08b87f8f6fca812dad8d40005174f55 … +Kyber shared: 8fd48c5489254e89bcea602904323a370050eee86240e171181e5d1602288aac +KEK: 8595d1368fa33a7ba26810adfc1f66a688768e07c6610766d80d0dcffe1ff3c1 +seskey: 244ab936bd8c02d89486abe92a5c145fb502099445987ed21ca78fa42e7f45ea +enc_seskey: 28093c2a75245fb24e16e2ae4bce22da587777136a4cd794f664fb7d35d45e7a \ + e6cd3c5a831ef89377 +Kyber/AES256.OCB encrypted for: "2D0F59CAFD12DBD9 pqc-sample-2" From 54741685ced22bfa0cbd6db5c41e50ef2148d1e3 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Apr 2024 16:21:49 +0200 Subject: [PATCH 456/869] Remove the deprecated gcry_set_log_handler. * common/miscellaneous.c (my_gcry_logger): Remove. (setup_libgcrypt_logging): Do not call the deprecated gcry_set_log_handler. * kbx/kbxutil.c (my_gcry_logger): Remove. * tools/no-libgcrypt.c (gcry_set_log_handler): Remove stub. --- common/miscellaneous.c | 22 ---------------------- kbx/kbxutil.c | 25 ------------------------- tools/no-libgcrypt.c | 8 -------- 3 files changed, 55 deletions(-) diff --git a/common/miscellaneous.c b/common/miscellaneous.c index 28d3e7a2e..a41acc240 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -36,27 +36,6 @@ #include "iobuf.h" #include "i18n.h" -/* Used by libgcrypt for logging. */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - (void)dummy; - - /* Map the log levels. */ - switch (level) - { - case GCRY_LOG_CONT: level = GPGRT_LOGLVL_CONT; break; - case GCRY_LOG_INFO: level = GPGRT_LOGLVL_INFO; break; - case GCRY_LOG_WARN: level = GPGRT_LOGLVL_WARN; break; - case GCRY_LOG_ERROR:level = GPGRT_LOGLVL_ERROR; break; - case GCRY_LOG_FATAL:level = GPGRT_LOGLVL_FATAL; break; - case GCRY_LOG_BUG: level = GPGRT_LOGLVL_BUG; break; - case GCRY_LOG_DEBUG:level = GPGRT_LOGLVL_DEBUG; break; - default: level = GPGRT_LOGLVL_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - /* This function is called by libgcrypt on a fatal error. */ static void @@ -100,7 +79,6 @@ my_gcry_outofcore_handler (void *opaque, size_t req_n, unsigned int flags) void setup_libgcrypt_logging (void) { - gcry_set_log_handler (my_gcry_logger, NULL); gcry_set_fatalerror_handler (my_gcry_fatalerror_handler, NULL); gcry_set_outofcore_handler (my_gcry_outofcore_handler, NULL); } diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index f5bc8bd77..5a0543128 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -132,29 +132,6 @@ my_strusage( int level ) } -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - (void)dummy; - - /* Map the log levels. */ - switch (level) - { - case GCRY_LOG_CONT: level = GPGRT_LOGLVL_CONT; break; - case GCRY_LOG_INFO: level = GPGRT_LOGLVL_INFO; break; - case GCRY_LOG_WARN: level = GPGRT_LOGLVL_WARN; break; - case GCRY_LOG_ERROR:level = GPGRT_LOGLVL_ERROR; break; - case GCRY_LOG_FATAL:level = GPGRT_LOGLVL_FATAL; break; - case GCRY_LOG_BUG: level = GPGRT_LOGLVL_BUG; break; - case GCRY_LOG_DEBUG:level = GPGRT_LOGLVL_DEBUG; break; - default: level = GPGRT_LOGLVL_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - - /* static void */ /* wrong_args( const char *text ) */ /* { */ @@ -481,8 +458,6 @@ main (int argc, char **argv) i18n_init (); init_common_subsystems (&argc, &argv); - gcry_set_log_handler (my_gcry_logger, NULL); - /*create_dotlock(NULL); register locking cleanup */ /* We need to use the gcry malloc function because jnlib uses them. */ diff --git a/tools/no-libgcrypt.c b/tools/no-libgcrypt.c index 3b577567a..cbf934013 100644 --- a/tools/no-libgcrypt.c +++ b/tools/no-libgcrypt.c @@ -136,14 +136,6 @@ gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque) (void)opaque; } -void -gcry_set_log_handler (gcry_handler_log_t f, void *opaque) -{ - (void)f; - (void)opaque; -} - - void gcry_create_nonce (void *buffer, size_t length) { From 32ec480024b306508f77b1ebc720e2587df7b6c3 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Apr 2024 16:25:05 +0200 Subject: [PATCH 457/869] gpg: Support encryption with kyber_bp256 and kyber_bp384 * common/openpgp-oid.c (oidtable): Support KEM for bp256 and bp384. * g10/pkglue.c (do_encrypt_kem): Ditto. -- GnuPG-bug-id: 6815 Note, this needs the very latest Libgcrypt to work properly --- common/openpgp-oid.c | 6 ++++-- g10/pkglue.c | 32 ++++++++++++++++++++++++++++++++ g10/pubkey-enc.c | 3 +++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index d54aff3a9..a374904cf 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -65,8 +65,10 @@ static struct { { "NIST P-384", "1.3.132.0.34", 384, "nistp384" }, { "NIST P-521", "1.3.132.0.35", 521, "nistp521" }, - { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", 256, NULL, "bp256" }, - { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", 384, NULL, "bp384" }, + { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", 256, NULL, "bp256", + 0, GCRY_KEM_RAW_BP256 }, + { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", 384, NULL, "bp384", + 0, GCRY_KEM_RAW_BP384 }, { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 512, NULL, "bp512" }, { "secp256k1", "1.3.132.0.10", 256 }, diff --git a/g10/pkglue.c b/g10/pkglue.c index fb39d5ba8..170a1c54b 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -522,6 +522,38 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, ecc_ss_len = 64; ecc_hash_algo = GCRY_MD_SHA3_512; } + else if (ecc_algo == GCRY_KEM_RAW_BP256) + { + ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits); + ecc_pubkey_len = (nbits+7)/8; + if (ecc_pubkey_len != 65) + { + if (opt.verbose) + log_info ("%s: ECC public key length invalid (%zu)\n", + __func__, ecc_pubkey_len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + ecc_ct_len = ecc_ecdh_len = 65; + ecc_ss_len = 32; + ecc_hash_algo = GCRY_MD_SHA3_256; + } + else if (ecc_algo == GCRY_KEM_RAW_BP384) + { + ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits); + ecc_pubkey_len = (nbits+7)/8; + if (ecc_pubkey_len != 97) + { + if (opt.verbose) + log_info ("%s: ECC public key length invalid (%zu)\n", + __func__, ecc_pubkey_len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + ecc_ct_len = ecc_ecdh_len = 97; + ecc_ss_len = 64; + ecc_hash_algo = GCRY_MD_SHA3_512; + } else { if (opt.verbose) diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 470525a95..563077803 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -457,6 +457,9 @@ get_it (ctrl_t ctrl, log_info (_("WARNING: cipher algorithm %s not found in recipient" " preferences\n"), openpgp_cipher_algo_name (dek->algo)); + /* if (!err && 25519 && openpgp_oidbuf_is_ed25519 (curve, len)) */ + /* log_info ("Note: legacy OID was used for cv25519\n"); */ + if (!err) { kbnode_t k; From dd650b2c7b7b1612afe494123bc817a2619bb124 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Apr 2024 17:40:27 +0200 Subject: [PATCH 458/869] gpg: Support Kyber with Brainpool512r1. * common/openpgp-oid.c (oidtable): Add GCRY_KEM_RAW_BP512. * agent/pkdecrypt.c (ecc_table): Support bp512 * g10/pkglue.c (do_encrypt_kem): Ditto. * tests/openpgp/samplekeys: Add sample keys for kyber_bp256, bp384, and bp512. * tests/openpgp/privkeys: Add corresponding private keys. * tests/openpgp/samplemsgs: Add sample messages for those keys. -- GnuPG-bug-id: 6815 --- agent/pkdecrypt.c | 6 + common/openpgp-oid.c | 3 +- g10/pkglue.c | 16 ++ tests/openpgp/Makefile.am | 21 ++- ...C87B74004E9839F3D56992B0A9943BF90B56F7.key | 7 + ...3906BEA5A40F25C9D6EBBCEF62D0784E7235A5.key | 8 + ...C551A7895031EE4543A1C789E16E6A6C229CFC.key | 137 ++++++++++++++++++ ...2F599E35E6E0BE68E6FDF25D887229D42780F7.key | 7 + ...31A4A632A49C4E8B1C8CBA53976ADFF714510F.key | 137 ++++++++++++++++++ ...ABFD89944870D04039D40C218EE127254AEEE9.key | 8 + ...7B85D88DB8B2B5A62A9958C8F2878F49605D09.key | 5 + ...4E9B75C3541D95C45E430DAC9645E9FB62C668.key | 5 + ...D718DCE3D2F33A20BFC8BA617844DEF3FFAF3A.key | 104 +++++++++++++ tests/openpgp/samplekeys/README | 3 + tests/openpgp/samplekeys/pqc-sample-3.key.asc | 48 ++++++ tests/openpgp/samplekeys/pqc-sample-4.key.asc | 58 ++++++++ tests/openpgp/samplekeys/pqc-sample-5.key.asc | 61 ++++++++ tests/openpgp/samplemsgs/pqc-sample-3.enc.asc | 32 ++++ tests/openpgp/samplemsgs/pqc-sample-4.enc.asc | 43 ++++++ tests/openpgp/samplemsgs/pqc-sample-5.enc.asc | 45 ++++++ 20 files changed, 750 insertions(+), 4 deletions(-) create mode 100644 tests/openpgp/privkeys/19C87B74004E9839F3D56992B0A9943BF90B56F7.key create mode 100644 tests/openpgp/privkeys/513906BEA5A40F25C9D6EBBCEF62D0784E7235A5.key create mode 100644 tests/openpgp/privkeys/6EC551A7895031EE4543A1C789E16E6A6C229CFC.key create mode 100644 tests/openpgp/privkeys/702F599E35E6E0BE68E6FDF25D887229D42780F7.key create mode 100644 tests/openpgp/privkeys/7C31A4A632A49C4E8B1C8CBA53976ADFF714510F.key create mode 100644 tests/openpgp/privkeys/A1ABFD89944870D04039D40C218EE127254AEEE9.key create mode 100644 tests/openpgp/privkeys/A87B85D88DB8B2B5A62A9958C8F2878F49605D09.key create mode 100644 tests/openpgp/privkeys/D54E9B75C3541D95C45E430DAC9645E9FB62C668.key create mode 100644 tests/openpgp/privkeys/EAD718DCE3D2F33A20BFC8BA617844DEF3FFAF3A.key create mode 100644 tests/openpgp/samplekeys/pqc-sample-3.key.asc create mode 100644 tests/openpgp/samplekeys/pqc-sample-4.key.asc create mode 100644 tests/openpgp/samplekeys/pqc-sample-5.key.asc create mode 100644 tests/openpgp/samplemsgs/pqc-sample-3.enc.asc create mode 100644 tests/openpgp/samplemsgs/pqc-sample-4.enc.asc create mode 100644 tests/openpgp/samplemsgs/pqc-sample-5.enc.asc diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 10bd92152..5509b1169 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -70,6 +70,12 @@ static const struct ecc_params ecc_table[] = GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP384, 0 }, + { + "brainpoolP512r1", + 129, 64, 129, 64, + GCRY_MD_SHA3_512, GCRY_KEM_RAW_BP512, + 0 + }, { NULL, 0, 0, 0, 0, 0, 0, 0 } }; diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index a374904cf..92f0dfbcd 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -69,7 +69,8 @@ static struct { 0, GCRY_KEM_RAW_BP256 }, { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", 384, NULL, "bp384", 0, GCRY_KEM_RAW_BP384 }, - { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 512, NULL, "bp512" }, + { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 512, NULL, "bp512", + 0, GCRY_KEM_RAW_BP512 }, { "secp256k1", "1.3.132.0.10", 256 }, diff --git a/g10/pkglue.c b/g10/pkglue.c index 170a1c54b..f4efa8fc5 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -554,6 +554,22 @@ do_encrypt_kem (PKT_public_key *pk, gcry_mpi_t data, int seskey_algo, ecc_ss_len = 64; ecc_hash_algo = GCRY_MD_SHA3_512; } + else if (ecc_algo == GCRY_KEM_RAW_BP512) + { + ecc_pubkey = gcry_mpi_get_opaque (pk->pkey[1], &nbits); + ecc_pubkey_len = (nbits+7)/8; + if (ecc_pubkey_len != 129) + { + if (opt.verbose) + log_info ("%s: ECC public key length invalid (%zu)\n", + __func__, ecc_pubkey_len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + ecc_ct_len = ecc_ecdh_len = 129; + ecc_ss_len = 64; + ecc_hash_algo = GCRY_MD_SHA3_512; + } else { if (opt.verbose) diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index e32ff3d17..d1f04e99b 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -218,7 +218,16 @@ priv_keys = privkeys/50B2D4FA4122C212611048BC5FC31BD44393626E.asc \ privkeys/8B2E1355C97C34E0AC1CBC9DFDF2526BFE8990A7.key \ privkeys/F5DB116462B7BD2FA83A4453C4DFA2AE8604FB59.key \ privkeys/8F9ABF3E5BBFC50D168DD524EB8F7263E7B33859.key \ - privkeys/A1598F57316F7FEC3F946895E35A7D2EAE8D3A13.key + privkeys/A1598F57316F7FEC3F946895E35A7D2EAE8D3A13.key \ + privkeys/19C87B74004E9839F3D56992B0A9943BF90B56F7.key \ + privkeys/513906BEA5A40F25C9D6EBBCEF62D0784E7235A5.key \ + privkeys/6EC551A7895031EE4543A1C789E16E6A6C229CFC.key \ + privkeys/702F599E35E6E0BE68E6FDF25D887229D42780F7.key \ + privkeys/7C31A4A632A49C4E8B1C8CBA53976ADFF714510F.key \ + privkeys/A1ABFD89944870D04039D40C218EE127254AEEE9.key \ + privkeys/A87B85D88DB8B2B5A62A9958C8F2878F49605D09.key \ + privkeys/D54E9B75C3541D95C45E430DAC9645E9FB62C668.key \ + privkeys/EAD718DCE3D2F33A20BFC8BA617844DEF3FFAF3A.key sample_keys = samplekeys/README \ @@ -248,7 +257,10 @@ sample_keys = samplekeys/README \ samplekeys/authenticate-only.pub.asc \ samplekeys/authenticate-only.sec.asc \ samplekeys/pqc-sample-1.key.asc \ - samplekeys/pqc-sample-2.key.asc + samplekeys/pqc-sample-2.key.asc \ + samplekeys/pqc-sample-3.key.asc \ + samplekeys/pqc-sample-4.key.asc \ + samplekeys/pqc-sample-5.key.asc sample_msgs = samplemsgs/clearsig-1-key-1.asc \ samplemsgs/clearsig-2-keys-1.asc \ @@ -283,7 +295,10 @@ sample_msgs = samplemsgs/clearsig-1-key-1.asc \ samplemsgs/signed-2-keys-1.asc \ samplemsgs/signed-2-keys-2.asc \ samplemsgs/pqc-sample-1.enc.asc \ - samplemsgs/pqc-sample-2.enc.asc + samplemsgs/pqc-sample-2.enc.asc \ + samplemsgs/pqc-sample-3.enc.asc \ + samplemsgs/pqc-sample-4.enc.asc \ + samplemsgs/pqc-sample-5.enc.asc EXTRA_DIST = defs.scm trust-pgp/common.scm $(XTESTS) $(TEST_FILES) \ mkdemodirs signdemokey $(priv_keys) $(sample_keys) \ diff --git a/tests/openpgp/privkeys/19C87B74004E9839F3D56992B0A9943BF90B56F7.key b/tests/openpgp/privkeys/19C87B74004E9839F3D56992B0A9943BF90B56F7.key new file mode 100644 index 000000000..d0c602d3f --- /dev/null +++ b/tests/openpgp/privkeys/19C87B74004E9839F3D56992B0A9943BF90B56F7.key @@ -0,0 +1,7 @@ +Created: 20240423T121650 +Key: (private-key (ecc (curve brainpoolP384r1)(q + #0472FB0D5A0A01E55C29E9FB8C5C425BDF37150DAFA3C556C786E2FEF9E011919E68 + 3DBC7731D1281FDB9780C4B7FD7785198516BE2033D06448BA7EA39C2BCB7128BC1E0B + 3F81F2E734434E6FE96B29E19C57B423C5009134010CD87FADCA63A1#)(d + #474FD16712E9A8EC87A6F94E553E369358985475B453E95CFFD2123E4E97679720AA + 269CD6002DC688C9F3B9B8C456F1#))) diff --git a/tests/openpgp/privkeys/513906BEA5A40F25C9D6EBBCEF62D0784E7235A5.key b/tests/openpgp/privkeys/513906BEA5A40F25C9D6EBBCEF62D0784E7235A5.key new file mode 100644 index 000000000..c902ecf25 --- /dev/null +++ b/tests/openpgp/privkeys/513906BEA5A40F25C9D6EBBCEF62D0784E7235A5.key @@ -0,0 +1,8 @@ +Created: 20240423T151658 +Key: (private-key (ecc (curve brainpoolP512r1)(q + #046E26896EAC8D3D7F31F0B57439FFDBC0078841CEF7A9A98AB15F489FEE34E9D15E + 2050EAFCA0CD4C7021E5E018F601EEC7EDDE1AACE959EA13F84143861489DD54ADAA4F + F86E5FF75E3CC2EA6453716075DD908B9647B45257A64AE88DD390D7325B9E30698027 + 16B3743AFE7A7E44495AF625C3E009C581C63E341A16A23D07#)(d + #1A1364149C7AB54D76D9345424EF755139031E85B5B7DEB0D221855D0189A579614B + BCB6D01D9E02627F5C187338D7A176A830DF55422FE20D3BFF7812255C1A#))) diff --git a/tests/openpgp/privkeys/6EC551A7895031EE4543A1C789E16E6A6C229CFC.key b/tests/openpgp/privkeys/6EC551A7895031EE4543A1C789E16E6A6C229CFC.key new file mode 100644 index 000000000..e9df95c0a --- /dev/null +++ b/tests/openpgp/privkeys/6EC551A7895031EE4543A1C789E16E6A6C229CFC.key @@ -0,0 +1,137 @@ +Created: 20240423T151658 +Key: (private-key (kyber1024 (p #BE7768B33800B583978414965EC439D29A4180 + 655B0A58BA40CB9C29D10088A07D66B47AE6124B986156A9347878FBCFC0351049D2C1 + 8835CEE72BADE28B7AC8BA7FF8345AD885B1E730409939C5B3A1A5867AB7912538F234 + 59AA335204ECC5E94A9B651772A9AC5C60A5137AA74719996479D7A424839172398078 + 57493825896C628DA1726418D843E4946F9838A2E2DA5B93C6805995CD7D4B26EB79BC + BD645E52B31703986686CB2AB26A22029879BD57212928096F0954A65654FAD6651FEB + 11039C6E0F03172025303480AE6F5A0ED786A17E3779ABD775B15407B6560C97C42CF8 + 6A63D7AA1032767D20D97EAD7A3EFCD346D00B4DFD147FAE9C7BCC64224837B6C62770 + 76E25BE756C201A58445779AE98679C753C2BBA69425D343A5156EAED17AACF0B939C4 + 9B3FE83AA80C5E4399BE81C13F0A2CB4E6B08E588A13B8944AC9F74D79541FAB1691BE + 88156F920FA836C4D41AC4965009FAA174DA36B5521C79F4313B498525311369261B64 + 48FC7AEE6B9D44455BF6347C35F2B99F95254C6027759B99CA16659006BAD1F7C0B20C + BDBFF66A8F454E24863B175A0B614830AC8ACB1AFB93F1D3C54F7216DAA05AE210B57B + 503E4657B6870A8CD448644B7A5B68F565E9F51C9F12890AC8315ED52015F6BBED89C6 + 924BC756EB752FB3502BC50CAFA073E1B6AE3DD29E0C9269F8B505CA0654702114F03B + AE81C945B13631EA6C28B244BCDFB159B55B1EACAC30AF7872BD3C8F5BEA0EE9056DB2 + E6C87C9B204AB21018696217D648EFCBBB4C078C16751B03702BAF447FFB741FDB2455 + AF5A9BCA6A3340C5B8F6B82748723024B20E6F5A3D56278DBC975D4EA70D9399A6E355 + 533920A3C5E858AD5180BD4434F3E42B971908AA591ABBF3C1EBF257627CB2BF740DC1 + B88C7551A5B8462F6CE3B58C65A390C07C01A15C2BC624AB007924D9B76DD1A50603C1 + 92278A24CC86CFAA952E66ACFE99A800D56C473A7877955FC7D83C1DD548A57527B259 + 0B56B6CB3E8525F06986725379C4130F8FE15524D569346AAF451538DC663149F1946D + 5509BE3BB6026031F87AC4B21B80D66981F8527CDAF0AD4BFC2A3B3265BDAC4E65190B + 5D777275896EA238606CA7B2173C1C4DE01058965128BC866B8CC2991045AE47324243 + CBB0808E2F851FC9563779AC269664B01AECBEF45465FEB9584CC47F3B031794594BF5 + 7497446B0A856755429A7389A21AB3573C2D8A036238486451013D647D288979200A83 + 72C6039FA23E35877008408C7C815E55035A5BA9165BBB3BA56A96253B526DDC37FCC2 + 9F16F18E7D6676A393B867849C85927CAF996A9FE388FF880D5615AC64B7B4251803D7 + 9599D2232D560C85F562643E9B9F33F8139D0B61ABE98F76043E5166145A045B83E574 + AAB35D9D119A3EB3107FB3388EF483B056726B3036C29663018C929FD972D444C54373 + 16D749AF0D12556F159FC02584C6B8456BF56DC2128DCA61B794E7AAFB61969354B5A6 + DA82EB545CFA242CE997A5168AA43926131165B534FBBE1F15A4D4432FF5BB8446A575 + E528480B7C3FA0328C8134C0BF778792C05902EB32476326AE979CCF0C80C39C4B7332 + 9FC4EA365164A848D529BCB43985D35B3AE30B02AC057E1910BDB616F50A79F22441B3 + 51C77C8A17AB4052F44930B991AF7C751209253C4D27C8C5166C3285A1B1D39981B85E + CE5CC7AF11B4B8B38170963766E6130A66ABD736478067C0A86470C542216AE1593591 + 62F72C34241601E4F54087D64A8752C38FD85CC09C0C7F38CE3A0320E5E16B507302D7 + 830EA18793774A3D7BAA807971AD17332D8862C0FA757D98782CE927577A32B45BF18E + EE77B393F410620C03093620470BBC93313489F11C96871C42DA296909ABF16A885950 + A2CF896CD18A61D54B3C529C96355AC2D3C69324C3AE634C8718C3CBFA734C40E78F91 + 53A1286B379E0B7636141DD20B43A26B6BB2E03A56F008F0868CE2B940CF108FCE7954 + C0A1B933CC15FE156E2C4C4E4EDCBBA1E87108E3CFF24865548A838E7619315B25C265 + 3465158CAE4683AA03696870C397359B118CB37AA853D46CC5B05ACFDBC010C8984284 + 07009340A4793A05718B0E12E95FA8685A213B8559B44021B8C3A458AF81C2476775AB + F0015DBFF820427CA306265DE9AE0F4AE474DF627DCD167AEA9FB7A6EB3F021BA4A78A + E111275F13AC923E23#)(s #2EB39309148C404770B9EC5188D13FEDD24E3DAA78FCC3 + 5AAA6840B1458E30511A973C389FF3B4F8073ACF9780AC09A648822E460C6399C125B5 + 191DCF16C92C350FFCF25A94E22E4E80C9A25C18DFC884D9536D2E8469CAC88781726C + CE899E477BAFE3B25F3319A310E499AF030CC65867E207D0BCFA1C1EF711F2403B8293 + 7F83A0859051CDC9AA9B43B53197CB47B1F47BC6BB5A073A3D5B2182A312C747A50C5B + E67CB43315019CB0B6D73216943144A5228307A4D7FA3C88B0B3AA1B088CCC73A81AA3 + 0EF56D06D3A2139517215A843E093C1F61C1B1890FE5E9A0FC64986622BBFF7635F6F7 + 70C1325727300665B437544456C1211FC7D1753B724DB691CAE729BC89CA97B5C60363 + 710FF5A2502C54C429591824A62547D70FB17A8D177979473B254E12BA1A589B1039CC + 9AF061FF098AF5B09B89334DF3E54B6D524FB8B99F7C9A41F4731175D4904BA040A201 + 76BF153241FC5F38D63665629C75C97935F99DF7B7B415816705C00A47020DB2D8A6C7 + 945FD950206FB1CE970A973A285469FC6B2D495BCC50BACCCC9DD03A9D85C2B667BB64 + 887A37EB645DC5F4281ABA6FA5D2B73C0B97D9AC9220DB5A0ADABA6B438367E60E0412 + 453E6791C275A19F1B44D23A9C00E11610EABC332746F6FC09DDAAA402475E7528C57F + 8B79BE8B506F100E43AB3131C138225622DC597F0405B86A3CCABF2B45CBA028FE1221 + A9AB4368EA6D9129A80A26B2F8CB76438A15D0FC8BD0B26BD6D5BDAB75BA25F636A889 + 95DCE2656A21C66C3CCBE2CACF38C66F2D66BB55C81A66C1695BA5391BA327F44B6596 + 4A035A37C6C3BA7198F27E758C822EDAC40E50CBC86274E6EC6710B74178321FEAD3B7 + 20319A50D34EAC953424379CCCF9753E3C26D60B896A555C62D21F226899620995CCEA + 312F840D08294A6816789DC77B1D730151FA5084BB8CA3CBA402E834CA5C2069D6455B + 133864F64CCDAA7C98B7038AD6A1FCF24C81E6B20D2C7BA1B1B45B4A949D48AC51683F + A8C4938B4CBBA49C258318742BFAA172DC58C5E628BD9A10A9C54116705B6E9C80D936 + 2C62E26DC5A132F02B2A4B1A2376A74668ECA44D2080C414941C6A3836CA90C590CD3D + 2B74F2C33C82288B15B708F4178D7B1A01990308DC76C0C83794063B0D2F434EE86AAE + 9240163AB0AB49DC36F5AC925F05C38CD6722E70B09F8871F04066DF90A4EF06AB3776 + 161DD8817313653A0A58CCE69040EBB5D84B9B1DEB0892E8071B073965D68F4C191354 + 184E2D0100A272636560C305394185D01D0FE527A66CC1F4ECB34C208222FB505FB39F + 5B47A6CE87BA58C848EAD5ADC78B17CE6584A4336C3AF8C23C9BBE805ACA16AC53247A + 621D074A1AC79339B83661D7018E55A6091C58441606A862C29A79BCB7600041AC7CFF + 5C76961B48D4C47437E3119D2697B28502748036784A99F4D07F21FC16C6A1C5F44070 + C2F07F71FC74D91114C8E71053E18A59EB567C1445CBE3216CAB431FE59D42E627BB8C + 5C905C4FDA2B1C0A5B3B67567879660E044B5FA0666310939250020AAF31A6FA789B38 + 904121713F08A5760EAAC87EA58444D25FC40787A3600B55059FE081AA535BBF6DF25C + 1C4A27DBA8A243AC88A4D879BBAB260BFA62DF0557BF7B7466654DE5C69DDBB18C3E17 + B5EBD0AD91A80AEA71C2F5F076794C1B60323E7C5416F11179CAD8A6F48C943AAB6265 + 6A9AFAFA2F5CE8918935C21E169806463CE140B1CF6930B9A3AD4AFCA1B2607867B441 + 5EE696E3949D53AAA74A8692913AA900E5A32BD7C9482284F1133245A08EBA41C17C70 + 987FC106C3961B3A13C2E9966DC6F9B42CFBA39EBA7620CA6E42DC7F58759315F04703 + 262E334B45CDD90FDE270C679A67C91B8D80076E4F539678822AF993633EC54FE6486D + 53E51DE286C5887B66A6188BC7E88BFF4455C03160F3A2AF2BF9C7EED288D1F977EB69 + 72BA48742543325FB667DA80B5B6CB3C70B76C15940A93CB2ABAC76315F18E7A578370 + 6320299C33B8636E0354966E46585025462444300BFB94C36784904A1DF199C6B1AB62 + 410723D6365F50111CD7854384296D47A1BA7B241FD179443C5721D3655435069C0F6A + 4DD6E21C40F3CAA5502431601486DB3ADC329888D7ACB364B3902B6781B52712C70054 + 8C61F811184A00AEBE7768B33800B583978414965EC439D29A4180655B0A58BA40CB9C + 29D10088A07D66B47AE6124B986156A9347878FBCFC0351049D2C18835CEE72BADE28B + 7AC8BA7FF8345AD885B1E730409939C5B3A1A5867AB7912538F23459AA335204ECC5E9 + 4A9B651772A9AC5C60A5137AA74719996479D7A42483917239807857493825896C628D + A1726418D843E4946F9838A2E2DA5B93C6805995CD7D4B26EB79BCBD645E52B3170398 + 6686CB2AB26A22029879BD57212928096F0954A65654FAD6651FEB11039C6E0F031720 + 25303480AE6F5A0ED786A17E3779ABD775B15407B6560C97C42CF86A63D7AA1032767D + 20D97EAD7A3EFCD346D00B4DFD147FAE9C7BCC64224837B6C6277076E25BE756C201A5 + 8445779AE98679C753C2BBA69425D343A5156EAED17AACF0B939C49B3FE83AA80C5E43 + 99BE81C13F0A2CB4E6B08E588A13B8944AC9F74D79541FAB1691BE88156F920FA836C4 + D41AC4965009FAA174DA36B5521C79F4313B498525311369261B6448FC7AEE6B9D4445 + 5BF6347C35F2B99F95254C6027759B99CA16659006BAD1F7C0B20CBDBFF66A8F454E24 + 863B175A0B614830AC8ACB1AFB93F1D3C54F7216DAA05AE210B57B503E4657B6870A8C + D448644B7A5B68F565E9F51C9F12890AC8315ED52015F6BBED89C6924BC756EB752FB3 + 502BC50CAFA073E1B6AE3DD29E0C9269F8B505CA0654702114F03BAE81C945B13631EA + 6C28B244BCDFB159B55B1EACAC30AF7872BD3C8F5BEA0EE9056DB2E6C87C9B204AB210 + 18696217D648EFCBBB4C078C16751B03702BAF447FFB741FDB2455AF5A9BCA6A3340C5 + B8F6B82748723024B20E6F5A3D56278DBC975D4EA70D9399A6E355533920A3C5E858AD + 5180BD4434F3E42B971908AA591ABBF3C1EBF257627CB2BF740DC1B88C7551A5B8462F + 6CE3B58C65A390C07C01A15C2BC624AB007924D9B76DD1A50603C192278A24CC86CFAA + 952E66ACFE99A800D56C473A7877955FC7D83C1DD548A57527B2590B56B6CB3E8525F0 + 6986725379C4130F8FE15524D569346AAF451538DC663149F1946D5509BE3BB6026031 + F87AC4B21B80D66981F8527CDAF0AD4BFC2A3B3265BDAC4E65190B5D777275896EA238 + 606CA7B2173C1C4DE01058965128BC866B8CC2991045AE47324243CBB0808E2F851FC9 + 563779AC269664B01AECBEF45465FEB9584CC47F3B031794594BF57497446B0A856755 + 429A7389A21AB3573C2D8A036238486451013D647D288979200A8372C6039FA23E3587 + 7008408C7C815E55035A5BA9165BBB3BA56A96253B526DDC37FCC29F16F18E7D6676A3 + 93B867849C85927CAF996A9FE388FF880D5615AC64B7B4251803D79599D2232D560C85 + F562643E9B9F33F8139D0B61ABE98F76043E5166145A045B83E574AAB35D9D119A3EB3 + 107FB3388EF483B056726B3036C29663018C929FD972D444C5437316D749AF0D12556F + 159FC02584C6B8456BF56DC2128DCA61B794E7AAFB61969354B5A6DA82EB545CFA242C + E997A5168AA43926131165B534FBBE1F15A4D4432FF5BB8446A575E528480B7C3FA032 + 8C8134C0BF778792C05902EB32476326AE979CCF0C80C39C4B73329FC4EA365164A848 + D529BCB43985D35B3AE30B02AC057E1910BDB616F50A79F22441B351C77C8A17AB4052 + F44930B991AF7C751209253C4D27C8C5166C3285A1B1D39981B85ECE5CC7AF11B4B8B3 + 8170963766E6130A66ABD736478067C0A86470C542216AE159359162F72C34241601E4 + F54087D64A8752C38FD85CC09C0C7F38CE3A0320E5E16B507302D7830EA18793774A3D + 7BAA807971AD17332D8862C0FA757D98782CE927577A32B45BF18EEE77B393F410620C + 03093620470BBC93313489F11C96871C42DA296909ABF16A885950A2CF896CD18A61D5 + 4B3C529C96355AC2D3C69324C3AE634C8718C3CBFA734C40E78F9153A1286B379E0B76 + 36141DD20B43A26B6BB2E03A56F008F0868CE2B940CF108FCE7954C0A1B933CC15FE15 + 6E2C4C4E4EDCBBA1E87108E3CFF24865548A838E7619315B25C2653465158CAE4683AA + 03696870C397359B118CB37AA853D46CC5B05ACFDBC010C898428407009340A4793A05 + 718B0E12E95FA8685A213B8559B44021B8C3A458AF81C2476775ABF0015DBFF820427C + A306265DE9AE0F4AE474DF627DCD167AEA9FB7A6EB3F021BA4A78AE111275F13AC923E + 23D1F7082DD2B7C9BA1CF7957573C9778E452967D9D35277277471D1E15EC88ED243E0 + ABDAF1149BF31CEC85D81BB32BF3CFFB4E62301100C95B53023559948E18#))) diff --git a/tests/openpgp/privkeys/702F599E35E6E0BE68E6FDF25D887229D42780F7.key b/tests/openpgp/privkeys/702F599E35E6E0BE68E6FDF25D887229D42780F7.key new file mode 100644 index 000000000..cb3e6ea3e --- /dev/null +++ b/tests/openpgp/privkeys/702F599E35E6E0BE68E6FDF25D887229D42780F7.key @@ -0,0 +1,7 @@ +Created: 20240423T121603 +Key: (private-key (ecc (curve brainpoolP384r1)(q + #044F9318AAA2E3A3D28DA76F4B3B6B7CCAFA9B77A571E9A5BFFDEAC24A0FD96C6BB3 + 8F74FCF980696EDD5F4CBCA2B628AE24C9DBC1C60EF1D5809D4D544EBAA01F7744233E + 248106D98A67CE1ED52D14FA942F6090C9988AA5EEB2368E19F679E2#)(d + #0D146C6EDEC6AE142765DABBFFEF4EA6CA290EB7DDF99676F3F59AE6CA3942531B31 + 7330A07F5C8AAAEDFF69E6855301#))) diff --git a/tests/openpgp/privkeys/7C31A4A632A49C4E8B1C8CBA53976ADFF714510F.key b/tests/openpgp/privkeys/7C31A4A632A49C4E8B1C8CBA53976ADFF714510F.key new file mode 100644 index 000000000..e46ebbc6e --- /dev/null +++ b/tests/openpgp/privkeys/7C31A4A632A49C4E8B1C8CBA53976ADFF714510F.key @@ -0,0 +1,137 @@ +Created: 20240423T121650 +Key: (private-key (kyber1024 (p #9A9A0790782C7F4A7F51934777FBCF7E56C66C + 2A56158680E424196D2749B7D624FDC9AC2B890BF8594CAE427E79DB4B0551A1512736 + ACA58CA8ACB41DDB854A08B546170190075051E91A85529795044500E239514A2ABAD1 + BE0D4C9F6512A887C30903AABECFDB6A6708185641402473637C80806162BDF85C2133 + B0BBA05450E638860784902616621FE7529A107A5A976FAC4985C3583BEFF33DC4A05E + 52767599D426C11BBDE0A0C0BC45B6AEC3747A316E3119ADA71A5B6589927797483E36 + 13E9F836C87685A26BB35C93CCDCC8B2C3B8AF38C60B2B8BB54B21C9ADC91644D541E1 + 70AE1A97ABCAC321BF41855A48B71CF9250A39948601100AD1B26DA8740E2AA117E60F + B813848A126FDB87C0F2856B0497104250590B9041919A0253ECA5F283688D25C7788B + 68A21450F388B1FFDBB6736A9E38CCBC2A2B0F6A64AD45F882EDAC680AF060C0FA2B73 + 921E7F053EDA54549176BE0E65ABD94B490FE75681822B21B4784D849FB32C76DF08C8 + 17846A2628B1118580818740B637CEF7B31C1EC2B10FA7ADB8B4AEC9B541C568244E74 + A4D94817E7B294B78A637A8AAD9F762028398B757063445C1BEE807B316788A3FCB7F8 + A288C5463975301E4EA27171738EA0983D5AE01CD38811E9699F5065101CCCA251C052 + 4CB5B147B98FF65902243C98B1992475D297910383F6AAC31BE8A32D8A6341F436F5C4 + 928826AD4628C51A443826C05314E11851BC41CA1571E43061BB730A5AA1CBC9963690 + 3745458851E28864E54A885C0BC88C423670795777784A9607A3BD2004F1F51871000D + C6F2578AC434D486871E665D14C76B1A416CC72676A96C4E6F79B75BE23FA31C2527D7 + C976133F4B211E07E0BF4ED46C2FB77D81272290DB760DE8B567527B36316276AA9A36 + 89AF4B3790C08820A844258D139856944EB8C40C9EBB6D199A196D446FCF25B0E61688 + 4591950021AC9D5B62AFF2A46A955C36D21EC41B294EE3AC6235323BA1B3A3000B384B + 87813550FCAA470C6C6CBCC16D8732C5A3387C16C87B34B60D56B71797B177584C6A20 + 804C9C145698A2ADA0453ABB290B36124D2690124D1B4A0FB37BAA9A1BA0237690018B + 66E426B7F1400A8B3C0635A79689861F3B1A8041919F600B435179E375859591293E98 + 209A2B07AFE028982B5532275157E0545F844BC07C0491E55A2757A6DBDBB0A0817D58 + 0CA677E8C60823AEFC76B42845AB54C40BF0D5733198C326AAA99F11667FD583A97195 + D4091BA790C419BB2312684479E15E09D94974B5BF747CCC99BB9F348C411178645555 + 372EE08C514B6AF5BC4EAF357FE0132AF374475BFC7754B29945D525E5E45561967002 + 452C9B6A99B7340577D9AC5184911D3BA1E833C3FCD93B3401B3E8913721179D75AAB9 + 94A17FA6C9C62C2CCE4194C563B4A78BABAE8CC82E177835AB351884FA1638898D5491 + 2A2E87A5BF14170FD689E0E494DED76C43EBC23CE564B0EB94A5927DEC720C98346562 + D375E116AE6E00B5081B69CC45AB8263ADA4304C50615FCB3C78FA37961953560912B0 + 1D2C255541B94C929E1F105B6F462A36436090461473ECAA05BCCCB26536DFC157EA60 + B37B49B4A17154AE6003A1C053E52329DF375F86A48300B7855C6865A7FAAA3F04A10D + 7821B18A978B8AA8DD096C6C101015C4CF385422CD1105E765201A445D9D22B3C61525 + C4A09C692CA838E01EEF6B45F82A25B9F15108441A5911C5529498BB629A22543239EA + 9765453633C51E75B8C62F2C2D5E8A524E69097DF8480E8347F0F94ECC193DD9E2C86B + 7134066189C7FA6BC12331D5622CCAC42D090553E1191186E6315165BAD5039AA3A75A + 777AB9057A59D463C0E93B5DC34A058519848C78A607ECC631CC050554CEA61B29658A + 75D4D33DBC95AF5E587C1EC3B2B8E717FE85B8D3D41AE5C4700DCC449EA65491B55685 + 791686CB9B51E97B18671D92F1A356A3060001CAB220707206B485EA6E0BD85F53719D + FA3876C6534058C4C291330244C19AC87B944B6945B77B44577772DDC8727C60260C5B + 17B4819A2C801A9D168D0EEA03BCA50236BC20F69886CEFB0C6994BF25C1CC09209EA5 + 3B6C04F15F9613C5D04646D151457A206F0B35C9A40CC3782B2F851759F93040CC0BC9 + 75477C7228BD7D1435DA80607EAB07CAF93F3FAFC623B4458888F05949EA9B2972888F + D40F3E6E009F8C935E#)(s #8D204312E102743757098841C5E7661CD0469E50326578 + B3F7324E3A303617BBBFB9022E03C61F69BAA89890C72AB82964B60F039786C9436A84 + 7223E412A76F34B1AB913C44D0CC9682593BAB0738072748F2014A38A424DA91D629A4 + 33DC33928C862BBC466B3166884010AD6A33E20A75D9870D3C07C183C01F410444D982 + A15B8A377806136DB03A94EB5D2EF1311AE03884E92CED483365C582E5C60EE708AF20 + 939E135A5EE45781448911DAA90EBCA6792F86C13579C4D6305816F493A35C4F8BC3C6 + 4D516D901A38174701B33C597AA40953FAB5CF3C672C4B29220176BE370846AB24E216 + B634F3A6ED26CA88757854883FFB203382DB609F473686E57AF1970B75724E8D339DF8 + A7B614063556E72569447A81901705A319686125EE5480FB8C3C1B73CDE6DC8EFE7060 + 2D8811C52C85DB834C06B57850AC742683C05451B27F8B47C7491A42B102D1A83AB114 + 0D8EEA401C80467CC1826C59B572DCCA3B32880E07BC14C7A6A39015E7548197FC1BB8 + C8203554312F170FC3916727E9A5A349B427EBCC2833C77F4C045E8C4F5B39708C4C61 + FD2761BD824BCD5606992B1716C15EDE0155DD311238BC529C7838AD6B65BFB31915F6 + 7248021410E6A4BA44817D307B0F713689186BA91C683EAA7C29B509D57A41BA0A09FA + 4427F5C806CD705039669A5871C4170BB3F7081A77E17BFB1455311650EEFCC35C8336 + 03976CC8B34C9C23CA52641698DB36ED45AAABE15540A757F0BB09647B5D0943305FA7 + 91C89C623EC941D24CA283A208EB8745F0B2049E196CB3CC032782BB44F01B94A89883 + B5C52040806BFABA3143464677CF8540876E189FBE69BEA7B151D8106711F666929596 + D61A7344D783A7A741BCC4C5F8A9064FB29C27D8A08EA009E13414523088361B52A6C8 + 5C5FE88D54E4CAC784804F9C0E9B508E49DC7F1FD9574863C2B3B39EE74614BA60ABA6 + 52777832175026613BD08EB979B66B92AFEE89341C30770601892172CC7A34587C04B3 + FB901F0618CFEC0BA54874C95F833C99AC2ED7F20AB74C3719A27D7572CA6F8A99A221 + 843CA939491B210703497CB3288F227680E54F0954B62B455650979250336509709280 + 7BB80349A2B4F8576B4600225A8D059608C8173E78398C971A12940B14F414208ABA1D + 00343DA1332E2A813164D80C8E9B54D0212A481027EC0B81D3580E74982D63DA100265 + 9EB600A9E096140938526AA3B709B9086F1A9E78076EF36B372EF3C4DC4C6A1BE015C6 + 9B7DCFE960AAE67449424BD4448861520EE59008391243C9F508DBF22A7DF1C90DA9AB + FF663DD1D7BA02B2C21DE9BB5656BD935B639565982BE41805D5A2FE63646CB48A4A69 + 26A8E11C3185BAEF032372B8687ECC71021BB44004ADA09A9B6AAC0F335C2A9B689BEB + 556D9C706CCFC480DA20695CD0C94807A05BCAB436B88911FBB36DD36E1F734E66F288 + 5A325A06CCA6CEA3BECCE02E1E6B71FB9A5327A13B172C9E9D908327655A25DA8E6307 + C9BC251C4C7CA11B211327C68783727AB7F280FB654EAE3883BA3B54D2EBB4564A7C23 + 7AA44D3C15F48817A23B9A6D346D562560C34B41CAE117075857F9A6B23B717EBD719F + D4A75537D9420F411C0D9A75BF3160DA172FA9615579E4B0D4D965376B6F5006660330 + 216DB476F2688B512A836D52A2CBDC4C56B690BE205D1C681EB1D55702BC0611B960F6 + 558AACD22B41370C04B10BBC63B4EBE10BBDDC024C94BD7046C525F2767C6A55668A0B + EB47C0330C1A4E17493B15460DA6AD8084C304268DC0203013119017B59C5FE2C785A6 + 6BD7E130004DCEC940BB422CCE6D434049385443E18FC832C0A2C60553A5B4C81B8708 + 78AB143016F883A36A4742ED7B2BE8EAA13C817475F6B0A49462AD38A0993CB1A6F5A3 + 88E0835A8164B5F9B53B8C7A41E419F9E42ABEA1921BC5154B293D00B05CD900323533 + 1384E8AA789304F570249BF2B1D2AC7FD4AB93F76B41E49421ECBA3AA0D44A7A72296A + 5711069C94394270D03B3B13D99CAEB78B091C8C71924D5241ABD14C80FDE9C2E34346 + 8A974A844B760BF80A2826249A22A20E26ABFB1486AAD01E815B54A2CB32E179946C04 + 3F6F298DAB042FEEB65494376784F8424D73099910154F29CF1CC55A4D76BA3487C41F + 7A9E5B9C8FC324A49A9A0790782C7F4A7F51934777FBCF7E56C66C2A56158680E42419 + 6D2749B7D624FDC9AC2B890BF8594CAE427E79DB4B0551A1512736ACA58CA8ACB41DDB + 854A08B546170190075051E91A85529795044500E239514A2ABAD1BE0D4C9F6512A887 + C30903AABECFDB6A6708185641402473637C80806162BDF85C2133B0BBA05450E63886 + 0784902616621FE7529A107A5A976FAC4985C3583BEFF33DC4A05E52767599D426C11B + BDE0A0C0BC45B6AEC3747A316E3119ADA71A5B6589927797483E3613E9F836C87685A2 + 6BB35C93CCDCC8B2C3B8AF38C60B2B8BB54B21C9ADC91644D541E170AE1A97ABCAC321 + BF41855A48B71CF9250A39948601100AD1B26DA8740E2AA117E60FB813848A126FDB87 + C0F2856B0497104250590B9041919A0253ECA5F283688D25C7788B68A21450F388B1FF + DBB6736A9E38CCBC2A2B0F6A64AD45F882EDAC680AF060C0FA2B73921E7F053EDA5454 + 9176BE0E65ABD94B490FE75681822B21B4784D849FB32C76DF08C817846A2628B11185 + 80818740B637CEF7B31C1EC2B10FA7ADB8B4AEC9B541C568244E74A4D94817E7B294B7 + 8A637A8AAD9F762028398B757063445C1BEE807B316788A3FCB7F8A288C5463975301E + 4EA27171738EA0983D5AE01CD38811E9699F5065101CCCA251C0524CB5B147B98FF659 + 02243C98B1992475D297910383F6AAC31BE8A32D8A6341F436F5C4928826AD4628C51A + 443826C05314E11851BC41CA1571E43061BB730A5AA1CBC99636903745458851E28864 + E54A885C0BC88C423670795777784A9607A3BD2004F1F51871000DC6F2578AC434D486 + 871E665D14C76B1A416CC72676A96C4E6F79B75BE23FA31C2527D7C976133F4B211E07 + E0BF4ED46C2FB77D81272290DB760DE8B567527B36316276AA9A3689AF4B3790C08820 + A844258D139856944EB8C40C9EBB6D199A196D446FCF25B0E616884591950021AC9D5B + 62AFF2A46A955C36D21EC41B294EE3AC6235323BA1B3A3000B384B87813550FCAA470C + 6C6CBCC16D8732C5A3387C16C87B34B60D56B71797B177584C6A20804C9C145698A2AD + A0453ABB290B36124D2690124D1B4A0FB37BAA9A1BA0237690018B66E426B7F1400A8B + 3C0635A79689861F3B1A8041919F600B435179E375859591293E98209A2B07AFE02898 + 2B5532275157E0545F844BC07C0491E55A2757A6DBDBB0A0817D580CA677E8C60823AE + FC76B42845AB54C40BF0D5733198C326AAA99F11667FD583A97195D4091BA790C419BB + 2312684479E15E09D94974B5BF747CCC99BB9F348C411178645555372EE08C514B6AF5 + BC4EAF357FE0132AF374475BFC7754B29945D525E5E45561967002452C9B6A99B73405 + 77D9AC5184911D3BA1E833C3FCD93B3401B3E8913721179D75AAB994A17FA6C9C62C2C + CE4194C563B4A78BABAE8CC82E177835AB351884FA1638898D54912A2E87A5BF14170F + D689E0E494DED76C43EBC23CE564B0EB94A5927DEC720C98346562D375E116AE6E00B5 + 081B69CC45AB8263ADA4304C50615FCB3C78FA37961953560912B01D2C255541B94C92 + 9E1F105B6F462A36436090461473ECAA05BCCCB26536DFC157EA60B37B49B4A17154AE + 6003A1C053E52329DF375F86A48300B7855C6865A7FAAA3F04A10D7821B18A978B8AA8 + DD096C6C101015C4CF385422CD1105E765201A445D9D22B3C61525C4A09C692CA838E0 + 1EEF6B45F82A25B9F15108441A5911C5529498BB629A22543239EA9765453633C51E75 + B8C62F2C2D5E8A524E69097DF8480E8347F0F94ECC193DD9E2C86B7134066189C7FA6B + C12331D5622CCAC42D090553E1191186E6315165BAD5039AA3A75A777AB9057A59D463 + C0E93B5DC34A058519848C78A607ECC631CC050554CEA61B29658A75D4D33DBC95AF5E + 587C1EC3B2B8E717FE85B8D3D41AE5C4700DCC449EA65491B55685791686CB9B51E97B + 18671D92F1A356A3060001CAB220707206B485EA6E0BD85F53719DFA3876C6534058C4 + C291330244C19AC87B944B6945B77B44577772DDC8727C60260C5B17B4819A2C801A9D + 168D0EEA03BCA50236BC20F69886CEFB0C6994BF25C1CC09209EA53B6C04F15F9613C5 + D04646D151457A206F0B35C9A40CC3782B2F851759F93040CC0BC975477C7228BD7D14 + 35DA80607EAB07CAF93F3FAFC623B4458888F05949EA9B2972888FD40F3E6E009F8C93 + 5EFC819BE888E45002962BD84C240119DDC2FB54BAC77FFB2D990600F53E83DA47DE79 + 15EC78E7947BADC403546041E8985FB1BB2CEBE867C9D6E08C213E54992D#))) diff --git a/tests/openpgp/privkeys/A1ABFD89944870D04039D40C218EE127254AEEE9.key b/tests/openpgp/privkeys/A1ABFD89944870D04039D40C218EE127254AEEE9.key new file mode 100644 index 000000000..fd50945f6 --- /dev/null +++ b/tests/openpgp/privkeys/A1ABFD89944870D04039D40C218EE127254AEEE9.key @@ -0,0 +1,8 @@ +Created: 20240423T151629 +Key: (private-key (ecc (curve brainpoolP512r1)(q + #04681C6E8D70DEF5DED6097972643ECEA2538EA6CA3F9F87DC1E4B27D37CFDA3296A + F129D5EEB331D836EC7A215CC1CF4103184D21F7AA184C1EE9C338BAB19147438F4C30 + 705E610E142C29F712C913D01132D862F5B65D7FADE1E145B4D9FB08E8B281DA94139D + 11D3FDC0A55B85D1AFF0DDFE052779115A72DE03BB098E03DD#)(d + #32C7C4790D709ADC404D85A791FB119C327FA8E88F835BE8C4076E250ABAD2858237 + 6496ACC61573108A9518789BCF13FA7D33D6D4324D962895F6554DD6A129#))) diff --git a/tests/openpgp/privkeys/A87B85D88DB8B2B5A62A9958C8F2878F49605D09.key b/tests/openpgp/privkeys/A87B85D88DB8B2B5A62A9958C8F2878F49605D09.key new file mode 100644 index 000000000..b3898c99d --- /dev/null +++ b/tests/openpgp/privkeys/A87B85D88DB8B2B5A62A9958C8F2878F49605D09.key @@ -0,0 +1,5 @@ +Created: 20240423T121404 +Key: (private-key (ecc (curve brainpoolP256r1)(q + #0431801CBE11209D65705872CDBED8E8718ADEBC8F4F44D69A71244F883EFFF54654 + 7B31DCC0BC0D1BF5DE953DBE11A753DC3B9BD39DB955DCA30C1F2535F59CB4#)(d + #6418FBDFBCE6B9389971AF84468050995EC79FBCF42BE6AB5A5F96BF4A8000BE#))) diff --git a/tests/openpgp/privkeys/D54E9B75C3541D95C45E430DAC9645E9FB62C668.key b/tests/openpgp/privkeys/D54E9B75C3541D95C45E430DAC9645E9FB62C668.key new file mode 100644 index 000000000..835045265 --- /dev/null +++ b/tests/openpgp/privkeys/D54E9B75C3541D95C45E430DAC9645E9FB62C668.key @@ -0,0 +1,5 @@ +Created: 20240423T121447 +Key: (private-key (ecc (curve brainpoolP256r1)(q + #049A80F4C7499AE14056F51D49D9899D7B73DB1BE7EE62EEEAA477C7A1F96F55F118 + CC0C0F89FF23E636C4F27AC51F6C571802606689A9FD9940D717EEDB0702ED#)(d + #409D4A1B8E6B0C8CB466BCD8D6C0B1D832A73FD8241C6EA65F01EA2D3BFFE1A4#))) diff --git a/tests/openpgp/privkeys/EAD718DCE3D2F33A20BFC8BA617844DEF3FFAF3A.key b/tests/openpgp/privkeys/EAD718DCE3D2F33A20BFC8BA617844DEF3FFAF3A.key new file mode 100644 index 000000000..bc1e024a4 --- /dev/null +++ b/tests/openpgp/privkeys/EAD718DCE3D2F33A20BFC8BA617844DEF3FFAF3A.key @@ -0,0 +1,104 @@ +Created: 20240423T121447 +Key: (private-key (kyber768 (p #46A3CE8B663A26CB4AFC5A5ED35A405AD3B3A66 + B47A859A458AC6F1BF3518575209D91CD2311777DEA1A14D196E50388AC7A2E2599221 + FF2697F5129FE6A5FC6B89AB1667AAD7179A99111CBD874E3D18699DBC03A601E82E16 + 0547C2AA2962972B5AFD1EA74ECE3C67599693448760CB383FF044F8F716C37493865B + 419872B60173360AC74CCC31035C23A380D7660B536105ABA2CB2598F2434631C733E4 + 952398A182C799C732BE69FBCC94796781AFA137D27080FCE314B9590A8F48261A3FC7 + CB94A2094535E9712A29E02BA50C3BDA4D8B76F68BEE95907BB72A6913829245C7B9EB + C86778994FFC183EB423B9C48AF1A3A149621868CB984A67CAA8A8987DA6983337418E + 50217F0780C595BA39845A724A0400DA35FD0E308D2250F83723B009D41818C38156B9 + 6C5C6ACDBD592BED95D67E939486A16565005EF105D55D7983E534F1E8767814B5C141 + 867A0AC7CBE297CD39885BF837C9602BFD4344158F304B1BBC91F832B291214AAA0BE4 + 7661168F16D9229A1A4B53B0BEC7C657729D0D6365A51C4A7919CC49B7D88DA619A5B4 + 0FB082A33C26BE6100C5D183D2A72634AC46D314825B190B4AAF27573844E0CCCB21C6 + 69513A5279AC0B5F1588D48C01167478E940BC62247A772065E80F339B708651740B8D + B2955F3BA78F50C2E5C645F995BCBCCFB466E0390DF2A595B69193FF3ADF1422D41A08 + 33940355DDC48DD93960B0A4D9681A5BD54234DB94B24C44B2EFC9A90731978B9B4E2D + 12E4C253A58A947651658FA949A267323A79C4875488A7F9C0D22EB743EF6A39EE30E3 + 423B6911677827BC3C2001154027381843E4C58B0B43B59EF317DEC146A27817664990 + 2DC68245406C4835A56BB0174A30C50CD59598F873A979A6F15612B5044798C1AAEEB5 + 40883A33766BB274A1B390BCB8AFC0C9C11A14A4D5568F237A9EC3232AA782BEFE6BBF + 2F8385B5C5E5133232907BAF963789F24B3EE989DC78C3AD0F59045B7ACF66340FDA65 + 5442A19AADA6697175013FB0668C45153B61EF722C2CBF571AE3810801A3B1567CD797 + 49C33955A4B413DCC989F24EA4AAFE80A2C3A24925574E422C11BA8735E9C96E9929DE + 9D263DA7ACD08A80A5BACA156C11161B3A7D0C56BADE20385C51A30941C16D4849EFCC + 89D479ADC6A9C06FC383AD900BA03750EC3BA81F97916D90FBC6582DE92CDF3E7C7DF5 + C9621CA99CCA47D72A171C8C945E6891E421C87CAF523776874A3C441C2A824704ACDC + 5D384F65958D47A46DEB079A1B895F0D37D9CF36F6622A1D19109FB1933B52B4D9D271 + 83496547B1794CDC675437C90C0C36C38F12A23D70B6D83540CC395BBA1B1885A3B8EB + 582D0A5C294E0048E7A94BC1A2E17F89DA710887C3B8241DB4D0891564D939932C047F + B28A2180B878F5BC142EB152E49411C8C1AB33A568E401BB827AD4E7B7B04A89236C40 + 0B233006A89A77CC362F5F63D57715A85EC08BB175348FA305876CD3A282547A3502FD + 14AB85004BEB50EB6C8B2F5E217FF086C86473F1B34672FB9CBFA63BE1DB8A13DC76A9 + CB30C6FEA0A25C828D8A6B6FB725569B888692B46DAEC53332A9AF9B61B1FC92851A02 + 33384A9735B86F076A05F44C97DA491C69AAD8622CEC7530C0BD13CA98B91E58BC1229 + 7CA2C2B37CDCE455EB5#)(s #0679BE74A86EB9B647B637B40EE3A26C4B3EA6D57024B + 56827C02017071E98052BCF0A4CA78036A672849D39975C06173FDAC73E6A732ACCB2E + FF887D77BA3D8E56A34643438A92ABCA1332F8C01AAB537AD721AD8E46DBB6742FE7C6 + 9BDDA9D6FC3139081839AD702979018E41C60BCA2650C682DD003BD05C8AE3622761EB + 775BFCB89EEC67A12211FC67700DD0C62D499C0E75A7084E618F4B141461ACA2387380 + 98947E8EBCDC86440426A8DB0F5737724218E75084E5C0A8CC96BFD842FEE6712B12B9 + A1EF5A506577C7DDC1CD7905F7A853588452CD4A17707546DB6039C90AB82FA17026AD + B035C329AF7309BC560B3706919A2770337E008C14936F30900FCF541FAE7050A49A6B + CA80DDF0695D3A885EBD1AAA80009C9F06D72D10FAD4A1A8908832E151B668575678CC + FB67A4A34B6489CE3CC5865A5AD290853B12668401076A6355837359C27229B748E400 + 2BC24506E42DA05DE5562107138DDBC13B99421C784CACA035766C040C9B8A5925666A + C218E7E1B300D3B5CC0D826F9E36871C860E7497804652F12D65BC2610FD5A3BD6AC4B + B0C38262C719EF66868CD4245F67C623CD5B7FAD28674E21564826A0D5B95E8125B03C + 9C99EB4ADD7B74AC16BC1CCF613453143F935A0AB34222FB6C079A4C372AC1632770FA + 8B30FA9B6399DCBAFA67723C760378DB081FCD8C825B18F45721550FBB86E747C1E7B0 + 2A68A3796266C11FC3444D38CBE0B72D9D885C5C77F0AE48A038B7EE2CA97B1C126333 + A9130DA1BDB94C6317660655C0F09D8C130A72ACA784176D4ADE57161B6801333A11C3 + E119CA2757BBEB08B5112AF06965452C1CD797165E51209BF04C6F90B3373F2CC9E02B + 1A1594D4895B4C18C4774D222C0505BABEA18216642E7B7CBA796ACBC5C82354152ECB + 765B2D56F10E925F57BC45ED1421638AF87B8C125A74473B78D026295F341315D7A1A6 + B1B2EA946817222338E8342C093CD5FC393F1A92931C92678766D2A465E5A4C5A90C35 + 758C20BE0AAB6A8E0752250607DCB0603018CF4F07390AA328CF2C8364AA63FB25C815 + 8A37A69716E743FE47303B498968E095226E59A24E4761676060504C5B0ABB5F0548DB + 3650854FB1AB66061426C3DBB177EFB1C0ADED3C142405C0CF7756A50776EBB76D4882 + 44AD008ABB3766594071C38A835CC477C01A169E0C6AFA43AB81037A6E9606CB234590 + 77DA8CC72F7C98732A56D557201B2C46E29460C37A3BD808C0E7BD346951292BFB51BE + 81C3A384B3277912CCCB521CB0BC81C76565CA65DF354680A1A243915655CA311374C4 + E998977DB488A79B63864C440C8EC0E59F9C169A181AC48CCED41722FBC16D8DC22179 + C3988237EF7E75467DC5AAC434AD6498690F28407A46015491BD0EC779AB079A9C0194 + 5C0B3DF39036F3A0BFE80CB1DF898B24A1354B0BE35560EA0DBB12C30935BF047ACF36 + 1CAC11B8D3C1D1C624B16F76EC3A80783C3742E195B031943C9A9A21702399BF9A4A25 + 848A8951DFB047FCBC4ADBDD79C73EC27F6348281072BD670831BA5B414945CC12423F + 2D5C2CF34C9F4C841AD620B665623CD74CCFC162E0AD04BD0646F581C372EBA355DA8A + 64CA92BE1056B2CFA7B46A3CE8B663A26CB4AFC5A5ED35A405AD3B3A66B47A859A458A + C6F1BF3518575209D91CD2311777DEA1A14D196E50388AC7A2E2599221FF2697F5129F + E6A5FC6B89AB1667AAD7179A99111CBD874E3D18699DBC03A601E82E160547C2AA2962 + 972B5AFD1EA74ECE3C67599693448760CB383FF044F8F716C37493865B419872B60173 + 360AC74CCC31035C23A380D7660B536105ABA2CB2598F2434631C733E4952398A182C7 + 99C732BE69FBCC94796781AFA137D27080FCE314B9590A8F48261A3FC7CB94A2094535 + E9712A29E02BA50C3BDA4D8B76F68BEE95907BB72A6913829245C7B9EBC86778994FFC + 183EB423B9C48AF1A3A149621868CB984A67CAA8A8987DA6983337418E50217F0780C5 + 95BA39845A724A0400DA35FD0E308D2250F83723B009D41818C38156B96C5C6ACDBD59 + 2BED95D67E939486A16565005EF105D55D7983E534F1E8767814B5C141867A0AC7CBE2 + 97CD39885BF837C9602BFD4344158F304B1BBC91F832B291214AAA0BE47661168F16D9 + 229A1A4B53B0BEC7C657729D0D6365A51C4A7919CC49B7D88DA619A5B40FB082A33C26 + BE6100C5D183D2A72634AC46D314825B190B4AAF27573844E0CCCB21C669513A5279AC + 0B5F1588D48C01167478E940BC62247A772065E80F339B708651740B8DB2955F3BA78F + 50C2E5C645F995BCBCCFB466E0390DF2A595B69193FF3ADF1422D41A0833940355DDC4 + 8DD93960B0A4D9681A5BD54234DB94B24C44B2EFC9A90731978B9B4E2D12E4C253A58A + 947651658FA949A267323A79C4875488A7F9C0D22EB743EF6A39EE30E3423B69116778 + 27BC3C2001154027381843E4C58B0B43B59EF317DEC146A278176649902DC68245406C + 4835A56BB0174A30C50CD59598F873A979A6F15612B5044798C1AAEEB540883A33766B + B274A1B390BCB8AFC0C9C11A14A4D5568F237A9EC3232AA782BEFE6BBF2F8385B5C5E5 + 133232907BAF963789F24B3EE989DC78C3AD0F59045B7ACF66340FDA655442A19AADA6 + 697175013FB0668C45153B61EF722C2CBF571AE3810801A3B1567CD79749C33955A4B4 + 13DCC989F24EA4AAFE80A2C3A24925574E422C11BA8735E9C96E9929DE9D263DA7ACD0 + 8A80A5BACA156C11161B3A7D0C56BADE20385C51A30941C16D4849EFCC89D479ADC6A9 + C06FC383AD900BA03750EC3BA81F97916D90FBC6582DE92CDF3E7C7DF5C9621CA99CCA + 47D72A171C8C945E6891E421C87CAF523776874A3C441C2A824704ACDC5D384F65958D + 47A46DEB079A1B895F0D37D9CF36F6622A1D19109FB1933B52B4D9D27183496547B179 + 4CDC675437C90C0C36C38F12A23D70B6D83540CC395BBA1B1885A3B8EB582D0A5C294E + 0048E7A94BC1A2E17F89DA710887C3B8241DB4D0891564D939932C047FB28A2180B878 + F5BC142EB152E49411C8C1AB33A568E401BB827AD4E7B7B04A89236C400B233006A89A + 77CC362F5F63D57715A85EC08BB175348FA305876CD3A282547A3502FD14AB85004BEB + 50EB6C8B2F5E217FF086C86473F1B34672FB9CBFA63BE1DB8A13DC76A9CB30C6FEA0A2 + 5C828D8A6B6FB725569B888692B46DAEC53332A9AF9B61B1FC92851A0233384A9735B8 + 6F076A05F44C97DA491C69AAD8622CEC7530C0BD13CA98B91E58BC12297CA2C2B37CDC + E455EB5F45B962B404EC9D9ADA018C9243AA1C5DB1F39D31391BF62AB800F85D6BAB5C + 503A078F0E1B47A9475FF068E159DED6A0D5C8291D6054524B0A8064D9DA18A39#))) diff --git a/tests/openpgp/samplekeys/README b/tests/openpgp/samplekeys/README index 8e8b598b3..88361ee30 100644 --- a/tests/openpgp/samplekeys/README +++ b/tests/openpgp/samplekeys/README @@ -25,6 +25,9 @@ v5-sample-1-pub.asc A version 5 key (ed25519/cert,sign,v5+cv25519/v5) v5-sample-1-sec.asc Ditto, but the secret keyblock (unprotected). pqc-sample-1.key.asc ky768_cv25519 public key. [*] pqc-sample-2.key.asc ky1024_cv448 public key. [*] +pqc-sample-3.key.asc ky768_bp256 public key. [*] +pqc-sample-4.key.asc ky1024_bp384 public key. [*] +pqc-sample-5.key.asc ky1024_bp384 public key. [*] Notes: diff --git a/tests/openpgp/samplekeys/pqc-sample-3.key.asc b/tests/openpgp/samplekeys/pqc-sample-3.key.asc new file mode 100644 index 000000000..78f9a8f75 --- /dev/null +++ b/tests/openpgp/samplekeys/pqc-sample-3.key.asc @@ -0,0 +1,48 @@ +pub brainpoolP256r1 2024-04-23 [SC] + 9F7DCCABC11EFE248F48CECD6F6570B33D05BDF8 + Keygrip = A87B85D88DB8B2B5A62A9958C8F2878F49605D09 +uid pqc-sample-3 +sub ky768_bp256 2024-04-23 [E] + B4707EA9BF0FF29F65190D779BE6064181208C59988A80BCD2B2177A9BBDFE22 + Keygrip = D54E9B75C3541D95C45E430DAC9645E9FB62C668, + EAD718DCE3D2F33A20BFC8BA617844DEF3FFAF3A + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mFMEZiemDBMJKyQDAwIIAQEHAgMEMYAcvhEgnWVwWHLNvtjocYrevI9PRNaacSRP +iD7/9UZUezHcwLwNG/XelT2+EadT3Dub0525VdyjDB8lNfWctLQMcHFjLXNhbXBs +ZS0ziJMEExMIADsCGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AWIQSffcyr +wR7+JI9Izs1vZXCzPQW9+AUCZiemUAAKCRBvZXCzPQW9+K6XAP9Y9gQJG6kAzNKX +BxHST/UwcxvA92UBYeHesTIXpop4kgD/dOS9g2UWNAWPkW0/xiGMSuFBIyJOSjpL +Ny73Fn0lmgG5BPsFZiemNx0AAATxCSskAwMCCAEBBwIDBJqA9MdJmuFAVvUdSdmJ +nXtz2xvn7mLu6qR3x6H5b1XxGMwMD4n/I+Y2xPJ6xR9sVxgCYGaJqf2ZQNcX7tsH +Au0AAASgRqPOi2Y6JstK/Fpe01pAWtOzpmtHqFmkWKxvG/NRhXUgnZHNIxF3feoa +FNGW5QOIrHouJZkiH/Jpf1Ep/mpfxriasWZ6rXF5qZERy9h049GGmdvAOmAeguFg +VHwqopYpcrWv0ep07OPGdZlpNEh2DLOD/wRPj3FsN0k4ZbQZhytgFzNgrHTMwxA1 +wjo4DXZgtTYQWrosslmPJDRjHHM+SVI5ihgseZxzK+afvMlHlnga+hN9JwgPzjFL +lZCo9IJho/x8uUoglFNelxKingK6UMO9pNi3b2i+6VkHu3KmkTgpJFx7nryGd4mU +/8GD60I7nEivGjoUliGGjLmEpnyqiomH2mmDM3QY5QIX8HgMWVujmEWnJKBADaNf +0OMI0iUPg3I7AJ1BgYw4FWuWxcas29WSvtldZ+k5SGoWVlAF7xBdVdeYPlNPHodn +gUtcFBhnoKx8vil805iFv4N8lgK/1DRBWPMEsbvJH4MrKRIUqqC+R2YRaPFtkimh +pLU7C+x8ZXcp0NY2WlHEp5GcxJt9iNphmltA+wgqM8Jr5hAMXRg9KnJjSsRtMUgl +sZC0qvJ1c4RODMyyHGaVE6UnmsC18ViNSMARZ0eOlAvGIkencgZegPM5twhlF0C4 +2ylV87p49QwuXGRfmVvLzPtGbgOQ3ypZW2kZP/Ot8UItQaCDOUA1XdxI3ZOWCwpN +loGlvVQjTblLJMRLLvyakHMZeLm04tEuTCU6WKlHZRZY+pSaJnMjp5xIdUiKf5wN +Iut0PvajnuMONCO2kRZ3gnvDwgARVAJzgYQ+TFiwtDtZ7zF97BRqJ4F2ZJkC3Ggk +VAbEg1pWuwF0owxQzVlZj4c6l5pvFWErUER5jBqu61QIg6M3ZrsnShs5C8uK/Ayc +EaFKTVVo8jep7DIyqngr7+a78vg4W1xeUTMjKQe6+WN4nySz7pidx4w60PWQRbes +9mNA/aZVRCoZqtpmlxdQE/sGaMRRU7Ye9yLCy/VxrjgQgBo7FWfNeXScM5VaS0E9 +zJifJOpKr+gKLDokklV05CLBG6hzXpyW6ZKd6dJj2nrNCKgKW6yhVsERYbOn0MVr +reIDhcUaMJQcFtSEnvzInUea3GqcBvw4OtkAugN1DsO6gfl5FtkPvGWC3pLN8+fH +31yWIcqZzKR9cqFxyMlF5okeQhyHyvUjd2h0o8RBwqgkcErNxdOE9llY1HpG3rB5 +obiV8NN9nPNvZiKh0ZEJ+xkztStNnScYNJZUexeUzcZ1Q3yQwMNsOPEqI9cLbYNU +DMOVu6GxiFo7jrWC0KXClOAEjnqUvBouF/idpxCIfDuCQdtNCJFWTZOZMsBH+yii +GAuHj1vBQusVLklBHIwaszpWjkAbuCetTnt7BKiSNsQAsjMAaomnfMNi9fY9V3Fa +hewIuxdTSPowWHbNOiglR6NQL9FKuFAEvrUOtsiy9eIX/whshkc/GzRnL7nL+mO+ +HbihPcdqnLMMb+oKJcgo2Ka2+3JVabiIaStG2uxTMyqa+bYbH8koUaAjM4Spc1uG +8HagX0TJfaSRxpqthiLOx1MMC9E8qYuR5YvBIpfKLCs3zc5FXrWIeAQYEwgAIBYh +BJ99zKvBHv4kj0jOzW9lcLM9Bb34BQJmJ6Y3AhsMAAoJEG9lcLM9Bb34tPABAIHU +3sAgcUS47Plw8XlrX04941JkVaoE/RAGWm4OHAsbAP4hylj3DC0vrKwUkirkJEkY +x4ISI2U8yiITrTcSWAKs9A== +=6QFw +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/openpgp/samplekeys/pqc-sample-4.key.asc b/tests/openpgp/samplekeys/pqc-sample-4.key.asc new file mode 100644 index 000000000..e913f78da --- /dev/null +++ b/tests/openpgp/samplekeys/pqc-sample-4.key.asc @@ -0,0 +1,58 @@ +pub brainpoolP384r1 2024-04-23 [SC] + A8237D19988A8255E70D2566EC280D0923FB2DF7 + Keygrip = 702F599E35E6E0BE68E6FDF25D887229D42780F7 +uid pqc-sample-4 +sub ky1024_bp384 2024-04-23 [E] + FBCD76AC9908E094D22CAE2564C9CB50EC69AACF0E3AEC91AA115CE43C71DC81 + Keygrip = 19C87B74004E9839F3D56992B0A9943BF90B56F7, + 7C31A4A632A49C4E8B1C8CBA53976ADFF714510F + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mHMEZiemgxMJKyQDAwIIAQELAwMET5MYqqLjo9KNp29LO2t8yvqbd6Vx6aW//erC +Sg/ZbGuzj3T8+YBpbt1fTLyitiiuJMnbwcYO8dWAnU1UTrqgH3dEIz4kgQbZimfO +HtUtFPqUL2CQyZiKpe6yNo4Z9nnitAxwcWMtc2FtcGxlLTSIswQTEwkAOxYhBKgj +fRmYioJV5w0lZuwoDQkj+y33BQJmJ6aDAhsDBQsJCAcCAiICBhUKCQgLAgQWAgMB +Ah4HAheAAAoJEOwoDQkj+y33WBIBfjsh0jq5dpbhgcJ+CWRSdbFUtLzm68BpuEbS +Xk3Rzfu06NahW7N6My5sXZTtkblgfAF/el7MA1ezHITsTp0xC+qrl4LeU5qq3LjB +AZ4vQZUYiparLFLGjgFydw//j4S/z8MPuQabBWYnprIdAAAGkQkrJAMDAggBAQsD +AwRy+w1aCgHlXCnp+4xcQlvfNxUNr6PFVseG4v754BGRnmg9vHcx0Sgf25eAxLf9 +d4UZhRa+IDPQZEi6fqOcK8txKLweCz+B8uc0Q05v6Wsp4ZxXtCPFAJE0AQzYf63K +Y6EAAAYgmpoHkHgsf0p/UZNHd/vPflbGbCpWFYaA5CQZbSdJt9Yk/cmsK4kL+FlM +rkJ+edtLBVGhUSc2rKWMqKy0HduFSgi1RhcBkAdQUekahVKXlQRFAOI5UUoqutG+ +DUyfZRKoh8MJA6q+z9tqZwgYVkFAJHNjfICAYWK9+FwhM7C7oFRQ5jiGB4SQJhZi +H+dSmhB6WpdvrEmFw1g77/M9xKBeUnZ1mdQmwRu94KDAvEW2rsN0ejFuMRmtpxpb +ZYmSd5dIPjYT6fg2yHaFomuzXJPM3Miyw7ivOMYLK4u1SyHJrckWRNVB4XCuGper +ysMhv0GFWki3HPklCjmUhgEQCtGybah0DiqhF+YPuBOEihJv24fA8oVrBJcQQlBZ +C5BBkZoCU+yl8oNojSXHeItoohRQ84ix/9u2c2qeOMy8KisPamStRfiC7axoCvBg +wPorc5IefwU+2lRUkXa+DmWr2UtJD+dWgYIrIbR4TYSfsyx23wjIF4RqJiixEYWA +gYdAtjfO97McHsKxD6etuLSuybVBxWgkTnSk2UgX57KUt4pjeoqtn3YgKDmLdXBj +RFwb7oB7MWeIo/y3+KKIxUY5dTAeTqJxcXOOoJg9WuAc04gR6WmfUGUQHMyiUcBS +TLWxR7mP9lkCJDyYsZkkddKXkQOD9qrDG+ijLYpjQfQ29cSSiCatRijFGkQ4JsBT +FOEYUbxByhVx5DBhu3MKWqHLyZY2kDdFRYhR4ohk5UqIXAvIjEI2cHlXd3hKlgej +vSAE8fUYcQANxvJXisQ01IaHHmZdFMdrGkFsxyZ2qWxOb3m3W+I/oxwlJ9fJdhM/ +SyEeB+C/TtRsL7d9gScikNt2Dei1Z1J7NjFidqqaNomvSzeQwIggqEQljROYVpRO +uMQMnrttGZoZbURvzyWw5haIRZGVACGsnVtir/KkapVcNtIexBspTuOsYjUyO6Gz +owALOEuHgTVQ/KpHDGxsvMFthzLFozh8Fsh7NLYNVrcXl7F3WExqIIBMnBRWmKKt +oEU6uykLNhJNJpASTRtKD7N7qpoboCN2kAGLZuQmt/FACos8BjWnlomGHzsagEGR +n2ALQ1F543WFlZEpPpggmisHr+AomCtVMidRV+BUX4RLwHwEkeVaJ1em29uwoIF9 +WAymd+jGCCOu/Ha0KEWrVMQL8NVzMZjDJqqpnxFmf9WDqXGV1Akbp5DEGbsjEmhE +eeFeCdlJdLW/dHzMmbufNIxBEXhkVVU3LuCMUUtq9bxOrzV/4BMq83RHW/x3VLKZ +RdUl5eRVYZZwAkUsm2qZtzQFd9msUYSRHTuh6DPD/Nk7NAGz6JE3IReddaq5lKF/ +psnGLCzOQZTFY7Sni6uujMguF3g1qzUYhPoWOImNVJEqLoelvxQXD9aJ4OSU3tds +Q+vCPOVksOuUpZJ97HIMmDRlYtN14RaubgC1CBtpzEWrgmOtpDBMUGFfyzx4+jeW +GVNWCRKwHSwlVUG5TJKeHxBbb0YqNkNgkEYUc+yqBbzMsmU238FX6mCze0m0oXFU +rmADocBT5SMp3zdfhqSDALeFXGhlp/qqPwShDXghsYqXi4qo3QlsbBAQFcTPOFQi +zREF52UgGkRdnSKzxhUlxKCcaSyoOOAe72tF+ColufFRCEQaWRHFUpSYu2KaIlQy +OeqXZUU2M8UedbjGLywtXopSTmkJffhIDoNH8PlOzBk92eLIa3E0BmGJx/prwSMx +1WIsysQtCQVT4RkRhuYxUWW61QOao6dad3q5BXpZ1GPA6Ttdw0oFhRmEjHimB+zG +McwFBVTOphspZYp11NM9vJWvXlh8HsOyuOcX/oW409Qa5cRwDcxEnqZUkbVWhXkW +hsubUel7GGcdkvGjVqMGAAHKsiBwcga0hepuC9hfU3Gd+jh2xlNAWMTCkTMCRMGa +yHuUS2lFt3tEV3dy3chyfGAmDFsXtIGaLIAanRaNDuoDvKUCNrwg9piGzvsMaZS/ +JcHMCSCepTtsBPFflhPF0EZG0VFFeiBvCzXJpAzDeCsvhRdZ+TBAzAvJdUd8cii9 +fRQ12oBgfqsHyvk/P6/GI7RFiIjwWUnqmylyiI/UDz5uAJ+Mk16IlwQYEwkAIBYh +BKgjfRmYioJV5w0lZuwoDQkj+y33BQJmJ6ayAhsMAAoJEOwoDQkj+y331g4BfiAE +9eRbjyVlWhuHPFETqMyGnkaB8G2OmY96TMCORisMyhfk3ahwJ8BNS3XLI5+tnwF4 +iMv+X1/eMgtVY8DCDox4fw6kbDNvR+rR1CfkBMn/ewKKc0IZ5BuQE+ByzMw1ujk= +=Ztpi +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/openpgp/samplekeys/pqc-sample-5.key.asc b/tests/openpgp/samplekeys/pqc-sample-5.key.asc new file mode 100644 index 000000000..6da585015 --- /dev/null +++ b/tests/openpgp/samplekeys/pqc-sample-5.key.asc @@ -0,0 +1,61 @@ +pub brainpoolP512r1 2024-04-23 [SC] + 7B3986A550E5DB116054B4B42CBE157D37FDEC1D + Keygrip = A1ABFD89944870D04039D40C218EE127254AEEE9 +uid pqc-sample-5 +sub ky1024_bp512 2024-04-23 [E] + CA44B5ED43D33290398C5D0983EE5EE4721EC5C680AEA12C2282451D3ED65F4F + Keygrip = 513906BEA5A40F25C9D6EBBCEF62D0784E7235A5, + 6EC551A7895031EE4543A1C789E16E6A6C229CFC + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mJMEZifQzRMJKyQDAwIIAQENBAMEaBxujXDe9d7WCXlyZD7OolOOpso/n4fcHksn +03z9oylq8SnV7rMx2DbseiFcwc9BAxhNIfeqGEwe6cM4urGRR0OPTDBwXmEOFCwp +9xLJE9ARMthi9bZdf63h4UW02fsI6LKB2pQTnRHT/cClW4XRr/Dd/gUneRFact4D +uwmOA920DHBxYy1zYW1wbGUtNYjTBBMTCgA7FiEEezmGpVDl2xFgVLS0LL4VfTf9 +7B0FAmYn0M0CGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQLL4VfTf9 +7B3UcwH+JBipc+OsxxqdhGeoNrYUAmDL4NoXMAhkTYPa7Qwub48ThWz3GjFOCnqr +dyfxBPrEjW5MjRarC2eomaWO7mGbbQH/VXLH4/pq2MGlrhpRfupidbWDmFtHH2NQ +oXSACpYNSTAjuy72p9s4dYbMMWRl85qQxh+4PtmY5XgQXOfd0FFgF7kGuwVmJ9Dq +HQAABrEJKyQDAwIIAQENBAMEbiaJbqyNPX8x8LV0Of/bwAeIQc73qamKsV9In+40 +6dFeIFDq/KDNTHAh5eAY9gHux+3eGqzpWeoT+EFDhhSJ3VStqk/4bl/3XjzC6mRT +cWB13ZCLlke0UlemSuiN05DXMlueMGmAJxazdDr+en5ESVr2JcPgCcWBxj40Ghai +PQcAAAYgvndoszgAtYOXhBSWXsQ50ppBgGVbCli6QMucKdEAiKB9ZrR65hJLmGFW +qTR4ePvPwDUQSdLBiDXO5yut4ot6yLp/+DRa2IWx5zBAmTnFs6Glhnq3kSU48jRZ +qjNSBOzF6UqbZRdyqaxcYKUTeqdHGZlkedekJIORcjmAeFdJOCWJbGKNoXJkGNhD +5JRvmDii4tpbk8aAWZXNfUsm63m8vWReUrMXA5hmhssqsmoiAph5vVchKSgJbwlU +plZU+tZlH+sRA5xuDwMXICUwNICub1oO14ahfjd5q9d1sVQHtlYMl8Qs+Gpj16oQ +MnZ9INl+rXo+/NNG0AtN/RR/rpx7zGQiSDe2xidwduJb51bCAaWERXea6YZ5x1PC +u6aUJdNDpRVurtF6rPC5OcSbP+g6qAxeQ5m+gcE/Ciy05rCOWIoTuJRKyfdNeVQf +qxaRvogVb5IPqDbE1BrEllAJ+qF02ja1Uhx59DE7SYUlMRNpJhtkSPx67mudREVb +9jR8NfK5n5UlTGAndZuZyhZlkAa60ffAsgy9v/Zqj0VOJIY7F1oLYUgwrIrLGvuT +8dPFT3IW2qBa4hC1e1A+Rle2hwqM1EhkS3pbaPVl6fUcnxKJCsgxXtUgFfa77YnG +kkvHVut1L7NQK8UMr6Bz4bauPdKeDJJp+LUFygZUcCEU8DuugclFsTYx6mwoskS8 +37FZtVserKwwr3hyvTyPW+oO6QVtsubIfJsgSrIQGGliF9ZI78u7TAeMFnUbA3Ar +r0R/+3Qf2yRVr1qbymozQMW49rgnSHIwJLIOb1o9VieNvJddTqcNk5mm41VTOSCj +xehYrVGAvUQ08+QrlxkIqlkau/PB6/JXYnyyv3QNwbiMdVGluEYvbOO1jGWjkMB8 +AaFcK8YkqwB5JNm3bdGlBgPBkieKJMyGz6qVLmas/pmoANVsRzp4d5Vfx9g8HdVI +pXUnslkLVrbLPoUl8GmGclN5xBMPj+FVJNVpNGqvRRU43GYxSfGUbVUJvju2AmAx ++HrEshuA1mmB+FJ82vCtS/wqOzJlvaxOZRkLXXdydYluojhgbKeyFzwcTeAQWJZR +KLyGa4zCmRBFrkcyQkPLsICOL4UfyVY3eawmlmSwGuy+9FRl/rlYTMR/OwMXlFlL +9XSXRGsKhWdVQppziaIas1c8LYoDYjhIZFEBPWR9KIl5IAqDcsYDn6I+NYdwCECM +fIFeVQNaW6kWW7s7pWqWJTtSbdw3/MKfFvGOfWZ2o5O4Z4SchZJ8r5lqn+OI/4gN +VhWsZLe0JRgD15WZ0iMtVgyF9WJkPpufM/gTnQthq+mPdgQ+UWYUWgRbg+V0qrNd +nRGaPrMQf7M4jvSDsFZyazA2wpZjAYySn9ly1ETFQ3MW10mvDRJVbxWfwCWExrhF +a/VtwhKNymG3lOeq+2GWk1S1ptqC61Rc+iQs6ZelFoqkOSYTEWW1NPu+HxWk1EMv +9buERqV15ShIC3w/oDKMgTTAv3eHksBZAusyR2MmrpeczwyAw5xLczKfxOo2UWSo +SNUpvLQ5hdNbOuMLAqwFfhkQvbYW9Qp58iRBs1HHfIoXq0BS9EkwuZGvfHUSCSU8 +TSfIxRZsMoWhsdOZgbhezlzHrxG0uLOBcJY3ZuYTCmar1zZHgGfAqGRwxUIhauFZ +NZFi9yw0JBYB5PVAh9ZKh1LDj9hcwJwMfzjOOgMg5eFrUHMC14MOoYeTd0o9e6qA +eXGtFzMtiGLA+nV9mHgs6SdXejK0W/GO7nezk/QQYgwDCTYgRwu8kzE0ifEclocc +QtopaQmr8WqIWVCiz4ls0Yph1Us8UpyWNVrC08aTJMOuY0yHGMPL+nNMQOePkVOh +KGs3ngt2NhQd0gtDomtrsuA6VvAI8IaM4rlAzxCPznlUwKG5M8wV/hVuLExOTty7 +oehxCOPP8khlVIqDjnYZMVslwmU0ZRWMrkaDqgNpaHDDlzWbEYyzeqhT1GzFsFrP +28AQyJhChAcAk0CkeToFcYsOEulfqGhaITuFWbRAIbjDpFivgcJHZ3Wr8AFdv/gg +QnyjBiZd6a4PSuR032J9zRZ66p+3pus/Ahukp4rhESdfE6ySPiOIuAQYEwoAIBYh +BHs5hqVQ5dsRYFS0tCy+FX03/ewdBQJmJ9DqAhsMAAoJECy+FX03/ewdgGQB/3hG +AN5CHePZ4HY9ijl6NtptnzotFl0upj+ItZGsQAd+VroLkPI3Mk0HBecsWplYniS5 +ccBhUFTxlrDpPUXziHgB/0OtCd8cWWJtDOKs2rqdGxb+wfGKYmpOfELMIM6xkh43 +xYAjT76qD4Ht7Hf8tXBLJ3sYfcR2CCSQlDmoXrEUdFg= +=qQEJ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/openpgp/samplemsgs/pqc-sample-3.enc.asc b/tests/openpgp/samplemsgs/pqc-sample-3.enc.asc new file mode 100644 index 000000000..6ceed5f6b --- /dev/null +++ b/tests/openpgp/samplemsgs/pqc-sample-3.enc.asc @@ -0,0 +1,32 @@ +-----BEGIN PGP MESSAGE----- + +hQS7A7Rwfqm/D/KfHQIDBHU3DvDIzFvwqYhmBHaN2qSe8cDi8rsj8Q4aJkioD9W/ +RJwG2ca+WWpOeBt1LBrZRE2+e1303lPxbWioK/osn+0AAARAZv6eblIHDvd1SgKP +Ta+5aYdnfSSkUVwes2RrE3g9sa1LbkHACvpyYaA1ZsKjnueqw9q0tSr3IiSQ1Pnb +yHbokFafgSViMJPbWtWv0d+Nr8piFa8bdNVCtTfwntnHqqHfsMhdBwoH8feq028K +yqC2kDJq/f22puO3ANOp8cwzuVGRaalDToY7U1umNV1xrv70iyOL/ZRxYIgltV0a +ZlxZ1xLC4vRcfcczRI/N3+A9w/rBinvxw2d5GYYjRlpjw9xFU6YskbuG3XExus+C +F0WcJ0DMduSpFpCELuqnD2RuDQKd01IHajzkLuRcBrglUC49+IBNJVNtXkHu3TVH +OllgHFMp2GaD28uil50oQYYj89Ok7JNir17aUChGNmKVaEkheOiDgeLQKJRpRwu+ +fL4LJYdI2sXnxSUv2uO7qUAvdk5xX5L1QCe4keAF//T14iSt9q00MX+wRfsmP6WC +nhK7DJJwjN40RcyBrSU0IUe4oR+AIzWNVJRbb1QMA6mhKDICMGknOnKAgfjPYbhp +kw579C6MS4XxwvwyaZaUQy3loKfOwN7ahp+Hdzn9ojpzDH8WHdgl/UZjj8A6+xC0 +626exdhGm0HSbsIW5ZUa5CZfbwlgsmRDlzovymtJl6Qvqp0845m4H969wwOxM3yC +8NTUn2yNiZA1WBlM9hHvypU6l8M+cmvLd8aP2v54e47039f+dmeZfnF4N+7C59kA +YrUyiFmYQEZfNLQAJ4cnggLqQIkS39aYjNVDitw3xhQw9J5uaoMN819pSI4w9rp+ +20JqzRszH7dUVsIFsAwB8kc6eIuJun7sd9Z9a16vRzSP39mM4xMnjyTF0EUSG849 +7n7Kwwgi92aA+VgYCIYc4aKyBeElMTLMdCS2Zlwz3/mMEAiDn9xLE3i0anZ4AoYj +my1A9lmOB0Ms5F6NKc08riz8/ONerbqO6ArSDo1icrARWtzRsozarPdHTE29Aq9C +kHYQLJ1aCnUs/f3KLbJEjReXNFimR1L9jsxuof82PeJO9LUAsdUTmkfdh0Ya0gjl +jaYMdWm7bhoOjoFWPrhBfSlF5D7CCpiFyblio0SrE4FkCawDelhQG12HfcXi/UhF +Y10g/xnvK86ntus1Gmk/M8BLgKQq3EzWgYvlS/+fI8oNPIxZWyZjW71TAkvjxR8L +ctnh9rvCQtq38d0lQslZUvmgFZOdPK3y3H3KOZP7vldCW4giI8Dv9fgqqLK/crlT +WQWgtI0KIFtFeKreLupeMOFRW/cxdZ8Hr5cO8nJkQXGkc7H0Fm2b4IJl3g6h+iLe +qiw+aEFbNE0j80WV2skRoS+YhhaESoP+Q9S6O+o0g6M9hZpGszLGN7RgUScTq9oV +N0zMUJ1phrVR9q0DwIaxm9bnuswO/qpmkIOcO/w/eIx49HAwlzSf8em34laGJNBC +hofsGUNKy/8tNikiJClvZU9s4kwJKOHU/UlwTZyyqHewonFrqnuNxTWPcKe+3gP1 +sxTzLo9nqC1SsWIwn53UeAEJAhDorI7/L0xtmEijEyFL73ztomomHYQkCfh1i9+z +9z0pzPXAFv8mWqKhj/jWOlQoGSO+o3yOcsfCcHG0fRwrCi88Gqe1r5AcWEjlm3Ru +BfsI2CQsGk6vslxsAAUx5HMajVohSl+fb4ptpPoQi4UlafSJPCxJig== +=Cv77 +-----END PGP MESSAGE----- diff --git a/tests/openpgp/samplemsgs/pqc-sample-4.enc.asc b/tests/openpgp/samplemsgs/pqc-sample-4.enc.asc new file mode 100644 index 000000000..f083a1248 --- /dev/null +++ b/tests/openpgp/samplemsgs/pqc-sample-4.enc.asc @@ -0,0 +1,43 @@ +-----BEGIN PGP MESSAGE----- + +hQa7A/vNdqyZCOCUHQMDBGElA03HzQ06dUNguRZyQ2q17tO8kcuN7b0gxloxKTXC +oQSHg7r4wi0bvTG5j7wtgzIHxDZ5TCUelLXroMdseDgwCvvwf4kQRbxNeaFbb4hd +uPTz5HqOaOal5mi6jPRknAAABiCFleLITElzivvWup6puUk5Pt+FO2riLA6ckeIq +iW3yYOLxK5jFBT+yFceBAFP7PCZgQJxQ3n907ky4uHqJhgw+PQfSY9pcsyOu/1Co +t2kHUS5R9RcYFYnoEKnZFCvDiToJ5ZBvj5pfDl5fhm/tUPkjxC+rFXVYu4LqNH72 +OFQjOPlpwgSIszemGpzXjakfwX6lT8Y0dyFqH7I12SDOKo8/5XzBRMHDrkItqAC1 +s1YSyXsxrsFFvVZ85H00xwLMUfPfSt0berVcu8TFq2+mQfAnr7VsE4FsCRo3PMWw +tp98p/js5FSsE9w5LsfTDHc9A/T5B8br5+tbJKgkrLo+VK+aZkx7Crs/ibTbhbEA +8nAO8oJ0eA2Xgtrz4KIMmuFTGmqn2VWjuWaVTAy74yi+cDdAsohi0IZIb6MSoLuY +wcuG529PFocpolnHJFb7P2aPyywdxlaS6paQpVjzv7mXumvaUal8ySO9RcKDH5TG +vw+ZpXa4OJPYuiCmQJijzyjPI5vGqDirB61ijf0QicSJjK/+k3xN8EUunr5/VenI +9AGYVaw9CwP3G6Bt9Vm9IvhgmBwsmszUKNO+RVfDLeP1ygPoZaDQ4uXtNP/heZ/5 +NyWP11aoWslUPJiYZgp83rxfJNMhQTAsW5MizpD9fDlS/ERB8B1E3R2NTx7Zm/WT +4Yp/dhzXhiLhoQRsNG5k4hOHhebHl86V1bXxN1CuPs+m04Jt4a+6FgGIdujJ2L5y +XWgRifxVUC/vjyFSyxJHgNeYFpcRKpKz4I76qfC3x0SfGOW8DTRSSMX0jm/SoBZL +a21agps3DUogs2SPJ+cyNtwsxMKoSiADwqsR0sfx4dGvoKPA6YKU9RHi1PJp4RzF +13Cv+1sTVxGQaUFU3Z668bnk9V64oOe5Pbx+brjaERf4S/616yqlvZFYsiR94BDv +wknr6Z0MZ7Ldv7MVYsq9eLi+ubrjesxUIzdyWVdDQhgsH5akvo166gHN9aNBCj9z +aJtrUvz/gYDC9uidQSLY0P2rxlYwT1tZ7/cEMDuRzBA0HnukpLLrheNne7+bvLhl +vzjtwWFpTrUObwym/AEWHwycxyFsSUlNL82TBd7jrp/dm12Q73rdzmcn3pK/oRrr +Cwq/yxtiNyPRFx3VyfnvIJp6nkSEZniTIaI0pYlSet3KbIqInM7m8PvZHS+Yk0dV +qwn09ZdNlXhvuLcoJoQH5tE4KpG1Q4LZVwWVo6iPjkceDXapElsyc9eRuDGzZn91 +duBUCsburQyl2psCWkP6CIB7qkI7cEknSj7qLIDVQ6GA2SooZt3iX3p8+M0pJxx2 +OdiBzufreUidS5hdVl1VGjEpibdQVP6xyEokTt+hQSxt33ZFJVPlIPbuN0Hf8Ze3 +kSo4IKhHIBsObxULAa0dEH0qJ85Tsx8ZSHXcnHROUET/koa8Sd12DnFeSZDhHqd+ +efv5Go6XxqDqXcvmYfO5UbentNRoov29BrItYK1KLZI2yxH5aOfmIqwY0ZdRKknI +DLsTummH+fTcsQkImaJ/1lWnQ9PhjDXDQybRJ1kvri+37eg7tsBE3lqOpcbSyDXA +guWLrt37ufGY4dgSea2sCb7MBWjU7JgrqVjrq6sokmiXEJn0Ld2UFDwitkSTnXGJ +xl3MLzPy0xYtNynk7gsgKAZm7YKCqtCPLNXF5h7CBlZM+kedms51t4a/Ng9E27gB +PfuLrgIwbchrLt2NwtKckYczQMskoz5KTRfBweN9H+Uk8Pryb2bdC8V76GKdAG7x +qBF8d+AqE5miCIMrWuhhmx2J4w55PGrSC3Qgee+BdKjlS24DEaApAFIVTWlFvqmi +hRcFQtZXwGPBQcvlj0bSSps6GGoZN+WkEv1vBjeWTLAMxcnOskWUvmnFIO4HoM3V +fD2k4OedR71UdJLBJ/Ql+3dp/LeBbFGjCnNNI3s2+whYdrPb1AkJQkvjZCUSpikA +LauqXXdNzTtWmu691Wm8MMekHIB2v8Px1xsieoTv9zTiEy4Zil0szsTgrFPtl7fn +0Sru5FE8vcjR24UDUWRcKyYANLRyqFUPpBnIfKu3h12s1o5WW5ZHyj3x//2EpWnL +OcLlzgkoxLwWQrq4DbM1mupY/MwGRAdkSVtLjgTGZAlTRWBo0oPmUi+bP/Mc8dRs +AQkCEEE0J1X8U7mB0Y4ovh04SLU/DvVDaqwjTEktsZoa4zJ6a+TpTcQAZLR2yRxM +NYLUZPuJikov/9A/nx3ujQsGipXdjIyLTpr0RhxFOBlm5vV0+O5a/zR9vM8q7QHF +se4uGUbzOJfEhVQ7 +=rlF7 +-----END PGP MESSAGE----- diff --git a/tests/openpgp/samplemsgs/pqc-sample-5.enc.asc b/tests/openpgp/samplemsgs/pqc-sample-5.enc.asc new file mode 100644 index 000000000..eb20f9791 --- /dev/null +++ b/tests/openpgp/samplemsgs/pqc-sample-5.enc.asc @@ -0,0 +1,45 @@ +-----BEGIN PGP MESSAGE----- + +hQbbA8pEte1D0zKQHQQDBD2VswlYqdsXhS8MJSsUJ6Hmg0uyG0Ovz8Tkifmqkq43 +Tkc/i1RXTb6JPmBsEipfJ7kjmHG7FrQphfMfAU7fdaU1LC2c0cHADw96f2dgQ3qS +c0YsFLzpJDu+t9KPnGyHGDSZvNmTfNM15WoGqyQQvAefuvkJB4e5x7GYmD8a/a21 +AAAGIFGuzK90gQgSBR5LxVwmtc3oM22nKb6MTooMs+IG+SFXB2vIZDUaYO7qdPrv +NhUH584QCPbrUSk7FcPddHSwdK5+ZG5UG+aYqzDfhyGImyuMwuCMzUpVNX46ENSp +LWu0ZQiixmasjZYf0JfiNbW2KLhDMjmwuLSKK9Q/J8yfgIsqKD8NSr0mESkuA/wr +jXXhyouZzIgC0l7iNsKdWzUrjvSptA+a/nyOjnVHFrvfW58SmgRMuw4Oju4DbR3o +4u0RtKC94f599BfDnpozsHVaDqbcMI92aESDiOIiXC1QLS1I4moasAaL2r43c7cK +rmlEoqtNP2vDcjYeHopwkzJPchXBT2r0k0+1ncUUCpIiKfdv4jkb02prT8pU6e7R +D6IkGlxFZ5yMkjvZdIUxdVdSzhCJHdIcQTltx5HVtpZcdFcjYHR5yW/5r5T8wBg6 +M1a5ZAVryuJivQCszOvSDEeTQ60/yLPl2FtpuN4zLRw2+Pg6VeYYf96dYO4ez8eY +fLuNlZiljmKcl94vf5eLCf4qIGcKKn7Tse3Rk2sCX9kib9AsJ/8sQCqg09KtMHF2 +YY6PyiMMyxiDXV3Gr5IXgd0gWly1b2dTVcxrlOebCWgC+oQmhU7weCME09TDOJrT +QxZVFtIY0gyZQBLIjnoEX1ta49VAHk0JFfKywHWNfzWh11/rY6rbacD5kto9H8ga +4ox9WsG1Wlkpi6eyFIzc/mcPLkzdK5Z4GKIc+rz6OXUpypUBsbcNpihYmi84vdbv +SFxwabc7GRumcAbyGsn5Tfc1ByQ+iZlQFl1moYgOq3aRbvWzgQ18QPsDprlfeOL1 ++YVSq4/EemzEntnfpk63RtoK0gJpLTy5V8wVwqJ5hzvTYYk9i9U72IuAp9uYYnNj +OlkGU4UYk3RR0qFt092zjXIkPEg+7CvnOdSEtFMhJvrSn0Du4X87c63rypF+Tr41 +mW2v1AE4Zpr3hJCf+d02X9RCSEiGMJwLUGk/uYNtwYfSyNldJI25xwHQizhcgHSV +mA0NEdvAWuMbzu9q2GOvCATofd9G1NXQ+bHYlDh+JRP0DZpyBSefRsNg2YwByUDG +XVlugx6mP5OiRUVMI4zOfCAsvaQ+qaKgccD2wJabhcbJBCW2L0WsnrW+0Tebac9S +tCOxfIpxxGCSiRz02Hw7auqoQwOq47f1uuKH0zZ2WuRO75IIF4/D+/tm5Ba+6Iz5 +L811hIUTvDesXFO7O4EXB8TAh5dLqEWTqCR8D6mmT+KWGf/9VEAJ8KzELdKgdMC4 +LOuVDce3SWXp+S692RxrPJrUMsNDbYJpeFkTR+6gpQqDDpQybdvXJgRaTsb0Sull +UtmjgkOZAFrZ5Go6wcNvK3KCP6136oStM/4kEJvdL0qpN/u2G6kgmG+VCvwjPCng +dRMqO2F5Coj5LbviRwFsHPdf2WgDuOeq+KmDIcryKFR+7s7r/98m7oOYpJDXQDpO +xIki9Y+Aou/8v389g7lWoFqKLPzYGJbVo+1i4tMFlQ4WJ8IJVomRhFJP5xEWHzY5 +3JsDTG6077ftm7wSfx4p3P3sTtjZRo+dnuvsHPeKjLvUCdjLveCls97DMu9enk01 +sZxCVO4anSBzrWWe/dNPFHvV+le+/2tF+wDIk8xJIZKqQn9O26Edm/E7M0VldtHS +nbq0IMNjID3tSDevLFN4HSvEKAZpNsTS4f1Z/DuQndGVUBEgStPF6/iBOKcfZ7Eo +dqA4/o0nhBPmw7/EhZJ9TQgS0hH//PlfXteMpVxsHh3O0B8gIgAxbgJsn8JO8Owd +6OCzq3TQfwE3bS7dgyAzLZ5E03ZmVwnQ7GBSLvpYCi3S4S33Ki4qsqSVm23yYo9n +FzE8iVcIvWzkHhvvWf32cv27cbbtdrVXKXtCuYw1gxe47ilGkP2GWUhShJKv5rrS +MMkIctimmDaAApNFnIjZNIzGTmBkMxpkaVWIKL8lofOFlcuB9pl6l3hEUto8MB+7 +SVmzBnGFJwkvjnbIKDxB7myo882x+BBDgp4niECLyWfUuGk0q1x0lYNL7Njya8x/ +Sbtolk1l0BP4z/seUAwxKQyZAtOh55X0V1jPsdnwLzWMLMvbCSgAuu11jblp33oF +eWKn7tHsKmS2EMoas1AnEVW63Xt8meBXrzKeZV6X1K0BCQIQzhAKL6eK3Er01f1M +SWatf3nuMir/gpVxHelc5KE8CiLso+4+LxoTjsfMU+usFCJCP296eEOeE0e+tJ5g +mQp5WQNloshZPeyKknYYOnb4k8LZL5rwuB4kXCrJaARp0Wvatt3jtTccYk2bjo91 +Q1vjARFTcW45x5vD3tH55CBaWrveU08iZA4Dn95rWpoRi5q5JxV/DSHugSG1uYBP +MQHiPA1Y6KsYPhsQYg== +=aAoH +-----END PGP MESSAGE----- From ab703eacf73e5e1ae16d13558b32ac22a29f8536 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Apr 2024 20:12:57 +0200 Subject: [PATCH 459/869] gpg: Split keygrip in a standard key listing. * g10/keylist.c (print_keygrip): New. (list_keyblock_print): Use new function to print the keygrip. --- g10/keylist.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/g10/keylist.c b/g10/keylist.c index 7717ca563..c6667936d 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1171,6 +1171,19 @@ dump_attribs (const PKT_user_id *uid, PKT_public_key *pk) } +static void +print_keygrip (const char *keygrip) +{ + const char *s; + + s = strchr (keygrip, ','); + if (s) + es_fprintf (es_stdout, " Keygrip = %.*s,\n%*s%s\n", + (int)(s-keygrip), keygrip, 16, "", s+1); + else + es_fprintf (es_stdout, " Keygrip = %s\n", keygrip); +} + /* If PK is given the output is written to a new file instead of * stdout. */ @@ -1513,7 +1526,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, print_fingerprint (ctrl, NULL, pk, 0); if (opt.with_keygrip && hexgrip) - es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip); + print_keygrip (hexgrip); if (serialno) print_card_serialno (serialno); @@ -1670,7 +1683,7 @@ list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr, print_card_serialno (serialno); } if (opt.with_keygrip && hexgrip) - es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip); + print_keygrip (hexgrip); if (opt.with_key_data) print_key_data (pk2); if (opt.with_key_screening) From d1f8caafb4e71f07d7c6238732732d6d2aa5624d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 24 Apr 2024 14:01:41 +0900 Subject: [PATCH 460/869] agent: Simplify diverting operation to the smartcard. * agent/pkdecrypt.c (agent_pkdecrypt): Remove no_shadow_info variable. -- Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 5509b1169..ef1280739 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -116,7 +116,6 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL; unsigned char *shadow_info = NULL; gpg_error_t err = 0; - int no_shadow_info = 0; char *buf = NULL; size_t len; @@ -145,17 +144,13 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, err = agent_key_from_file (ctrl, NULL, desc_text, NULL, &shadow_info, CACHE_MODE_NORMAL, NULL, &s_skey, NULL, NULL); - if (gpg_err_code (err) == GPG_ERR_NO_SECKEY) - no_shadow_info = 1; - else if (err) + if (err && gpg_err_code (err) != GPG_ERR_NO_SECKEY) { log_error ("failed to read the secret key\n"); - goto leave; } - - if (shadow_info || no_shadow_info) + else if (shadow_info + || err /* gpg_err_code (err) == GPG_ERR_NO_SECKEY */) { /* divert operation to the smartcard */ - if (!gcry_sexp_canon_len (ciphertext, ciphertextlen, NULL, NULL)) { err = gpg_error (GPG_ERR_INV_SEXP); @@ -170,12 +165,12 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, &buf, &len, r_padding); if (err) { - /* We restore the original error (ie. no seckey) is no card + /* We restore the original error (ie. no seckey) as no card * has been found and we have no shadow key. This avoids a * surprising "card removed" error code. */ if ((gpg_err_code (err) == GPG_ERR_CARD_REMOVED || gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT) - && no_shadow_info) + && !shadow_info) err = gpg_error (GPG_ERR_NO_SECKEY); else log_error ("smartcard decryption failed: %s\n", gpg_strerror (err)); From a45243548ed39f91cc6d87804d17c110e3150725 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 24 Apr 2024 15:08:41 +0900 Subject: [PATCH 461/869] agent:kem: Factor out ECC KEM operation from composite KEM. * agent/pkdecrypt.c (ecc_pgp_kem_decrypt): New. (composite_pgp_kem_decrypt): Use ecc_pgp_kem_decrypt. -- Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 243 ++++++++++++++++++++++++++-------------------- 1 file changed, 136 insertions(+), 107 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index ef1280739..cfb268190 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -244,26 +244,11 @@ reverse_buffer (unsigned char *buffer, unsigned int length) } -/* For composite PGP KEM (ECC+ML-KEM), decrypt CIPHERTEXT using KEM API. - First keygrip is for ECC, second keygrip is for PQC. CIPHERTEXT - should follow the format of: - - (enc-val(pqc(c%d)(e%m)(k%m)(s%m)(fixed-info&))) - c: cipher identifier (symmetric) - e: ECDH ciphertext - k: ML-KEM ciphertext - s: encrypted session key - fixed-info: A buffer with the fixed info. - - FIXME: For now, possible keys on smartcard are not supported. - */ static gpg_error_t -composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, - gcry_sexp_t s_cipher, membuf_t *outbuf) +ecc_pgp_kem_decrypt (ctrl_t ctrl, gcry_sexp_t s_skey0, + const unsigned char *ecc_ct, size_t ecc_ct_len, + unsigned char *ecc_ss, size_t *r_shared_len, size_t *r_point_len) { - gcry_sexp_t s_skey0 = NULL; - gcry_sexp_t s_skey1 = NULL; - unsigned char *shadow_info = NULL; gpg_error_t err = 0; const struct ecc_params *ecc; @@ -271,92 +256,23 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *p; size_t len; - int algo; - gcry_mpi_t encrypted_sessionkey_mpi = NULL; - const unsigned char *encrypted_sessionkey; - size_t encrypted_sessionkey_len; - gcry_mpi_t ecc_sk_mpi = NULL; unsigned char ecc_sk[ECC_SCALAR_LEN_MAX]; gcry_mpi_t ecc_pk_mpi = NULL; unsigned char ecc_pk[ECC_POINT_LEN_MAX]; - gcry_mpi_t ecc_ct_mpi = NULL; - const unsigned char *ecc_ct; unsigned char ecc_ecdh[ECC_POINT_LEN_MAX]; - unsigned char ecc_ss[ECC_HASH_LEN_MAX]; - - enum gcry_kem_algos mlkem_kem_algo; - gcry_mpi_t mlkem_sk_mpi = NULL; - gcry_mpi_t mlkem_ct_mpi = NULL; - const unsigned char *mlkem_sk; - size_t mlkem_sk_len; - const unsigned char *mlkem_ct; - size_t mlkem_ct_len; - unsigned char mlkem_ss[GCRY_KEM_MLKEM1024_SHARED_LEN]; - size_t mlkem_ss_len; - - unsigned char kek[32]; - size_t kek_len = 32; /* AES-256 is mandatory */ - - gcry_cipher_hd_t hd; - unsigned char sessionkey[256]; - size_t sessionkey_len; - gcry_buffer_t fixed_info = { 0, 0, 0, NULL }; gcry_sexp_t curve = NULL; char *curve_name = NULL; - err = agent_key_from_file (ctrl, NULL, desc_text, - ctrl->keygrip, &shadow_info, - CACHE_MODE_NORMAL, NULL, &s_skey0, NULL, NULL); - if (err) - { - log_error ("failed to read the secret key\n"); - goto leave; - } + (void)ctrl; - err = agent_key_from_file (ctrl, NULL, desc_text, - ctrl->keygrip1, &shadow_info, - CACHE_MODE_NORMAL, NULL, &s_skey1, NULL, NULL); - if (err) - { - log_error ("failed to read the another secret key\n"); - goto leave; - } - - /* Here assumes no smartcard, but private keys */ - - err = gcry_sexp_extract_param (s_cipher, NULL, "%dc/eks&'fixed-info'", - &algo, &ecc_ct_mpi, &mlkem_ct_mpi, - &encrypted_sessionkey_mpi, &fixed_info, NULL); - if (err) - { - if (opt.verbose) - log_info ("%s: extracting parameters failed\n", __func__); - goto leave; - } - - len = gcry_cipher_get_algo_keylen (algo); - encrypted_sessionkey = gcry_mpi_get_opaque (encrypted_sessionkey_mpi, &nbits); - encrypted_sessionkey_len = (nbits+7)/8; - if (len == 0 || encrypted_sessionkey_len != len + 8) - { - if (opt.verbose) - log_info ("%s: encrypted session key length %zu" - " does not match the length for algo %d\n", - __func__, encrypted_sessionkey_len, algo); - err = gpg_error (GPG_ERR_INV_DATA); - goto leave; - } - - /* Firstly, ECC part. */ curve = gcry_sexp_find_token (s_skey0, "curve", 0); if (!curve) { if (opt.verbose) log_info ("%s: no curve given\n", __func__); - err = gpg_error (GPG_ERR_BAD_SECKEY); - goto leave; + return gpg_error (GPG_ERR_BAD_SECKEY); } curve_name = gcry_sexp_nth_string (curve, 1); @@ -369,6 +285,18 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, goto leave; } + *r_shared_len = ecc->shared_len; + *r_point_len = ecc->point_len; + + if (ecc->point_len != ecc_ct_len) + { + if (opt.verbose) + log_info ("%s: ECC cipher text length invalid (%zu)\n", + __func__, ecc->point_len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + err = gcry_sexp_extract_param (s_skey0, NULL, "/qd", &ecc_pk_mpi, &ecc_sk_mpi, NULL); if (err) @@ -417,16 +345,6 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, mpi_release (ecc_sk_mpi); ecc_sk_mpi = NULL; - ecc_ct = gcry_mpi_get_opaque (ecc_ct_mpi, &nbits); - if (ecc->point_len != (nbits+7)/8) - { - if (opt.verbose) - log_info ("%s: ECC cipher text length invalid (%zu)\n", - __func__, ecc->point_len); - err = gpg_error (GPG_ERR_INV_DATA); - goto leave; - } - if (DBG_CRYPTO) { log_debug ("ECC curve: %s\n", curve_name); @@ -460,6 +378,123 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, if (DBG_CRYPTO) log_printhex (ecc_ss, ecc->shared_len, "ECC shared:"); + leave: + wipememory (ecc_sk, sizeof ecc_sk); + wipememory (ecc_ecdh, sizeof ecc_ecdh); + + mpi_release (ecc_pk_mpi); + mpi_release (ecc_sk_mpi); + xfree (curve_name); + gcry_sexp_release (curve); + return err; +} + +/* For composite PGP KEM (ECC+ML-KEM), decrypt CIPHERTEXT using KEM API. + First keygrip is for ECC, second keygrip is for PQC. CIPHERTEXT + should follow the format of: + + (enc-val(pqc(c%d)(e%m)(k%m)(s%m)(fixed-info&))) + c: cipher identifier (symmetric) + e: ECDH ciphertext + k: ML-KEM ciphertext + s: encrypted session key + fixed-info: A buffer with the fixed info. + + FIXME: For now, possible keys on smartcard are not supported. + */ +static gpg_error_t +composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, + gcry_sexp_t s_cipher, membuf_t *outbuf) +{ + gcry_sexp_t s_skey0 = NULL; + gcry_sexp_t s_skey1 = NULL; + unsigned char *shadow_info = NULL; + gpg_error_t err = 0; + + unsigned int nbits; + size_t len; + + int algo; + gcry_mpi_t encrypted_sessionkey_mpi = NULL; + const unsigned char *encrypted_sessionkey; + size_t encrypted_sessionkey_len; + + gcry_mpi_t ecc_ct_mpi = NULL; + const unsigned char *ecc_ct; + size_t ecc_ct_len; + unsigned char ecc_ss[ECC_HASH_LEN_MAX]; + size_t ecc_shared_len, ecc_point_len; + + enum gcry_kem_algos mlkem_kem_algo; + gcry_mpi_t mlkem_sk_mpi = NULL; + gcry_mpi_t mlkem_ct_mpi = NULL; + const unsigned char *mlkem_sk; + size_t mlkem_sk_len; + const unsigned char *mlkem_ct; + size_t mlkem_ct_len; + unsigned char mlkem_ss[GCRY_KEM_MLKEM1024_SHARED_LEN]; + size_t mlkem_ss_len; + + unsigned char kek[32]; + size_t kek_len = 32; /* AES-256 is mandatory */ + + gcry_cipher_hd_t hd; + unsigned char sessionkey[256]; + size_t sessionkey_len; + gcry_buffer_t fixed_info = { 0, 0, 0, NULL }; + + err = agent_key_from_file (ctrl, NULL, desc_text, + ctrl->keygrip, &shadow_info, + CACHE_MODE_NORMAL, NULL, &s_skey0, NULL, NULL); + if (err) + { + log_error ("failed to read the secret key\n"); + goto leave; + } + + err = agent_key_from_file (ctrl, NULL, desc_text, + ctrl->keygrip1, &shadow_info, + CACHE_MODE_NORMAL, NULL, &s_skey1, NULL, NULL); + if (err) + { + log_error ("failed to read the another secret key\n"); + goto leave; + } + + /* Here assumes no smartcard, but private keys */ + + err = gcry_sexp_extract_param (s_cipher, NULL, "%dc/eks&'fixed-info'", + &algo, &ecc_ct_mpi, &mlkem_ct_mpi, + &encrypted_sessionkey_mpi, &fixed_info, NULL); + if (err) + { + if (opt.verbose) + log_info ("%s: extracting parameters failed\n", __func__); + goto leave; + } + + ecc_ct = gcry_mpi_get_opaque (ecc_ct_mpi, &nbits); + ecc_ct_len = (nbits+7)/8; + + len = gcry_cipher_get_algo_keylen (algo); + encrypted_sessionkey = gcry_mpi_get_opaque (encrypted_sessionkey_mpi, &nbits); + encrypted_sessionkey_len = (nbits+7)/8; + if (len == 0 || encrypted_sessionkey_len != len + 8) + { + if (opt.verbose) + log_info ("%s: encrypted session key length %zu" + " does not match the length for algo %d\n", + __func__, encrypted_sessionkey_len, algo); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; + } + + /* Firstly, ECC part. */ + err = ecc_pgp_kem_decrypt (ctrl, s_skey0, ecc_ct, ecc_ct_len, + ecc_ss, &ecc_shared_len, &ecc_point_len); + if (err) + goto leave; + /* Secondly, PQC part. For now, we assume ML-KEM. */ err = gcry_sexp_extract_param (s_skey1, NULL, "/s", &mlkem_sk_mpi, NULL); if (err) @@ -521,7 +556,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, /* Then, combine two shared secrets and ciphertexts into one KEK */ err = gnupg_kem_combiner (kek, kek_len, - ecc_ss, ecc->shared_len, ecc_ct, ecc->point_len, + ecc_ss, ecc_shared_len, ecc_ct, ecc_point_len, mlkem_ss, mlkem_ss_len, mlkem_ct, mlkem_ct_len, fixed_info.data, fixed_info.size); if (err) @@ -573,22 +608,16 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, put_membuf (outbuf, ")", 2); leave: - wipememory (ecc_sk, sizeof ecc_sk); - wipememory (ecc_ecdh, sizeof ecc_ecdh); wipememory (ecc_ss, sizeof ecc_ss); wipememory (mlkem_ss, sizeof mlkem_ss); wipememory (kek, sizeof kek); wipememory (sessionkey, sizeof sessionkey); - mpi_release (mlkem_sk_mpi); - mpi_release (ecc_pk_mpi); - mpi_release (ecc_sk_mpi); mpi_release (ecc_ct_mpi); + mpi_release (mlkem_sk_mpi); mpi_release (mlkem_ct_mpi); mpi_release (encrypted_sessionkey_mpi); gcry_free (fixed_info.data); - gcry_sexp_release (curve); - xfree (curve_name); gcry_sexp_release (s_skey0); gcry_sexp_release (s_skey1); return err; From 2958e5e4cfff8e7e8a8a113dca65dec028deb5aa Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Apr 2024 09:56:30 +0200 Subject: [PATCH 462/869] gpg: New option --require-pqc-encryption * g10/gpg.c (oRequirePQCEncryption): New. (opts): Add option. (main): Set option. * g10/mainproc.c (print_pkenc_list): Print a warning. * g10/options.h (flags): Add flag require_pqc_encryption. * g10/getkey.c (finish_lookup): Skip non-pqc keys if the option is set. -- GnuPG-bug-id: 6815 --- doc/gpg.texi | 9 +++++++++ g10/getkey.c | 17 +++++++++++++++++ g10/gpg.c | 6 +++++- g10/mainproc.c | 4 ++++ g10/options.h | 1 + 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/doc/gpg.texi b/doc/gpg.texi index 10a1937f6..446189b4b 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -3146,6 +3146,15 @@ This option adjusts the compliance mode "de-vs" for stricter key size requirements. For example, a value of 3000 turns rsa2048 and dsa2048 keys into non-VS-NfD compliant keys. +@item --require-pqc-encryption +@opindex require-pqc-encryption +This option forces the use of quantum-resistant encryption algorithms. +If not all public keys are quantum-resistant the encryption will fail. +On decryption a warning is printed for all non-quantum-resistant keys. +As of now the Kyber (ML-KEM768 and ML-KEM1024) algorithms are +considered quantum-resistant; Kyber is always used in a composite +scheme along with a classic ECC algorithm. + @item --require-compliance @opindex require-compliance To check that data has been encrypted according to the rules of the diff --git a/g10/getkey.c b/g10/getkey.c index ce59628a0..f2d1e7d7b 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -3779,6 +3779,16 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, continue; } + if (opt.flags.require_pqc_encryption + && (req_usage & PUBKEY_USAGE_ENC) + && pk->pubkey_algo != PUBKEY_ALGO_KYBER) + { + if (DBG_LOOKUP) + log_debug ("\tsubkey is not quantum-resistant\n"); + continue; + } + + if (want_secret) { int secret_key_avail = agent_probe_secret_key (NULL, pk); @@ -3857,6 +3867,13 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact, if (DBG_LOOKUP) log_debug ("\tprimary key has expired\n"); } + else if (opt.flags.require_pqc_encryption + && (req_usage & PUBKEY_USAGE_ENC) + && pk->pubkey_algo != PUBKEY_ALGO_KYBER) + { + if (DBG_LOOKUP) + log_debug ("\tprimary key is not quantum-resistant\n"); + } else /* Okay. */ { if (DBG_LOOKUP) diff --git a/g10/gpg.c b/g10/gpg.c index 658fb7cf1..82745fa18 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -456,6 +456,7 @@ enum cmd_and_opt_values oAssertSigner, oAssertPubkeyAlgo, oKbxBufferSize, + oRequirePQCEncryption, oNoop }; @@ -896,7 +897,7 @@ static gpgrt_opt_t opts[] = { ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"), ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"), ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"), - + ARGPARSE_s_n (oRequirePQCEncryption, "require-pqc-encryption", "@"), ARGPARSE_header (NULL, N_("Options for unattended use")), @@ -3071,6 +3072,9 @@ main (int argc, char **argv) break; case oMinRSALength: opt.min_rsa_length = pargs.r.ret_ulong; break; + case oRequirePQCEncryption: + opt.flags.require_pqc_encryption = 1; + break; case oRFC2440Text: opt.rfc2440_text=1; break; case oNoRFC2440Text: opt.rfc2440_text=0; break; diff --git a/g10/mainproc.c b/g10/mainproc.c index 48bc463c5..91ababbb6 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -578,6 +578,10 @@ print_pkenc_list (ctrl_t ctrl, struct pubkey_enc_list *list) openpgp_pk_algo_name (list->pubkey_algo), keystr(list->keyid)); + if (opt.flags.require_pqc_encryption + && pk->pubkey_algo != PUBKEY_ALGO_KYBER) + log_info (_("WARNING: key is not quantum-resistant\n")); + free_public_key (pk); } } diff --git a/g10/options.h b/g10/options.h index 2fe4f5bbf..ae429fcc1 100644 --- a/g10/options.h +++ b/g10/options.h @@ -283,6 +283,7 @@ struct /* Fail if an operation can't be done in the requested compliance * mode. */ unsigned int require_compliance:1; + unsigned int require_pqc_encryption:1; } flags; /* Linked list of ways to find a key if the key isn't on the local From 2593dcbcebbe55d7ab43f7ac67af08cedd0ab40c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 25 Apr 2024 10:48:24 +0900 Subject: [PATCH 463/869] agent: Allow NULL for R_PADDING, when calling scd and tpm2d. * agent/call-scd.c (padding_info_cb): Allow NULL. (agent_card_pkdecrypt): Likewise. * agent/divert-scd.c (divert_pkdecrypt): Likewise. * agent/divert-tpm2.c (divert_tpm2_pkdecrypt): Likewise. -- It's for RSA PKCD#1 encoding if the decrypt operation removes padding or not. When caller knows it's not RSA, this information is no use and it is better to allow NULL with the variable R_PADDING. Signed-off-by: NIIBE Yutaka --- agent/call-scd.c | 10 ++++++---- agent/divert-scd.c | 5 +++-- agent/divert-tpm2.c | 6 ++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/agent/call-scd.c b/agent/call-scd.c index 91e28e68c..3da16e619 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -548,7 +548,8 @@ padding_info_cb (void *opaque, const char *line) if ((s=has_leading_keyword (line, "PADDING"))) { - *r_padding = atoi (s); + if (r_padding) + *r_padding = atoi (s); } else if ((s=has_leading_keyword (line, "PINCACHE_PUT"))) err = handle_pincache_put (s); @@ -560,8 +561,8 @@ padding_info_cb (void *opaque, const char *line) /* Decipher INDATA using the current card. Note that the returned * value is not an s-expression but the raw data as returned by * scdaemon. The padding information is stored at R_PADDING with -1 - * for not known. DESC_TEXT is an additional parameter passed to - * GETPIN_CB. */ + * for not known, when it's not NULL. DESC_TEXT is an additional + * parameter passed to GETPIN_CB. */ int agent_card_pkdecrypt (ctrl_t ctrl, const char *keyid, @@ -579,7 +580,8 @@ agent_card_pkdecrypt (ctrl_t ctrl, size_t len; *r_buf = NULL; - *r_padding = -1; /* Unknown. */ + if (r_padding) + *r_padding = -1; /* Unknown. */ rc = start_scd (ctrl); if (rc) return rc; diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 4a2bebffa..d7454d968 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -380,7 +380,7 @@ divert_pksign (ctrl_t ctrl, const unsigned char *grip, /* Decrypt the value given as an s-expression in CIPHER using the key identified by SHADOW_INFO and return the plaintext in an allocated buffer in R_BUF. The padding information is stored at - R_PADDING with -1 for not known. */ + R_PADDING with -1 for not known, when it's not NULL. */ int divert_pkdecrypt (ctrl_t ctrl, const unsigned char *grip, @@ -399,7 +399,8 @@ divert_pkdecrypt (ctrl_t ctrl, bin2hex (grip, 20, hexgrip); - *r_padding = -1; + if (r_padding) + *r_padding = -1; s = cipher; if (*s != '(') return gpg_error (GPG_ERR_INV_SEXP); diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c index 2496d091a..6ebb9ef78 100644 --- a/agent/divert-tpm2.c +++ b/agent/divert-tpm2.c @@ -106,7 +106,8 @@ divert_tpm2_pkdecrypt (ctrl_t ctrl, const unsigned char *s; size_t n; - *r_padding = -1; + if (r_padding) + *r_padding = -1; s = cipher; if (*s != '(') @@ -125,7 +126,8 @@ divert_tpm2_pkdecrypt (ctrl_t ctrl, return gpg_error (GPG_ERR_INV_SEXP); if (smatch (&s, n, "rsa")) { - *r_padding = 0; + if (r_padding) + *r_padding = 0; if (*s != '(') return gpg_error (GPG_ERR_UNKNOWN_SEXP); s++; From 02b056ef777c09acf13eb7706af23053e32e7b04 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 25 Apr 2024 13:51:47 +0900 Subject: [PATCH 464/869] agent:kem: Fix memory leaks. * agent/pkdecrypt.c (composite_pgp_kem_decrypt): Release shadow_info memory. -- Signed-off-by: NIIBE Yutaka --- agent/pkdecrypt.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index cfb268190..6e466154d 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -408,7 +408,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, { gcry_sexp_t s_skey0 = NULL; gcry_sexp_t s_skey1 = NULL; - unsigned char *shadow_info = NULL; + unsigned char *shadow_info0 = NULL; + unsigned char *shadow_info1 = NULL; gpg_error_t err = 0; unsigned int nbits; @@ -444,7 +445,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_buffer_t fixed_info = { 0, 0, 0, NULL }; err = agent_key_from_file (ctrl, NULL, desc_text, - ctrl->keygrip, &shadow_info, + ctrl->keygrip, &shadow_info0, CACHE_MODE_NORMAL, NULL, &s_skey0, NULL, NULL); if (err) { @@ -453,7 +454,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, } err = agent_key_from_file (ctrl, NULL, desc_text, - ctrl->keygrip1, &shadow_info, + ctrl->keygrip1, &shadow_info1, CACHE_MODE_NORMAL, NULL, &s_skey1, NULL, NULL); if (err) { @@ -620,6 +621,8 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, gcry_free (fixed_info.data); gcry_sexp_release (s_skey0); gcry_sexp_release (s_skey1); + xfree (shadow_info0); + xfree (shadow_info1); return err; } From d3b41e76119c0ecad6671ceaa6d06dbd0d710f8d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Apr 2024 10:59:14 +0200 Subject: [PATCH 465/869] Install the new gpg-authcode-sign.sh script. * tools/gpg-authcode-sign.sh: New. * tools/Makefile.am (bin_SCRIPTS): Add that tool. -- This script makes use of gpg anyway and thus it is best to have it also installed with the gpg version used to cross-build our software. The script was orginally developed for gpg4win. --- tools/Makefile.am | 1 + tools/gpg-authcode-sign.sh | 257 +++++++++++++++++++++++++++++++++++++ 2 files changed, 258 insertions(+) create mode 100644 tools/gpg-authcode-sign.sh diff --git a/tools/Makefile.am b/tools/Makefile.am index 769a81a00..822c42a4f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -54,6 +54,7 @@ endif AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS) sbin_SCRIPTS = addgnupghome applygnupgdefaults +bin_SCRIPTS = gpg-authcode-sign.sh if BUILD_WKS_TOOLS gpg_wks_server = gpg-wks-server diff --git a/tools/gpg-authcode-sign.sh b/tools/gpg-authcode-sign.sh new file mode 100644 index 000000000..0f6a34824 --- /dev/null +++ b/tools/gpg-authcode-sign.sh @@ -0,0 +1,257 @@ +#!/bin/sh +# gpg-authcode-sign.sh - Wrapper for osslsigncode +# Copyright (C) 2024 g10 Code GmbH +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +VERSION=2024-03-25 +PGM=gpg-authcode-sign.sh + +set -e + +usage() +{ + cat <&2 + ;; + *) + break + ;; + esac + shift +done + +if [ $# -ne 2 ]; then + usage 1 1>&2 +fi +inname="$1" +outname="$2" +shift + +if [ ! -f $autogenrc ]; then + echo >&2 "$PGM: error: '$autogenrc' missing" + echo >&2 "$PGM: hint: use option --template" + exit 1 +fi + + +for v in AUTHENTICODE_SIGNHOST AUTHENTICODE_TOOL AUTHENTICODE_TSURL \ + AUTHENTICODE_KEY AUTHENTICODE_CERTS VERSION_SIGNKEY \ + OSSLSIGNCODE OSSLPKCS11ENGINE SCUTEMODULE ; do + eval $v=$(grep '^[[:blank:]]*'$v'[[:blank:]]*=' "$autogenrc"|cut -d= -f2\ + |sed -e 's,\\,\\\\,g'| sed -e 's,^",'\', -e 's,"$,'\',) +done + + +if [ "$stamp" = yes ]; then + if [ "$outname.asig-done" -nt "$outname" ]; then + echo >&2 "$PGM: file is '$outname' is already signed" + exit 0 + fi +fi + +if [ -n "$dryrun" ]; then + + echo >&2 "$PGM: would sign: '$inname' to '$outname'" + +elif [ -n "$AUTHENTICODE_SIGNHOST" ]; then + + echo >&2 "$PGM: Signing via host $AUTHENTICODE_SIGNHOST" + + scp "$inname" "$AUTHENTICODE_SIGNHOST:a.exe" + # Invoke command on Windows via ssh + ssh "$AUTHENTICODE_SIGNHOST" \""$AUTHENTICODE_TOOL"\" sign \ + /v /sm \ + /a /n '"g10 Code GmbH"' \ + /tr \""$AUTHENTICODE_TSURL"\" /td sha256 \ + /d \""$desc"\" \ + /fd sha256 /du https://gnupg.com a.exe + scp "$AUTHENTICODE_SIGNHOST:a.exe" "$outname" + +elif [ "$AUTHENTICODE_KEY" = card ]; then + + echo >&2 "$PGM: Signing using a card: '$inname'" + + "$OSSLSIGNCODE" sign \ + -pkcs11engine "$OSSLPKCS11ENGINE" \ + -pkcs11module "$SCUTEMODULE" \ + -certs "$AUTHENTICODE_CERTS" \ + -h sha256 -n "$desc" -i "$url" \ + -ts "$AUTHENTICODE_TSURL" \ + -in "$inname" -out "$outname.tmp" + cp "$outname.tmp" "$outname" + rm "$outname.tmp" + +elif [ "$AUTHENTICODE_KEY" = none ]; then + + echo >&2 "$PGM: Signing disabled; would sign: '$inname'" + [ "$inname" != "$outname" ] && cp "$inname" "$outname" + +else + + echo >&2 "$PGM: Signing using key $AUTHENTICODE_KEY" + osslsigncode sign -certs "$AUTHENTICODE_CERTS" \ + -pkcs12 "$AUTHENTICODE_KEY" -askpass \ + -ts "$AUTHENTICODE_TSURL" \ + -h sha256 -n "$desc" -i "$url" \ + -in "$inname" -out "$outname.tmp" + cp "$outname.tmp" "$outname" + rm "$outname.tmp" + +fi + +if [ -z "$dryrun" ]; then + [ "$stamp" = yes ] && touch "$outname.asig-done" + echo >&2 "$PGM: signed file is '$outname'" +fi + +# eof From 83e2dede0a49b048c4aab9e5a2016144a8031763 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Apr 2024 11:19:25 +0200 Subject: [PATCH 466/869] speedo: Use gpg-authcode-sign.sh and change archive label to v2.5. -- --- Makefile.am | 2 +- build-aux/speedo.mk | 95 ++++----------------------------------------- tools/Makefile.am | 2 +- 3 files changed, 9 insertions(+), 90 deletions(-) diff --git a/Makefile.am b/Makefile.am index 1b6933484..b6b8a8e9e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,7 +24,7 @@ WITH_MSI=1 # Location of the released tarball archives. This is prefixed by # the variable RELEASE_ARCHIVE in ~/.gnupg-autogen.rc. For example: # RELEASE_ARCHIVE=user@host:archive/tarballs -RELEASE_ARCHIVE_SUFFIX = gnupg/v2.4 +RELEASE_ARCHIVE_SUFFIX = gnupg/v2.5 # The variable RELEASE_SIGNKEY in ~/.gnupg-autogen.rc is used # to specify the key for signing. For example: # RELEASE_SIGNKEY=D8692123C4065DEA5E0F3AB5249B39D24F25E3B6 diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 8946c764c..3f515306b 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -43,58 +43,7 @@ # # The information required to sign the tarballs and binaries # are expected in the developer specific file ~/.gnupg-autogen.rc". -# Here is an example: -#--8<---------------cut here---------------start------------->8--- -# # Location of the released tarball archives. Note that this is an -# # internal archive and before uploading this to the public server, -# # manual tests should be run and the git release tagged and pushed. -# # This is greped by the Makefile. -# RELEASE_ARCHIVE=foo@somehost:tarball-archive -# -# # The key used to sign the GnuPG sources. -# # This is greped by the Makefile. -# RELEASE_SIGNKEY=6DAA6E64A76D2840571B4902528897B826403ADA -# -# # The key used to sign the VERSION files of some MSI installers. -# VERSION_SIGNKEY=02F38DFF731FF97CB039A1DA549E695E905BA208 -# -# # For signing Windows binaries we need to employ a Windows machine. -# # We connect to this machine via ssh and take the connection -# # parameters via .ssh/config. For example a VM could be specified -# # like this: -# # -# # Host authenticode-signhost -# # HostName localhost -# # Port 27042 -# # User gpgsign -# # -# # Depending on the used token it might be necessary to allow single -# # signon and unlock the token before running the make. The following -# # variable references this entry. This is greped by the Makefile. -# AUTHENTICODE_SIGNHOST=authenticode-signhost -# -# # The name of the signtool as used on Windows. -# # This is greped by the Makefile. -# AUTHENTICODE_TOOL="C:\Program Files (x86)\Windows Kits\10\bin\signtool.exe" -# -# # The URL for the timestamping service -# AUTHENTICODE_TSURL=http://rfc3161timestamp.globalsign.com/advanced -# -# # To use osslsigncode the follwing entries are required and -# # an empty string must be given for AUTHENTICODE_SIGNHOST. -# # They are greped by the Makefile. -# AUTHENTICODE_KEY=/home/foo/.gnupg/my-authenticode-key.p12 -# AUTHENTICODE_CERTS=/home/foo/.gnupg/my-authenticode-certs.pem -# -# # If a smartcard is used for the Authenticode signature these -# # entries are required instead: -# AUTHENTICODE_KEY=card -# AUTHENTICODE_CERTS=/home/foo/.gnupg/my_authenticode_cert.pem -# OSSLSIGNCODE=/usr/bin/osslsigncode -# OSSLPKCS11ENGINE=/usr/lib/x86_64-linux-gnu/engines-1.1/pkcs11.so -# SCUTEMODULE=/usr/local/lib/scute.so -# -#--8<---------------cut here---------------end--------------->8--- +# Use "gpg-authcode-sign.sh --template" to create a template. # We need to know our own name. @@ -246,14 +195,6 @@ PATCHELF := $(shell patchelf --version 2>/dev/null >/dev/null || echo "echo plea define READ_AUTOGEN_template $(1) = $$(shell grep '^[[:blank:]]*$(1)[[:blank:]]*=' $$$$HOME/.gnupg-autogen.rc|cut -d= -f2|xargs) endef -$(eval $(call READ_AUTOGEN_template,AUTHENTICODE_SIGNHOST)) -$(eval $(call READ_AUTOGEN_template,AUTHENTICODE_TOOL)) -$(eval $(call READ_AUTOGEN_template,AUTHENTICODE_TSURL)) -$(eval $(call READ_AUTOGEN_template,AUTHENTICODE_KEY)) -$(eval $(call READ_AUTOGEN_template,AUTHENTICODE_CERTS)) -$(eval $(call READ_AUTOGEN_template,OSSLSIGNCODE)) -$(eval $(call READ_AUTOGEN_template,OSSLPKCS11ENGINE)) -$(eval $(call READ_AUTOGEN_template,SCUTEMODULE)) $(eval $(call READ_AUTOGEN_template,OVERRIDE_TARBALLS)) @@ -1351,35 +1292,13 @@ endef # Sign the file $1 and save the result as $2 define AUTHENTICODE_sign - set -e;\ - if [ -n "$(AUTHENTICODE_SIGNHOST)" ]; then \ - echo "speedo: Signing via host $(AUTHENTICODE_SIGNHOST)";\ - scp $(1) "$(AUTHENTICODE_SIGNHOST):a.exe" ;\ - ssh "$(AUTHENTICODE_SIGNHOST)" '$(AUTHENTICODE_TOOL)' sign \ - /a /n '"g10 Code GmbH"' \ - /tr '$(AUTHENTICODE_TSURL)' /td sha256 \ - /fd sha256 /du https://gnupg.org a.exe ;\ - scp "$(AUTHENTICODE_SIGNHOST):a.exe" $(2);\ - echo "speedo: signed file is '$(2)'" ;\ - elif [ "$(AUTHENTICODE_KEY)" = card ]; then \ - echo "speedo: Signing using a card: '$(1)'";\ - $(OSSLSIGNCODE) sign \ - -pkcs11engine $(OSSLPKCS11ENGINE) \ - -pkcs11module $(SCUTEMODULE) \ - -certs $(AUTHENTICODE_CERTS) \ - -h sha256 -n GnuPG -i https://gnupg.org \ - -ts $(AUTHENTICODE_TSURL) \ - -in $(1) -out $(2).tmp ; mv $(2).tmp $(2) ; \ - elif [ -e "$(AUTHENTICODE_KEY)" ]; then \ - echo "speedo: Signing using key $(AUTHENTICODE_KEY)";\ - osslsigncode sign -certs $(AUTHENTICODE_CERTS) \ - -pkcs12 $(AUTHENTICODE_KEY) -askpass \ - -ts "$(AUTHENTICODE_TSURL)" \ - -h sha256 -n GnuPG -i https://gnupg.org \ - -in $(1) -out $(2) ;\ + (set -e; + if gpg-authcode-sign.sh --version >/dev/null; then \ + gpg-authcode-sign.sh "$(1)" "$(2)"; \ else \ - echo "speedo: WARNING: Binaries are not signed"; \ - fi + echo 2>&1 "warning: Please install gpg-authcode-sign.sh to sign files." ;\ + [ "$(1)" != "$(2)" ] && cp "$(1)" "$(2)" ;\ + fi) endef # Help target for testing to sign a file. diff --git a/tools/Makefile.am b/tools/Makefile.am index 822c42a4f..9321da9e3 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -18,7 +18,7 @@ EXTRA_DIST = \ Manifest watchgnupg.c no-libgcrypt.c \ - addgnupghome applygnupgdefaults \ + addgnupghome applygnupgdefaults gpg-authcode-sign.sh \ lspgpot mail-signed-keys convert-from-106 sockprox.c \ ccidmon.c ChangeLog-2011 \ gpg-connect-agent-w32info.rc gpg-connect-agent.w32-manifest.in \ From 9128d81bb7b92660c896965d0b6b1b1a1622d3e6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 26 Apr 2024 14:18:03 +0900 Subject: [PATCH 467/869] agent:kem:ecc: Support a key on smartcard. * agent/agent.h (agent_card_ecc_kem): New. * agent/divert-scd.c (agent_card_ecc_kem): New. * agent/pkdecrypt.c (ecc_extract_pk_from_key): New. (ecc_extract_sk_from_key): New. (ecc_raw_kem, get_cardkey, ecc_get_curve): New. (ecc_pgp_kem_decrypt): Support a key on smartcard for ECC. (composite_pgp_kem_decrypt): Handle a case of a key on smartcard. * common/sexputil.c (get_ecc_curve_from_key): New. * common/util.h (get_ecc_curve_from_key): New. -- GnuPG-bug-id: 7097 Signed-off-by: NIIBE Yutaka --- agent/agent.h | 5 +- agent/divert-scd.c | 28 +++++ agent/pkdecrypt.c | 284 +++++++++++++++++++++++++++++++++------------ common/sexputil.c | 44 +++++++ common/util.h | 1 + 5 files changed, 288 insertions(+), 74 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 4a945102a..dbb3000dd 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -705,6 +705,9 @@ gpg_error_t divert_writekey (ctrl_t ctrl, int force, const char *serialno, const char *keyref, const char *keydata, size_t keydatalen); +gpg_error_t agent_card_ecc_kem (ctrl_t ctrl, const unsigned char *ecc_ct, + size_t ecc_point_len, unsigned char *ecc_ecdh); + /*-- call-daemon.c --*/ gpg_error_t daemon_start (enum daemon_type type, ctrl_t ctrl); assuan_context_t daemon_type_ctx (enum daemon_type type, ctrl_t ctrl); @@ -753,6 +756,7 @@ int agent_card_pkdecrypt (ctrl_t ctrl, const char *desc_text, const unsigned char *indata, size_t indatalen, char **r_buf, size_t *r_buflen, int *r_padding); + int agent_card_readcert (ctrl_t ctrl, const char *id, char **r_buf, size_t *r_buflen); int agent_card_readkey (ctrl_t ctrl, const char *id, @@ -774,7 +778,6 @@ void agent_card_free_keyinfo (struct card_key_info_s *l); gpg_error_t agent_card_keyinfo (ctrl_t ctrl, const char *keygrip, int cap, struct card_key_info_s **result); - /*-- learncard.c --*/ int agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context, int force); diff --git a/agent/divert-scd.c b/agent/divert-scd.c index d7454d968..d8c2bcca7 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -486,6 +486,34 @@ divert_pkdecrypt (ctrl_t ctrl, return rc; } +gpg_error_t +agent_card_ecc_kem (ctrl_t ctrl, const unsigned char *ecc_ct, + size_t ecc_point_len, unsigned char *ecc_ecdh) +{ + gpg_error_t err = 0; + char *ecdh = NULL; + size_t len; + int rc; + + rc = agent_card_pkdecrypt (ctrl, ctrl->keygrip, getpin_cb, ctrl, NULL, + ecc_ct, ecc_point_len, &ecdh, &len, NULL); + if (rc) + return rc; + + if (len != ecc_point_len) + { + if (opt.verbose) + log_info ("%s: ECC result length invalid (%zu != %zu)\n", + __func__, len, ecc_point_len); + return gpg_error (GPG_ERR_INV_DATA); + } + else + memcpy (ecc_ecdh, ecdh, len); + + xfree (ecdh); + return err; +} + gpg_error_t divert_writekey (ctrl_t ctrl, int force, const char *serialno, diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 6e466154d..efaf53098 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -40,7 +40,7 @@ struct ecc_params size_t point_len; size_t shared_len; int hash_algo; - int algo; + int kem_algo; int scalar_reverse; }; @@ -245,65 +245,21 @@ reverse_buffer (unsigned char *buffer, unsigned int length) static gpg_error_t -ecc_pgp_kem_decrypt (ctrl_t ctrl, gcry_sexp_t s_skey0, - const unsigned char *ecc_ct, size_t ecc_ct_len, - unsigned char *ecc_ss, size_t *r_shared_len, size_t *r_point_len) +ecc_extract_pk_from_key (const struct ecc_params *ecc, gcry_sexp_t s_skey, + unsigned char *ecc_pk) { - gpg_error_t err = 0; - const struct ecc_params *ecc; - + gpg_error_t err; unsigned int nbits; const unsigned char *p; size_t len; - - gcry_mpi_t ecc_sk_mpi = NULL; - unsigned char ecc_sk[ECC_SCALAR_LEN_MAX]; gcry_mpi_t ecc_pk_mpi = NULL; - unsigned char ecc_pk[ECC_POINT_LEN_MAX]; - unsigned char ecc_ecdh[ECC_POINT_LEN_MAX]; - gcry_sexp_t curve = NULL; - char *curve_name = NULL; - - (void)ctrl; - - curve = gcry_sexp_find_token (s_skey0, "curve", 0); - if (!curve) - { - if (opt.verbose) - log_info ("%s: no curve given\n", __func__); - return gpg_error (GPG_ERR_BAD_SECKEY); - } - - curve_name = gcry_sexp_nth_string (curve, 1); - ecc = get_ecc_params (curve_name); - if (!ecc) - { - if (opt.verbose) - log_info ("%s: curve '%s' not supported\n", __func__, curve_name); - err = gpg_error (GPG_ERR_BAD_SECKEY); - goto leave; - } - - *r_shared_len = ecc->shared_len; - *r_point_len = ecc->point_len; - - if (ecc->point_len != ecc_ct_len) - { - if (opt.verbose) - log_info ("%s: ECC cipher text length invalid (%zu)\n", - __func__, ecc->point_len); - err = gpg_error (GPG_ERR_INV_DATA); - goto leave; - } - - err = gcry_sexp_extract_param (s_skey0, NULL, "/qd", - &ecc_pk_mpi, &ecc_sk_mpi, NULL); + err = gcry_sexp_extract_param (s_skey, NULL, "/q", &ecc_pk_mpi, NULL); if (err) { if (opt.verbose) log_info ("%s: extracting q and d from ECC key failed\n", __func__); - goto leave; + return err; } p = gcry_mpi_get_opaque (ecc_pk_mpi, &nbits); @@ -326,8 +282,31 @@ ecc_pgp_kem_decrypt (ctrl_t ctrl, gcry_sexp_t s_skey0, goto leave; } + if (DBG_CRYPTO) + log_printhex (ecc_pk, ecc->pubkey_len, "ECC pubkey:"); + + leave: mpi_release (ecc_pk_mpi); - ecc_pk_mpi = NULL; + return err; +} + +static gpg_error_t +ecc_extract_sk_from_key (const struct ecc_params *ecc, gcry_sexp_t s_skey, + unsigned char *ecc_sk) +{ + gpg_error_t err; + unsigned int nbits; + const unsigned char *p; + size_t len; + gcry_mpi_t ecc_sk_mpi = NULL; + + err = gcry_sexp_extract_param (s_skey, NULL, "/d", &ecc_sk_mpi, NULL); + if (err) + { + if (opt.verbose) + log_info ("%s: extracting d from ECC key failed\n", __func__); + return err; + } p = gcry_mpi_get_opaque (ecc_sk_mpi, &nbits); len = (nbits+7)/8; @@ -346,47 +325,206 @@ ecc_pgp_kem_decrypt (ctrl_t ctrl, gcry_sexp_t s_skey0, ecc_sk_mpi = NULL; if (DBG_CRYPTO) + log_printhex (ecc_sk, ecc->scalar_len, "ECC seckey:"); + + leave: + mpi_release (ecc_sk_mpi); + return err; +} + +static gpg_error_t +ecc_raw_kem (const struct ecc_params *ecc, gcry_sexp_t s_skey, + const unsigned char *ecc_ct, unsigned char *ecc_ecdh) +{ + gpg_error_t err = 0; + unsigned char ecc_sk[ECC_SCALAR_LEN_MAX]; + + if (ecc->scalar_len > ECC_SCALAR_LEN_MAX) { - log_debug ("ECC curve: %s\n", curve_name); - log_printhex (ecc_pk, ecc->pubkey_len, "ECC pubkey:"); - log_printhex (ecc_sk, ecc->scalar_len, "ECC seckey:"); - log_printhex (ecc_ct, ecc->point_len, "ECC ephem:"); + if (opt.verbose) + log_info ("%s: ECC scalar length invalid (%zu)\n", + __func__, ecc->scalar_len); + err = gpg_error (GPG_ERR_INV_DATA); + goto leave; } - err = gcry_kem_decap (ecc->algo, ecc_sk, ecc->scalar_len, - ecc_ct, ecc->point_len, ecc_ecdh, ecc->point_len, NULL, 0); + err = ecc_extract_sk_from_key (ecc, s_skey, ecc_sk); + if (err) + goto leave; + + err = gcry_kem_decap (ecc->kem_algo, ecc_sk, ecc->scalar_len, + ecc_ct, ecc->point_len, ecc_ecdh, ecc->point_len, + NULL, 0); if (err) { if (opt.verbose) log_info ("%s: gcry_kem_decap for ECC failed\n", __func__); + } + + leave: + wipememory (ecc_sk, sizeof ecc_sk); + + return err; +} + +static gpg_error_t +get_cardkey (ctrl_t ctrl, const char *keygrip, gcry_sexp_t *r_s_pk) +{ + gpg_error_t err; + unsigned char *pkbuf; + size_t pkbuflen; + + err = agent_card_readkey (ctrl, keygrip, &pkbuf, NULL); + if (err) + return err; + + pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL); + err = gcry_sexp_sscan (r_s_pk, NULL, (char*)pkbuf, pkbuflen); + if (err) + log_error ("failed to build S-Exp from received card key: %s\n", + gpg_strerror (err)); + + xfree (pkbuf); + return err; +} + +static gpg_error_t +ecc_get_curve (ctrl_t ctrl, gcry_sexp_t s_skey, const char **r_curve) +{ + gpg_error_t err = 0; + gcry_sexp_t s_skey_card = NULL; + const char *curve = NULL; + gcry_sexp_t key; + + *r_curve = NULL; + + if (!s_skey) + { + err = get_cardkey (ctrl, ctrl->keygrip, &s_skey_card); + if (err) + goto leave; + + key = s_skey_card; + } + else + key = s_skey; + + curve = get_ecc_curve_from_key (key); + if (!curve) + { + err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; } + *r_curve = curve; + + leave: + gcry_sexp_release (s_skey_card); + return err; +} + +/* Given a private key in SEXP by S_SKEY0 and a cipher text by ECC_CT + * with length ECC_POINT_LEN, do ECC-KEM operation. Result is + * returned in the memory referred by ECC_SS. Shared secret length is + * returned in the memory referred by R_SHARED_LEN. CTRL is used to + * access smartcard, internally. */ +static gpg_error_t +ecc_pgp_kem_decrypt (ctrl_t ctrl, gcry_sexp_t s_skey0, + unsigned char *shadow_info0, + const unsigned char *ecc_ct, size_t ecc_point_len, + unsigned char *ecc_ss, size_t *r_shared_len) +{ + gpg_error_t err; + unsigned char ecc_ecdh[ECC_POINT_LEN_MAX]; + unsigned char ecc_pk[ECC_POINT_LEN_MAX]; + const char *curve; + const struct ecc_params *ecc = NULL; + + if (ecc_point_len > ECC_POINT_LEN_MAX) + return gpg_error (GPG_ERR_INV_DATA); + + err = ecc_get_curve (ctrl, s_skey0, &curve); + if (err) + { + if ((gpg_err_code (err) == GPG_ERR_CARD_REMOVED + || gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT) + && !s_skey0) + err = gpg_error (GPG_ERR_NO_SECKEY); + return err; + } + + ecc = get_ecc_params (curve); + if (!ecc) + { + if (opt.verbose) + log_info ("%s: curve '%s' not supported\n", __func__, curve); + return gpg_error (GPG_ERR_BAD_SECKEY); + } + + *r_shared_len = ecc->shared_len; + if (DBG_CRYPTO) - log_printhex (ecc_ecdh, ecc->point_len, "ECC ecdh:"); + log_debug ("ECC curve: %s\n", curve); + + if (ecc->point_len != ecc_point_len) + { + if (opt.verbose) + log_info ("%s: ECC cipher text length invalid (%zu != %zu)\n", + __func__, ecc->point_len, ecc_point_len); + return gpg_error (GPG_ERR_INV_DATA); + } + + err = ecc_extract_pk_from_key (ecc, s_skey0, ecc_pk); + if (err) + return err; + + if (DBG_CRYPTO) + log_printhex (ecc_ct, ecc->point_len, "ECC ephem:"); + + if (shadow_info0 || !s_skey0) + { + if (s_skey0 && agent_is_tpm2_key (s_skey0)) + { + log_error ("TPM decryption failed: %s\n", gpg_strerror (err)); + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } + else + { + err = agent_card_ecc_kem (ctrl, ecc_ct, ecc->point_len, ecc_ecdh); + if (err) + { + log_error ("smartcard decryption failed: %s\n", + gpg_strerror (err)); + return err; + } + } + } + else + err = ecc_raw_kem (ecc, s_skey0, ecc_ct, ecc_ecdh); + + if (err) + return err; + + if (DBG_CRYPTO) + log_printhex (ecc_ecdh, ecc_point_len, "ECC ecdh:"); err = gnupg_ecc_kem_kdf (ecc_ss, ecc->shared_len, ecc->hash_algo, ecc_ecdh, ecc->point_len, ecc_ct, ecc->point_len, ecc_pk, ecc->point_len); + + wipememory (ecc_ecdh, sizeof ecc_ecdh); + if (err) { if (opt.verbose) log_info ("%s: kdf for ECC failed\n", __func__); - goto leave; + return err; } if (DBG_CRYPTO) log_printhex (ecc_ss, ecc->shared_len, "ECC shared:"); - leave: - wipememory (ecc_sk, sizeof ecc_sk); - wipememory (ecc_ecdh, sizeof ecc_ecdh); - - mpi_release (ecc_pk_mpi); - mpi_release (ecc_sk_mpi); - xfree (curve_name); - gcry_sexp_release (curve); - return err; + return 0; } /* For composite PGP KEM (ECC+ML-KEM), decrypt CIPHERTEXT using KEM API. @@ -447,7 +585,7 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, err = agent_key_from_file (ctrl, NULL, desc_text, ctrl->keygrip, &shadow_info0, CACHE_MODE_NORMAL, NULL, &s_skey0, NULL, NULL); - if (err) + if (err && gpg_err_code (err) != GPG_ERR_NO_SECKEY) { log_error ("failed to read the secret key\n"); goto leave; @@ -456,14 +594,13 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, err = agent_key_from_file (ctrl, NULL, desc_text, ctrl->keygrip1, &shadow_info1, CACHE_MODE_NORMAL, NULL, &s_skey1, NULL, NULL); + /* Here assumes no smartcard for ML-KEM, but private key in a file. */ if (err) { log_error ("failed to read the another secret key\n"); goto leave; } - /* Here assumes no smartcard, but private keys */ - err = gcry_sexp_extract_param (s_cipher, NULL, "%dc/eks&'fixed-info'", &algo, &ecc_ct_mpi, &mlkem_ct_mpi, &encrypted_sessionkey_mpi, &fixed_info, NULL); @@ -491,8 +628,9 @@ composite_pgp_kem_decrypt (ctrl_t ctrl, const char *desc_text, } /* Firstly, ECC part. */ - err = ecc_pgp_kem_decrypt (ctrl, s_skey0, ecc_ct, ecc_ct_len, - ecc_ss, &ecc_shared_len, &ecc_point_len); + ecc_point_len = ecc_ct_len; + err = ecc_pgp_kem_decrypt (ctrl, s_skey0, shadow_info0, ecc_ct, ecc_point_len, + ecc_ss, &ecc_shared_len); if (err) goto leave; diff --git a/common/sexputil.c b/common/sexputil.c index e6fc84da0..15fd7cf1d 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -1194,3 +1194,47 @@ cipher_mode_to_string (int mode) default: return "[?]"; } } + +/* Return the cannonical name of the ECC curve in KEY. */ +const char * +get_ecc_curve_from_key (gcry_sexp_t key) +{ + gcry_sexp_t list = NULL; + gcry_sexp_t l2 = NULL; + const char *curve_name = NULL; + char *name = NULL; + + /* Check that the first element is valid. */ + 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); + if (!list) + goto leave; + + l2 = gcry_sexp_cadr (list); + gcry_sexp_release (list); + list = l2; + l2 = NULL; + + name = gcry_sexp_nth_string (list, 0); + if (!name) + goto leave; + + if (gcry_pk_map_name (name) != GCRY_PK_ECC) + goto leave; + + l2 = gcry_sexp_find_token (list, "curve", 0); + xfree (name); + name = gcry_sexp_nth_string (l2, 1); + curve_name = openpgp_oid_or_name_to_curve (name, 1); + gcry_sexp_release (l2); + + leave: + xfree (name); + gcry_sexp_release (list); + return curve_name; +} diff --git a/common/util.h b/common/util.h index 238b8f1bc..f8447aea7 100644 --- a/common/util.h +++ b/common/util.h @@ -196,6 +196,7 @@ 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 *cipher_mode_to_string (int mode); +const char *get_ecc_curve_from_key (gcry_sexp_t key); /*-- convert.c --*/ int hex2bin (const char *string, void *buffer, size_t length); From 351f5e814b22654809f162f77249a385f109dcc7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Apr 2024 15:50:06 +0200 Subject: [PATCH 468/869] speedo: Set gnupg_ver macro to gnupg26_ver. -- Also fixed a syntax erro rin AUTHENTICODE_sign --- build-aux/speedo.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 3f515306b..a81b75bc3 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -303,7 +303,7 @@ endif # Version numbers of the released packages gnupg_ver_this = $(shell cat $(topsrc)/VERSION) -gnupg_ver := $(shell awk '$$1=="gnupg24_ver" {print $$2}' swdb.lst) +gnupg_ver := $(shell awk '$$1=="gnupg26_ver" {print $$2}' swdb.lst) libgpg_error_ver := $(shell awk '$$1=="libgpg_error_ver" {print $$2}' swdb.lst) libgpg_error_sha1:= $(shell awk '$$1=="libgpg_error_sha1" {print $$2}' swdb.lst) @@ -1292,7 +1292,7 @@ endef # Sign the file $1 and save the result as $2 define AUTHENTICODE_sign - (set -e; + (set -e; \ if gpg-authcode-sign.sh --version >/dev/null; then \ gpg-authcode-sign.sh "$(1)" "$(2)"; \ else \ From c1d62418d5b3898eae264a619631d9064735f21c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 25 Apr 2024 16:21:30 +0200 Subject: [PATCH 469/869] speedo: Prepare for building 64 bit Windows versions. -- --- build-aux/speedo.mk | 56 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index a81b75bc3..03750ca65 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -73,6 +73,7 @@ help: @echo 'Use WIXPREFIX to provide the WIX binaries for the MSI package.' @echo ' Using WIX also requires wine with installed wine mono.' @echo ' See help-wixlib for more information' + @echo 'Set W32VERSION=w64 to build a 64 bit Windows version.' help-wixlib: @echo 'The buildsystem can create a wixlib to build MSI packages.' @@ -157,9 +158,12 @@ w32-release-offline: check-tools # to "this" from the unpacked sources. WHAT=git -# Set target to "native" or "w32" +# Set target to "native" or "w32". TARGETOS= +# To build a 64 bit Windows version also change this to "w64" +W32VERSION=w32 + # Set to 1 to use a pre-installed swdb.lst instead of the online version. CUSTOM_SWDB=0 @@ -180,7 +184,9 @@ TARBALLS=$(shell pwd)/../tarballs MAKE_J=6 # Name to use for the w32 installer and sources -INST_NAME=gnupg-w32 + + +INST_NAME=gnupg-$(W32VERSION) # Use this to override the installaion directory for native builds. INSTALL_PREFIX=none @@ -271,7 +277,12 @@ endif # Packages which are additionally build for 64 bit Windows. They are # only used for gpgex and thus we need to build them only if we want # a full installer. -speedo_w64_spkgs = +ifeq ($(W32VERSION),w64) + # Keep this empty + speedo_w64_spkgs = +else + speedo_w64_spkgs = +endif # Packages which use the gnupg autogen.sh build style speedo_gnupg_style = \ @@ -350,7 +361,7 @@ sqlite_sha1 := $(shell awk '$$1=="sqlite_sha1_gz" {print $$2}' swdb.lst) sqlite_sha2 := $(shell awk '$$1=="sqlite_sha2_gz" {print $$2}' swdb.lst) -$(info Information from the version database) +$(info Information from the version database:) $(info GnuPG ..........: $(gnupg_ver) (building $(gnupg_ver_this))) $(info GpgRT ..........: $(libgpg_error_ver)) $(info Npth ...........: $(npth_ver)) @@ -365,6 +376,18 @@ $(info GPGME ..........: $(gpgme_ver)) $(info Pinentry .......: $(pinentry_ver)) endif +$(info Information for this run:) +$(info Build type .....: $(WHAT)) +$(info Target .........: $(TARGETOS)) +ifeq ($(TARGETOS),w32) +ifeq ($(W32VERSION),w64) + $(info Windows version : 64 bit) +else + $(info Windows version : 32 bit) +endif +endif + + # Version number for external packages pkg_config_ver = 0.23 libiconv_ver = 1.14 @@ -592,12 +615,21 @@ report: report-speedo clean: clean-speedo + +ifeq ($(W32VERSION),w64) +W32CC_PREFIX = x86_64 +else +W32CC_PREFIX = i686 +endif + ifeq ($(TARGETOS),w32) -STRIP = i686-w64-mingw32-strip +STRIP = $(W32CC_PREFIX)-w64-mingw32-strip +W32STRIP32 = i686-w64-mingw32-strip else STRIP = strip endif -W32CC = i686-w64-mingw32-gcc +W32CC = $(W32CC_PREFIX)-w64-mingw32-gcc +W32CC32 = i686-w64-mingw32-gcc -include config.mk @@ -639,9 +671,9 @@ ifneq ($(TARGETOS),) # Determine build and host system build := $(shell $(topsrc)/autogen.sh --silent --print-build) ifeq ($(TARGETOS),w32) - speedo_autogen_buildopt := --build-w32 + speedo_autogen_buildopt := --build-$(W32VERSION) speedo_autogen_buildopt6 := --build-w64 - host := $(shell $(topsrc)/autogen.sh --silent --print-host --build-w32) + host := $(shell $(topsrc)/autogen.sh --silent --print-host --build-$(W32VERSION)) host6:= $(shell $(topsrc)/autogen.sh --silent --print-host --build-w64) speedo_host_build_option := --host=$(host) --build=$(build) speedo_host_build_option6 := --host=$(host6) --build=$(build) @@ -865,7 +897,7 @@ else ifneq ($(findstring $(1),$(speedo_gnupg_style)),) mkdir "$$$${pkgbdir}"; \ cd "$$$${pkgbdir}"; \ if [ -n "$(speedo_autogen_buildopt)" ]; then \ - eval AUTOGEN_SH_SILENT=1 w32root="$(idir)" \ + eval AUTOGEN_SH_SILENT=1 $(W32VERSION)root="$(idir)" \ "$$$${pkgsdir}/autogen.sh" \ $(speedo_autogen_buildopt) \ $$$${pkgcfg} $$$${pkgextracflags}; \ @@ -1179,13 +1211,13 @@ $(bdir)/README.txt: $(bdir)/NEWS.tmp $(topsrc)/README $(w32src)/README.txt \ $(bdir)/g4wihelp.dll: $(w32src)/g4wihelp.c $(w32src)/exdll.h $(w32src)/exdll.c (set -e; cd $(bdir); \ - $(W32CC) -DUNICODE -static-libgcc -I . -O2 -c \ + $(W32CC32) -DUNICODE -static-libgcc -I . -O2 -c \ -o exdll.o $(w32src)/exdll.c; \ - $(W32CC) -DUNICODE -static-libgcc -I. -shared -O2 \ + $(W32CC32) -DUNICODE -static-libgcc -I. -shared -O2 \ -o g4wihelp.dll $(w32src)/g4wihelp.c exdll.o \ -lwinmm -lgdi32 -luserenv \ -lshell32 -loleaut32 -lshlwapi -lmsimg32; \ - $(STRIP) g4wihelp.dll) + $(W32STRIP32) g4wihelp.dll) w32_insthelpers: $(bdir)/g4wihelp.dll From c8a3b711f0386e158ccaa7484ffe74055b6706b3 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 Apr 2024 14:10:29 +0200 Subject: [PATCH 470/869] speedo: Do not use the gpg-error-config in the build system -- With that installed we don't get proper suport for SYSROOT. --- build-aux/speedo.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 03750ca65..aaf7065db 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -478,8 +478,8 @@ speedo_pkg_gettext_tar = $(pkg2rep)/gettext-$(gettext_ver).tar.gz speedo_pkg_npth_configure = --enable-static -speedo_pkg_libgpg_error_configure = --enable-static --enable-install-gpg-error-config -speedo_pkg_w64_libgpg_error_configure = --enable-static --enable-install-gpg-error-config +speedo_pkg_libgpg_error_configure = --enable-static +speedo_pkg_w64_libgpg_error_configure = --enable-static speedo_pkg_libassuan_configure = --enable-static speedo_pkg_w64_libassuan_configure = --enable-static From 516b5301262e21396343aa5a1dbc0f1bf0f3e9bf Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 26 Apr 2024 14:33:48 +0200 Subject: [PATCH 471/869] speedo: Change install directory for Windows -- Given that we will build only 64 bit versions, we need to switch where stuff is installed on Windows. --- build-aux/speedo.mk | 5 ++++- build-aux/speedo/w32/inst.nsi | 17 +++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index aaf7065db..68c4af1fd 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -186,7 +186,7 @@ MAKE_J=6 # Name to use for the w32 installer and sources -INST_NAME=gnupg-$(W32VERSION) +INST_NAME=gnupg-w32 # Use this to override the installaion directory for native builds. INSTALL_PREFIX=none @@ -384,6 +384,9 @@ ifeq ($(W32VERSION),w64) $(info Windows version : 64 bit) else $(info Windows version : 32 bit) +ifneq ($(W32VERSION),w32) + $(error W32VERSION is not set to a proper value: Use only w32 or w64) +endif endif endif diff --git a/build-aux/speedo/w32/inst.nsi b/build-aux/speedo/w32/inst.nsi index 6c4b84969..acd32ad27 100644 --- a/build-aux/speedo/w32/inst.nsi +++ b/build-aux/speedo/w32/inst.nsi @@ -46,7 +46,7 @@ Unicode true !define PRETTY_PACKAGE "GNU Privacy Guard" !define PRETTY_PACKAGE_SHORT "GnuPG" !define COMPANY "The GnuPG Project" -!define COPYRIGHT "Copyright (C) 2021 g10 Code GmbH" +!define COPYRIGHT "Copyright (C) 2024 g10 Code GmbH" !define DESCRIPTION "GnuPG: The GNU Privacy Guard for Windows" !define INSTALL_DIR "GnuPG" @@ -63,13 +63,13 @@ Unicode true GnuPG includes an advanced key management facility and is compliant \ with the OpenPGP Internet standard as described in RFC-4880. \ \r\n\r\n$_CLICK \ - \r\n\r\n\r\n\r\n\r\nThis is GnuPG version ${VERSION}.\r\n\ + \r\n\r\n\r\n\r\n\r\nThis is GnuPG version ${VERSION} (64 bit).\r\n\ File version: ${PROD_VERSION}\r\n\ Release date: ${BUILD_ISODATE}" !define ABOUT_GERMAN \ "GnuPG is die häufigst verwendete Software zur Mail- und Datenverschlüsselung.\ \r\n\r\n$_CLICK \ - \r\n\r\n\r\n\r\n\r\nDies ist GnuPG Version ${VERSION}.\r\n\ + \r\n\r\n\r\n\r\n\r\nDies ist GnuPG Version ${VERSION} (64 bit).\r\n\ Dateiversion: ${PROD_VERSION}\r\n\ Releasedatum: ${BUILD_ISODATE}" @@ -119,7 +119,7 @@ OutFile "${NAME}-${VERSION}_${BUILD_DATESTR}.exe" !ifndef INSTALL_DIR !define INSTALL_DIR "GnuPG" !endif -InstallDir "$PROGRAMFILES\${INSTALL_DIR}" +InstallDir "$PROGRAMFILES64\${INSTALL_DIR}" # Add version information to the file properties. VIProductVersion "${PROD_VERSION}" @@ -1465,7 +1465,12 @@ Function .onInit Call G4wRunOnce - SetOutPath $TEMP + ${IfNot} ${RunningX64} + MessageBox MB_OK "Sorry this version runs only on x64 machines" + Abort + ${EndIf} + + SetOutPath $TEMP #!ifdef SOURCES # File /oname=gpgspltmp.bmp "${TOP_SRCDIR}/doc/logo/gnupg-logo-400px.bmp" # # We play the tune only for the soruce installer @@ -1486,7 +1491,7 @@ Function .onInit Var /GLOBAL changed_dir # Check if the install directory was modified on the command line - StrCmp "$INSTDIR" "$PROGRAMFILES\${INSTALL_DIR}" unmodified 0 + StrCmp "$INSTDIR" "$PROGRAMFILES64\${INSTALL_DIR}" unmodified 0 # It is modified. Save that value. StrCpy $changed_dir "$INSTDIR" From f415d96facd3d99905d817e381b9b231622d3f20 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 16 Nov 2022 17:15:36 +0100 Subject: [PATCH 472/869] gpg: Add a notation to Kyber encryption subkeys * g10/keygen.c (struct opaque_data_usage_and_pk): New. (do_add_notation): New. (keygen_add_key_flags_from_oduap): New. (write_keybinding): Prepare for de-vs cplimance notation. Add a notation to Kyber subkeys. -- This code is based on the 2.2 commit b284412786d71c1cf382e1dff3a36ec6cce11556 However the de-vs notation is currently ineffective as long as Libgcrypt won't claim compliance. The new notation fips203.ipd.2023-08-24 has been added to allow detection of subkeys which have been crated with a pre-final FIPS203 spec for Kyber. --- g10/keygen.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 119f7ca5d..13d46e43c 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -146,6 +146,16 @@ struct common_gen_cb_parm_s typedef struct common_gen_cb_parm_s *common_gen_cb_parm_t; +/* A communication object to help adding certain notations to a key + * binding signature. */ +struct opaque_data_usage_and_pk +{ + unsigned int usage; + const char *cpl_notation; + PKT_public_key *pk; +}; + + /* FIXME: These globals vars are ugly. And using MAX_PREFS even for * aeads is useless, given that we don't expects more than a very few * algorithms. */ @@ -177,6 +187,9 @@ static gpg_error_t gen_card_key (int keyno, int algo, int is_primary, u32 expireval, int *keygen_flags); static unsigned int get_keysize_range (int algo, unsigned int *min, unsigned int *max); +static void do_add_notation (PKT_signature *sig, + const char *name, const char *value, + int critical); @@ -341,6 +354,20 @@ keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque) } +/* This is only used to write the key binding signature. It is not + * used for the primary key. */ +static int +keygen_add_key_flags_from_oduap (PKT_signature *sig, void *opaque) +{ + struct opaque_data_usage_and_pk *oduap = opaque; + + do_add_key_flags (sig, oduap->usage); + if (oduap->cpl_notation) + do_add_notation (sig, "cpl@gnupg.org", oduap->cpl_notation, 0); + return keygen_add_key_expire (sig, oduap->pk); +} + + static int set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf) { @@ -946,6 +973,44 @@ keygen_add_keyserver_url(PKT_signature *sig, void *opaque) return 0; } + +/* This function is used to add a notations to a signature. In + * general the caller should have cleared exiting notations before + * adding new ones. For example by calling: + * + * delete_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION); + * delete_sig_subpkt(sig->unhashed,SIGSUBPKT_NOTATION); + * + * Only human readable notaions may be added. NAME and value are + * expected to be UTF-* strings. + */ +static void +do_add_notation (PKT_signature *sig, const char *name, const char *value, + int critical) +{ + unsigned char *buf; + unsigned int n1,n2; + + n1 = strlen (name); + n2 = strlen (value); + + buf = xmalloc (8 + n1 + n2); + + buf[0] = 0x80; /* human readable. */ + buf[1] = buf[2] = buf[3] = 0; + buf[4] = n1 >> 8; + buf[5] = n1; + buf[6] = n2 >> 8; + buf[7] = n2; + memcpy (buf+8, name, n1); + memcpy (buf+8+n1, value, n2); + build_sig_subpkt (sig, + (SIGSUBPKT_NOTATION|(critical?SIGSUBPKT_FLAG_CRITICAL:0)), + buf, 8+n1+n2 ); + xfree (buf); +} + + int keygen_add_notations(PKT_signature *sig,void *opaque) { @@ -995,6 +1060,7 @@ keygen_add_notations(PKT_signature *sig,void *opaque) return 0; } + int keygen_add_revkey (PKT_signature *sig, void *opaque) { @@ -1228,6 +1294,7 @@ write_keybinding (ctrl_t ctrl, kbnode_t root, PKT_signature *sig; KBNODE node; PKT_public_key *pri_pk, *sub_pk; + struct opaque_data_usage_and_pk oduap; if (opt.verbose) log_info(_("writing key binding signature\n")); @@ -1253,10 +1320,21 @@ write_keybinding (ctrl_t ctrl, kbnode_t root, BUG(); /* Make the signature. */ - sub_pk->pubkey_usage = use; + oduap.usage = use; + if ((use & PUBKEY_USAGE_ENC) + && opt.compliance == CO_DE_VS + /* The required libgcrypt 1.11 won't yet claim a compliant RNG. */ + && gnupg_rng_is_compliant (CO_DE_VS)) + oduap.cpl_notation = "de-vs"; + else if ((use & PUBKEY_USAGE_ENC) + && sub_pk->pubkey_algo == PUBKEY_ALGO_KYBER) + oduap.cpl_notation = "fips203.ipd.2023-08-24"; + else + oduap.cpl_notation = NULL; + oduap.pk = sub_pk; err = make_keysig_packet (ctrl, &sig, pri_pk, NULL, sub_pk, pri_psk, 0x18, timestamp, 0, - keygen_add_key_flags_and_expire, sub_pk, + keygen_add_key_flags_from_oduap, &oduap, cache_nonce); if (err) { From 467239dccbf975a19485eb5725b174b6f69aeca0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 2 May 2024 21:13:18 +0200 Subject: [PATCH 473/869] speedo: Update the instructions to use the gnupg26 tag. -- --- build-aux/speedo.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index 68c4af1fd..e92a94231 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -1109,8 +1109,8 @@ ifneq ($(TARGETOS),w32) echo "speedo: * Now copy $(idir)/ to the final location and" ;\ echo "speedo: * adjust $(idir)/bin/gpgconf.ctl accordingly" ;\ echo "speedo: * Or run:" ;\ - echo "speedo: * make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24" ;\ - echo "speedo: * ldconfig -n /usr/local/gnupg24/lib";\ + echo "speedo: * make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg26" ;\ + echo "speedo: * ldconfig -n /usr/local/gnupg26/lib";\ echo "speedo: */") endif @@ -1125,8 +1125,8 @@ ifneq ($(TARGETOS),w32) echo "speedo: ERROR: SYSROOT has not been given";\ echo "speedo: Set SYSROOT to the desired install directory";\ echo "speedo: Example:";\ - echo "speedo: make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg24";\ - echo "speedo: ldconfig -n /usr/local/gnupg24/lib";\ + echo "speedo: make -f $(topsrc)/build-aux/speedo.mk install SYSROOT=/usr/local/gnupg26";\ + echo "speedo: ldconfig -n /usr/local/gnupg26/lib";\ exit 1;\ fi;\ if [ ! -d "$$SYSROOT"/bin ]; then if ! mkdir "$$SYSROOT"/bin; then \ @@ -1316,7 +1316,7 @@ wixlib: installer $(bdir)/README.txt $(w32src)/wixlib.wxs ) define MKSWDB_commands - ( pref="#+macro: gnupg24_w32_$(3)" ;\ + ( pref="#+macro: gnupg26_w32_$(3)" ;\ echo "$${pref}ver $(INST_VERSION)_$(BUILD_DATESTR)" ;\ echo "$${pref}date $(2)" ;\ echo "$${pref}size $$(wc -c <$(1)|awk '{print int($$1/1024)}')k";\ From 473f37a53ef4896995fe6b3cc05e95bd3ed25449 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 6 May 2024 09:48:20 +0200 Subject: [PATCH 474/869] scd:piv: Support listing of retired keys with KEYINFO. * scd/app-piv.c (data_objects): Mark returned key as having a keypair. (do_with_keygrip): Check against encrusage and not used one tag. * tools/gpg-card.c (piv_keyref_is_retired): New. (list_all_kinfo): Pretty print retired keys. -- This allows to list all existing retired keys without using separate readkey commands. --- doc/gpg-card.texi | 2 +- scd/app-piv.c | 42 +++++++++++++++++++++--------------------- tools/gpg-card.c | 28 +++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/doc/gpg-card.texi b/doc/gpg-card.texi index 3a659e80f..6458598bd 100644 --- a/doc/gpg-card.texi +++ b/doc/gpg-card.texi @@ -546,7 +546,7 @@ be printed; to create a new key anyway the option @samp{--force} can be used. Note that only the private and public keys have been created but no certificates are stored in the key slots. In fact, GnuPG uses its own non-standard method to store just the public key in place of -the the certificate. Other application will not be able to make use +the certificate. Other application will not be able to make use these keys until @command{gpgsm} or another tool has been used to create and store the respective certificates. Let us see what the list command now shows: diff --git a/scd/app-piv.c b/scd/app-piv.c index dc92bd2e2..d7f9acca3 100644 --- a/scd/app-piv.c +++ b/scd/app-piv.c @@ -128,45 +128,45 @@ static struct data_object_s data_objects[] = { "Discovery Object" }, { 0x5FC10C, 0, 0,1, 0,0, 0, "", "2.96.96", NULL, "Key History Object" }, - { 0x5FC10D, 0, 0,1, 0,0, 0, "82", "2.16.1", "e", + { 0x5FC10D, 0, 0,1, 0,0, 1, "82", "2.16.1", "e", "Retired Cert Key Mgm 1" }, - { 0x5FC10E, 0, 0,1, 0,0, 0, "83", "2.16.2", "e", + { 0x5FC10E, 0, 0,1, 0,0, 1, "83", "2.16.2", "e", "Retired Cert Key Mgm 2" }, - { 0x5FC10F, 0, 0,1, 0,0, 0, "84", "2.16.3", "e", + { 0x5FC10F, 0, 0,1, 0,0, 1, "84", "2.16.3", "e", "Retired Cert Key Mgm 3" }, - { 0x5FC110, 0, 0,1, 0,0, 0, "85", "2.16.4", "e", + { 0x5FC110, 0, 0,1, 0,0, 1, "85", "2.16.4", "e", "Retired Cert Key Mgm 4" }, - { 0x5FC111, 0, 0,1, 0,0, 0, "86", "2.16.5", "e", + { 0x5FC111, 0, 0,1, 0,0, 1, "86", "2.16.5", "e", "Retired Cert Key Mgm 5" }, - { 0x5FC112, 0, 0,1, 0,0, 0, "87", "2.16.6", "e", + { 0x5FC112, 0, 0,1, 0,0, 1, "87", "2.16.6", "e", "Retired Cert Key Mgm 6" }, - { 0x5FC113, 0, 0,1, 0,0, 0, "88", "2.16.7", "e", + { 0x5FC113, 0, 0,1, 0,0, 1, "88", "2.16.7", "e", "Retired Cert Key Mgm 7" }, - { 0x5FC114, 0, 0,1, 0,0, 0, "89", "2.16.8", "e", + { 0x5FC114, 0, 0,1, 0,0, 1, "89", "2.16.8", "e", "Retired Cert Key Mgm 8" }, - { 0x5FC115, 0, 0,1, 0,0, 0, "8A", "2.16.9", "e", + { 0x5FC115, 0, 0,1, 0,0, 1, "8A", "2.16.9", "e", "Retired Cert Key Mgm 9" }, - { 0x5FC116, 0, 0,1, 0,0, 0, "8B", "2.16.10", "e", + { 0x5FC116, 0, 0,1, 0,0, 1, "8B", "2.16.10", "e", "Retired Cert Key Mgm 10" }, - { 0x5FC117, 0, 0,1, 0,0, 0, "8C", "2.16.11", "e", + { 0x5FC117, 0, 0,1, 0,0, 1, "8C", "2.16.11", "e", "Retired Cert Key Mgm 11" }, - { 0x5FC118, 0, 0,1, 0,0, 0, "8D", "2.16.12", "e", + { 0x5FC118, 0, 0,1, 0,0, 1, "8D", "2.16.12", "e", "Retired Cert Key Mgm 12" }, - { 0x5FC119, 0, 0,1, 0,0, 0, "8E", "2.16.13", "e", + { 0x5FC119, 0, 0,1, 0,0, 1, "8E", "2.16.13", "e", "Retired Cert Key Mgm 13" }, - { 0x5FC11A, 0, 0,1, 0,0, 0, "8F", "2.16.14", "e", + { 0x5FC11A, 0, 0,1, 0,0, 1, "8F", "2.16.14", "e", "Retired Cert Key Mgm 14" }, - { 0x5FC11B, 0, 0,1, 0,0, 0, "90", "2.16.15", "e", + { 0x5FC11B, 0, 0,1, 0,0, 1, "90", "2.16.15", "e", "Retired Cert Key Mgm 15" }, - { 0x5FC11C, 0, 0,1, 0,0, 0, "91", "2.16.16", "e", + { 0x5FC11C, 0, 0,1, 0,0, 1, "91", "2.16.16", "e", "Retired Cert Key Mgm 16" }, - { 0x5FC11D, 0, 0,1, 0,0, 0, "92", "2.16.17", "e", + { 0x5FC11D, 0, 0,1, 0,0, 1, "92", "2.16.17", "e", "Retired Cert Key Mgm 17" }, - { 0x5FC11E, 0, 0,1, 0,0, 0, "93", "2.16.18", "e", + { 0x5FC11E, 0, 0,1, 0,0, 1, "93", "2.16.18", "e", "Retired Cert Key Mgm 18" }, - { 0x5FC11F, 0, 0,1, 0,0, 0, "94", "2.16.19", "e", + { 0x5FC11F, 0, 0,1, 0,0, 1, "94", "2.16.19", "e", "Retired Cert Key Mgm 19" }, - { 0x5FC120, 0, 0,1, 0,0, 0, "95", "2.16.20", "e", + { 0x5FC120, 0, 0,1, 0,0, 1, "95", "2.16.20", "e", "Retired Cert Key Mgm 20" }, { 0x5FC121, 0, 2,2, 0,0, 0, "", "2.16.21", NULL, "Cardholder Iris Images" }, @@ -3543,7 +3543,7 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action, } if (capability == GCRY_PK_USAGE_ENCR) { - if (strcmp (data_objects[i].keyref, "9D")) + if (strcmp (data_objects[i].usage, "e")) continue; } if (capability == GCRY_PK_USAGE_AUTH) diff --git a/tools/gpg-card.c b/tools/gpg-card.c index f24b74194..8b3a3082b 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -836,6 +836,21 @@ list_one_kinfo (card_info_t info, key_info_t kinfo, } +/* Return the retired key number if KEYREF is for a retired key; 0 if + * not. */ +static int +piv_keyref_is_retired (const char *keyref) +{ + if (!strncmp (keyref, "PIV.8", 5) + && keyref[5] >= '2' && hexdigitp (keyref + 5)) + return xtoi_1 (keyref+5) - 1; + else if (!strncmp (keyref, "PIV.9", 5) + && keyref[5] >= '0' && keyref[5] <= '5') + return atoi_1 (keyref+5) + 15; + else + return 0; +} + /* List all keyinfo in INFO using the list of LABELS. */ static void list_all_kinfo (card_info_t info, keyinfolabel_t labels, estream_t fp, @@ -843,6 +858,7 @@ list_all_kinfo (card_info_t info, keyinfolabel_t labels, estream_t fp, { key_info_t kinfo; int idx, i, j; + int rn; /* Print the keyinfo. We first print those we known and then all * remaining item. */ @@ -864,9 +880,15 @@ list_all_kinfo (card_info_t info, keyinfolabel_t labels, estream_t fp, { if (kinfo->xflag) continue; - tty_fprintf (fp, "Key %s", kinfo->keyref); - for (i=4+strlen (kinfo->keyref), j=0; i < 18; i++, j=1) - tty_fprintf (fp, j? ".":" "); + if (info->apptype == APP_TYPE_PIV + && (rn = piv_keyref_is_retired (kinfo->keyref))) + tty_fprintf (fp, "Key retired %2d ...", rn); + else + { + tty_fprintf (fp, "Key %s", kinfo->keyref); + for (i=4+strlen (kinfo->keyref), j=0; i < 18; i++, j=1) + tty_fprintf (fp, j? ".":" "); + } tty_fprintf (fp, ":"); list_one_kinfo (info, kinfo, NULL, fp, no_key_lookup, create_shadow); } From 351fc6e6fa65e654d4b087e8577cf46b36ce0a2e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 6 May 2024 10:47:01 +0200 Subject: [PATCH 475/869] gpg: Algo "kyber" is now a shortcut for ky768_bp256. * g10/keygen.c (parse_key_parameter_part): Change Kyber defaults. -- Also kyber1024 is now a shortcut for ky1024_bp384. This change is to align it with the original wussler draft. --- g10/keygen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 13d46e43c..fe9a5d8f2 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3769,7 +3769,7 @@ parse_key_parameter_part (ctrl_t ctrl, { /* Get the curve and check that it can technically be used * (i.e. everything except the EdXXXX curves. */ - curve = openpgp_is_curve_supported ("brainpoolP384r1", &algo, NULL); + curve = openpgp_is_curve_supported ("brainpoolP256r1", &algo, NULL); if (!curve || algo == PUBKEY_ALGO_EDDSA) return gpg_error (GPG_ERR_UNKNOWN_CURVE); algo = PUBKEY_ALGO_KYBER; @@ -3780,7 +3780,7 @@ parse_key_parameter_part (ctrl_t ctrl, { /* Get the curve and check that it can technically be used * (i.e. everything except the EdXXXX curves. */ - curve = openpgp_is_curve_supported ("brainpoolP512r1", &algo, NULL); + curve = openpgp_is_curve_supported ("brainpoolP384r1", &algo, NULL); if (!curve || algo == PUBKEY_ALGO_EDDSA) return gpg_error (GPG_ERR_UNKNOWN_CURVE); algo = PUBKEY_ALGO_KYBER; From 14534e72e1135a0323b896339bd1f508a592a7be Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 14 May 2024 15:48:45 +0900 Subject: [PATCH 476/869] dirmngr: Fix a call of calloc. * dirmngr/ldap-parse-uri.c (ldap_parse_uri): Fix arguments. -- Signed-off-by: NIIBE Yutaka --- dirmngr/ldap-parse-uri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dirmngr/ldap-parse-uri.c b/dirmngr/ldap-parse-uri.c index 573bcc77f..5856c1b4e 100644 --- a/dirmngr/ldap-parse-uri.c +++ b/dirmngr/ldap-parse-uri.c @@ -162,7 +162,7 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri) if (password) { - puri->query = calloc (sizeof (*puri->query), 1); + puri->query = calloc (1, sizeof (*puri->query)); if (!puri->query) { err = gpg_err_code_from_syserror (); From 0cb7f6fbb7cadff4ab4d390475176fecc1232017 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 15 May 2024 11:57:49 +0900 Subject: [PATCH 477/869] common: Remove unused function. * common/exechelp-posix.c (my_error): Remove. -- Signed-off-by: NIIBE Yutaka --- common/exechelp-posix.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index 7b20a3796..d90b4e8c7 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -84,12 +84,6 @@ my_error_from_syserror (void) return gpg_err_make (default_errsource, gpg_err_code_from_syserror ()); } -static inline gpg_error_t -my_error (int errcode) -{ - return gpg_err_make (default_errsource, errcode); -} - /* Return the maximum number of currently allowed open file descriptors. Only useful on POSIX systems but returns a value on From e0543f97be007983a0a052df09a852a11331ee5d Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 15 May 2024 15:27:20 +0900 Subject: [PATCH 478/869] tpm2d: Use BYTE type to acces TPM2B object. * tpm2d/tpm2.c (tpm2_SensitiveToDuplicate): Don't use the cast of (TPM2B *). -- While it works (since the actual access is done by the macros), compiler may complain the alignment property of type BYTE * and TPM2B object is different. Signed-off-by: NIIBE Yutaka --- tpm2d/tpm2.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/tpm2d/tpm2.c b/tpm2d/tpm2.c index 3e908ddb1..d0b32ed35 100644 --- a/tpm2d/tpm2.c +++ b/tpm2d/tpm2.c @@ -695,8 +695,8 @@ TPM_RC tpm2_SensitiveToDuplicate (TPMT_SENSITIVE *s, { TPMT_HA hash; const int hlen = TSS_GetDigestSize (nalg); - TPM2B *digest = (TPM2B *)buf; - TPM2B *s2b; + BYTE *digest; + BYTE *s2b; int32_t size; unsigned char null_iv[AES_128_BLOCK_SIZE_BYTES]; UINT16 bsize, written = 0; @@ -707,13 +707,12 @@ TPM_RC tpm2_SensitiveToDuplicate (TPMT_SENSITIVE *s, memset (null_iv, 0, sizeof (null_iv)); /* reserve space for hash before the encrypted sensitive */ - bsize = sizeof (digest->size) + hlen; - buf += bsize; + digest = buf; + bsize = sizeof (uint16_t /* TPM2B.size */) + hlen; p->size += bsize; - s2b = (TPM2B *)buf; + s2b = digest + bsize; /* marshal the digest size */ - buf = (BYTE *)&digest->size; bsize = hlen; size = 2; TSS_UINT16_Marshal (&bsize, &written, &buf, &size); @@ -721,13 +720,13 @@ TPM_RC tpm2_SensitiveToDuplicate (TPMT_SENSITIVE *s, /* marshal the unencrypted sensitive in place */ size = sizeof (*s); bsize = 0; - buf = s2b->buffer; + buf = s2b + offsetof (TPM2B, buffer); TSS_TPMT_SENSITIVE_Marshal (s, &bsize, &buf, &size); - buf = (BYTE *)&s2b->size; + buf = s2b; size = 2; TSS_UINT16_Marshal (&bsize, &written, &buf, &size); - bsize = bsize + sizeof (s2b->size); + bsize = bsize + sizeof (uint16_t /* TPM2B.size */); p->size += bsize; /* compute hash of unencrypted marshalled sensitive and @@ -736,7 +735,7 @@ TPM_RC tpm2_SensitiveToDuplicate (TPMT_SENSITIVE *s, TSS_Hash_Generate (&hash, bsize, s2b, name->size, name->name, 0, NULL); - memcpy (digest->buffer, &hash.digest, hlen); + memcpy (digest + offsetof (TPM2B, buffer), &hash.digest, hlen); gcry_cipher_open (&hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE); gcry_cipher_setiv (hd, null_iv, sizeof (null_iv)); @@ -749,20 +748,20 @@ TPM_RC tpm2_SensitiveToDuplicate (TPMT_SENSITIVE *s, else if (symdef->algorithm == TPM_ALG_NULL) { /* Code is for debugging only, should never be used in production */ - TPM2B *s2b = (TPM2B *)buf; + BYTE *s2b = buf; int32_t size = sizeof (*s); UINT16 bsize = 0, written = 0; log_error ("Secret key sent to TPM unencrypted\n"); - buf = s2b->buffer; + buf = s2b + offsetof (TPM2B, buffer); /* marshal the unencrypted sensitive in place */ TSS_TPMT_SENSITIVE_Marshal (s, &bsize, &buf, &size); - buf = (BYTE *)&s2b->size; + buf = s2b; size = 2; TSS_UINT16_Marshal (&bsize, &written, &buf, &size); - p->size += bsize + sizeof (s2b->size); + p->size += bsize + sizeof (uint16_t /* TPM2B.size */); } else { From b36e557c5b05ba21942f385c03988f138d57dfb9 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 15 May 2024 09:56:40 +0200 Subject: [PATCH 479/869] gpg: Terminate key listing on output write error. * g10/keylist.c (list_all): Handle error from list_keyblock. (list_one): Ditto. (locate_one): Ditto. (list_keyblock): Detect write error, print, and return it. (list_keyblock_direct): Return error from list_keyblock. * g10/import.c (import_one_real): Break on listing error. -- Test by using gpg -k >/dev/full GnuPG-bug-id: 6185 --- g10/import.c | 4 +++- g10/keygen.c | 5 ++++- g10/keylist.c | 53 +++++++++++++++++++++++++++++++++++---------------- g10/main.h | 4 ++-- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/g10/import.c b/g10/import.c index ff8847cb6..bbeeebdfe 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2175,10 +2175,12 @@ import_one_real (ctrl_t ctrl, merge_keys_done = 1; /* Note that we do not want to show the validity because the key * has not yet imported. */ - list_keyblock_direct (ctrl, keyblock, from_sk, 0, + err = list_keyblock_direct (ctrl, keyblock, from_sk, 0, opt.fingerprint || opt.with_fingerprint, 1); es_fflush (es_stdout); no_usable_encr_subkeys_warning (keyblock); + if (err) + goto leave; } /* Write the keyblock to the output and do not actually import. */ diff --git a/g10/keygen.c b/g10/keygen.c index fe9a5d8f2..4bdb9f53a 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -6292,9 +6292,12 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para, list_keyblock_direct (ctrl, pub_root, 0, 1, opt.fingerprint || opt.with_fingerprint, 1); + /* Note that we ignore errors from the list function + * because that would only be an additional info. It + * has already been remarked that the key has been + * created. */ } - if (!opt.batch && (get_parameter_algo (ctrl, para, pKEYTYPE, NULL) == PUBKEY_ALGO_DSA diff --git a/g10/keylist.c b/g10/keylist.c index c6667936d..81d6805a5 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -82,7 +82,7 @@ static estream_t attrib_fp; -static void list_keyblock (ctrl_t ctrl, +static gpg_error_t list_keyblock (ctrl_t ctrl, kbnode_t keyblock, int secret, int has_secret, int fpr, struct keylist_context *listctx); @@ -745,6 +745,7 @@ list_all (ctrl_t ctrl, int secret, int mark_secret) int any_secret; const char *lastresname, *resname; struct keylist_context listctx; + gpg_error_t listerr = 0; memset (&listctx, 0, sizeof (listctx)); if (opt.check_sigs) @@ -802,13 +803,13 @@ list_all (ctrl_t ctrl, int secret, int mark_secret) } } merge_keys_and_selfsig (ctrl, keyblock); - list_keyblock (ctrl, keyblock, secret, any_secret, opt.fingerprint, - &listctx); + listerr = list_keyblock (ctrl, keyblock, secret, any_secret, + opt.fingerprint, &listctx); } release_kbnode (keyblock); keyblock = NULL; } - while (!(rc = keydb_search_next (hd))); + while (!listerr && !(rc = keydb_search_next (hd))); es_fflush (es_stdout); if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND) log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); @@ -839,6 +840,7 @@ list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret) const char *keyring_str = _("Keyring"); int i; struct keylist_context listctx; + gpg_error_t listerr = 0; memset (&listctx, 0, sizeof (listctx)); if (!secret && opt.check_sigs) @@ -887,12 +889,12 @@ list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret) es_putc ('-', es_stdout); es_putc ('\n', es_stdout); } - list_keyblock (ctrl, keyblock, secret, any_secret, - opt.fingerprint, &listctx); + listerr = list_keyblock (ctrl, keyblock, secret, any_secret, + opt.fingerprint, &listctx); } release_kbnode (keyblock); } - while (!getkey_next (ctrl, ctx, NULL, &keyblock)); + while (!listerr && !getkey_next (ctrl, ctx, NULL, &keyblock)); getkey_end (ctrl, ctx); if (opt.check_sigs && !opt.with_colons) @@ -910,12 +912,13 @@ locate_one (ctrl_t ctrl, strlist_t names, int no_local) GETKEY_CTX ctx = NULL; KBNODE keyblock = NULL; struct keylist_context listctx; + gpg_error_t listerr = 0; memset (&listctx, 0, sizeof (listctx)); if (opt.check_sigs) listctx.check_sigs = 1; - for (sl = names; sl; sl = sl->next) + for (sl = names; sl && !listerr; sl = sl->next) { rc = get_best_pubkey_byname (ctrl, no_local? GET_PUBKEY_NO_LOCAL @@ -933,10 +936,11 @@ locate_one (ctrl_t ctrl, strlist_t names, int no_local) { do { - list_keyblock (ctrl, keyblock, 0, 0, opt.fingerprint, &listctx); + listerr = list_keyblock (ctrl, keyblock, 0, 0, + opt.fingerprint, &listctx); release_kbnode (keyblock); } - while (ctx && !getkey_next (ctrl, ctx, NULL, &keyblock)); + while (!listerr && ctx && !getkey_next (ctrl, ctx, NULL, &keyblock)); getkey_end (ctrl, ctx); ctx = NULL; } @@ -2325,11 +2329,18 @@ reorder_keyblock (KBNODE keyblock) } -static void +/* Note: If this function returns an error the caller is expected to + * honor this and stop all further processing. Any error returned + * will be a write error (to stdout) and a diagnostics is always + * printed using log_error. */ +static gpg_error_t list_keyblock (ctrl_t ctrl, KBNODE keyblock, int secret, int has_secret, int fpr, struct keylist_context *listctx) { + gpg_error_t err = 0; + + es_clearerr (es_stdout); reorder_keyblock (keyblock); if (list_filter.selkey) @@ -2347,7 +2358,7 @@ list_keyblock (ctrl_t ctrl, } } if (!selected) - return; /* Skip this one. */ + return 0; /* Skip this one. */ } if (opt.with_colons) @@ -2361,24 +2372,34 @@ list_keyblock (ctrl_t ctrl, else list_keyblock_print (ctrl, keyblock, secret, fpr, listctx); - if (secret) - es_fflush (es_stdout); + if (es_ferror (es_stdout)) + err = gpg_error_from_syserror (); + + if (secret && es_fflush (es_stdout) && !err) + err = gpg_error_from_syserror (); + + if (err) + log_error (_("error writing to stdout: %s\n"), gpg_strerror (err)); + + return err; } /* Public function used by keygen to list a keyblock. If NO_VALIDITY * is set the validity of a key is never shown. */ -void +gpg_error_t list_keyblock_direct (ctrl_t ctrl, kbnode_t keyblock, int secret, int has_secret, int fpr, int no_validity) { struct keylist_context listctx; + gpg_error_t err; memset (&listctx, 0, sizeof (listctx)); listctx.no_validity = !!no_validity; - list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx); + err = list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx); keylist_context_release (&listctx); + return err; } diff --git a/g10/main.h b/g10/main.h index 5123dd03b..2443aa7fe 100644 --- a/g10/main.h +++ b/g10/main.h @@ -470,8 +470,8 @@ void secret_key_list (ctrl_t ctrl, strlist_t list ); gpg_error_t parse_and_set_list_filter (const char *string); void print_subpackets_colon(PKT_signature *sig); void reorder_keyblock (KBNODE keyblock); -void list_keyblock_direct (ctrl_t ctrl, kbnode_t keyblock, int secret, - int has_secret, int fpr, int no_validity); +gpg_error_t list_keyblock_direct (ctrl_t ctrl, kbnode_t keyblock, int secret, + int has_secret, int fpr, int no_validity); int cmp_signodes (const void *av, const void *bv); void print_fingerprint (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int mode); From 3bbfcab606bf9af22f5f453d37a026936855b33d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 15 May 2024 12:31:33 +0200 Subject: [PATCH 480/869] Update NEWS -- --- NEWS | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/NEWS b/NEWS index 2182bd225..690dbcf43 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,22 @@ Noteworthy changes in version 2.4.6 (unreleased) ------------------------------------------------ + * gpg: New command --quick-set-ownertrust. [rG967678d972] + + * gpg: Indicate disabled keys in key listings and add list option + "show-ownertrust". [rG2a0a706eb2] + + * gpg: Make sure a DECRYPTION_OKAY is never issued for a bad OCB + tag. [T7042] + + * gpg: Do not allow to accidently set the RENC usage. [T7072] + + * agent: Consider an empty pattern file as valid. [rGc27534de95] + + * agent: Fix error handling of READKEY. [T6012] + + * gpgconf: Check readability of some files with -X and change its + output format. [rG759adb2493] Release-info: https://dev.gnupg.org/T7030 From 0eefa08295b2d19f6f3066b925e001833934a1f0 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 9 Apr 2024 09:24:11 +0900 Subject: [PATCH 481/869] gpg: Allow no CRC24 checksum in armor. * g10/armor.c (radix64_read): Detect the end of armor when there is no CRC24 checksum. -- Cherry-pick master commit of: 3a344d6236521d768793e8b34a96a18ce13bab0e GnuPG-bug-id: 7071 Signed-off-by: NIIBE Yutaka --- g10/armor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g10/armor.c b/g10/armor.c index b47c04ab3..81af15339 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1031,10 +1031,10 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, checkcrc++; break; } - else if (afx->dearmor_state && c == '-' + else if (c == '-' && afx->buffer_pos + 8 < afx->buffer_len && !strncmp (afx->buffer, "-----END ", 8)) { - break; /* End in --dearmor mode. */ + break; /* End in --dearmor mode or No CRC. */ } else { log_error(_("invalid radix64 character %02X skipped\n"), c); From 6b2ebc36a932a53e137c429bc1e385054f3bb5cc Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 15 Apr 2024 10:23:25 +0900 Subject: [PATCH 482/869] scd:openpgp: Robust Data Object handling for constructed case. * scd/app-openpgp.c (get_cached_data): When it comes with its tag and length for the constructed Data Object, remove them. -- Cherry-pick master commit of: 35ef87d8d9db42c3077996317781986a692552cc GnuPG-bug-id: 7058 Signed-off-by: NIIBE Yutaka --- scd/app-openpgp.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 1f5d64e6a..fe0855e77 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -409,6 +409,10 @@ get_cached_data (app_t app, int tag, size_t len; struct cache_s *c; int exmode; + int do_constructed = 0; + + if ((tag < 0x0100 && (tag & 0x20)) || (tag >= 0x0100 && (tag & 0x2000))) + do_constructed = 1; *result = NULL; *resultlen = 0; @@ -451,6 +455,52 @@ get_cached_data (app_t app, int tag, err = iso7816_get_data (app_get_slot (app), exmode, tag, &p, &len); if (err) return err; + + /* When Data Object is constructed, when it comes with its tag and + length, remove them before storing it into the cache, because + it's redundant and takes space. This handling also works well + with the card implementation which doesn't include its tag and + length for the DO value returned by GET DATA. */ + if (do_constructed) + { + if (len && tag < 0x0100 && p[0] == tag) + { + if (len >= 2 && p[1] < 0x80 && p[1] == len - 2) + { + len -= 2; + memmove (p, p+2, len); + } + else if (len >= 3 && p[1] == 0x81 && p[2] == len - 3) + { + len -= 3; + memmove (p, p+3, len); + } + else if (len >= 4 && p[1] == 0x82 && ((p[2] << 8) | p[3]) == len - 4) + { + len -= 4; + memmove (p, p+4, len); + } + } + else if (len >= 2 && tag >= 0x0100 && ((p[0] << 8) | p[1]) == tag) + { + if (len >= 3 && p[2] < 0x80 && p[2] == len - 2) + { + len -= 3; + memmove (p, p+3, len); + } + else if (len >= 4 && p[2] == 0x81 && p[3] == len - 3) + { + len -= 4; + memmove (p, p+4, len); + } + else if (len >= 5 && p[2] == 0x82 && ((p[3] << 8) | p[4]) == len - 4) + { + len -= 5; + memmove (p, p+5, len); + } + } + } + if (len) *result = p; *resultlen = len; From 758cd4ccfc1174390ea72bbfc408472659def02a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 May 2024 09:23:43 +0200 Subject: [PATCH 483/869] po: Enable Dutch translation -- Although it is largely outdated, it does not harm too much. GnuPG-bug-id: 7120 --- po/LINGUAS | 1 + 1 file changed, 1 insertion(+) diff --git a/po/LINGUAS b/po/LINGUAS index cc9cf27ab..5e26a2c3b 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -16,6 +16,7 @@ id it ja nb +nl pl pt ro From 7f661aa129fd5d57ae5247b01143960c5a3c99a7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 May 2024 09:34:00 +0200 Subject: [PATCH 484/869] kbx: Use standard function to setup gcrypt logging in kbxutil. * kbx/kbxutil.c (main): Use setup_libgcrypt_logging. (my_gcry_logger): Remove. --- kbx/kbxutil.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index f5bc8bd77..935dbc735 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -132,28 +132,6 @@ my_strusage( int level ) } -/* Used by gcry for logging */ -static void -my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) -{ - (void)dummy; - - /* Map the log levels. */ - switch (level) - { - case GCRY_LOG_CONT: level = GPGRT_LOGLVL_CONT; break; - case GCRY_LOG_INFO: level = GPGRT_LOGLVL_INFO; break; - case GCRY_LOG_WARN: level = GPGRT_LOGLVL_WARN; break; - case GCRY_LOG_ERROR:level = GPGRT_LOGLVL_ERROR; break; - case GCRY_LOG_FATAL:level = GPGRT_LOGLVL_FATAL; break; - case GCRY_LOG_BUG: level = GPGRT_LOGLVL_BUG; break; - case GCRY_LOG_DEBUG:level = GPGRT_LOGLVL_DEBUG; break; - default: level = GPGRT_LOGLVL_ERROR; break; - } - log_logv (level, fmt, arg_ptr); -} - - /* static void */ /* wrong_args( const char *text ) */ @@ -480,8 +458,7 @@ main (int argc, char **argv) /* Make sure that our subsystems are ready. */ i18n_init (); init_common_subsystems (&argc, &argv); - - gcry_set_log_handler (my_gcry_logger, NULL); + setup_libgcrypt_logging (); /*create_dotlock(NULL); register locking cleanup */ From 5355d0885512211d3f9a00001ad73e3c87f54fc7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 May 2024 09:33:24 +0200 Subject: [PATCH 485/869] card: Fix compiler warning. * tools/gpg-card.h (opt): Make gpg_program, gpgsm_program, and agent_program const. --- tools/gpg-card.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/gpg-card.h b/tools/gpg-card.h index 8d7975ba9..5b49ef31e 100644 --- a/tools/gpg-card.h +++ b/tools/gpg-card.h @@ -34,9 +34,9 @@ struct unsigned int debug; int quiet; int with_colons; - char *gpg_program; - char *gpgsm_program; - char *agent_program; + const char *gpg_program; + const char *gpgsm_program; + const char *agent_program; int autostart; int no_key_lookup; /* Assume --no-key-lookup for "list". */ From cdc798db5c6b0d2886701df84dffbbd6852dc0b8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 22 May 2024 10:45:49 +0200 Subject: [PATCH 486/869] tools: Fix help output for gpg-authcode-sign.sh -- --- tools/gpg-authcode-sign.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/gpg-authcode-sign.sh b/tools/gpg-authcode-sign.sh index 0f6a34824..56b743b94 100644 --- a/tools/gpg-authcode-sign.sh +++ b/tools/gpg-authcode-sign.sh @@ -20,8 +20,8 @@ usage() cat < Date: Wed, 22 May 2024 10:46:58 +0200 Subject: [PATCH 487/869] scd:openpgp: Add new vendor. -- --- scd/app-openpgp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index c2a8d5ffe..5882153eb 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -311,6 +311,7 @@ get_manufacturer (unsigned int no) case 0x000E: return "Excelsecu"; case 0x000F: return "Nitrokey"; case 0x0010: return "NeoPGP"; + case 0x0011: return "Token2"; case 0x002A: return "Magrathea"; case 0x0042: return "GnuPG e.V."; From 2e4b1f78505513c333532755a715bce0f5ad3c99 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 28 May 2024 11:52:04 +0200 Subject: [PATCH 488/869] tpm: Do not use fprintf for logging. * tpm2d/intel-tss.h (TSS_Create): Replace fprintf logging by log_error. --- tpm2d/intel-tss.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tpm2d/intel-tss.h b/tpm2d/intel-tss.h index 53da5cee2..1649cca05 100644 --- a/tpm2d/intel-tss.h +++ b/tpm2d/intel-tss.h @@ -300,7 +300,7 @@ TSS_Create(TSS_CONTEXT **tssContext) } else { - fprintf(stderr, "Unknown TPM_INTERFACE_TYPE %s\n", intType); + log_error ("tss: Unknown TPM_INTERFACE_TYPE %s\n", intType); } } @@ -352,15 +352,15 @@ TSS_Hash_Generate(TPMT_HA *digest, ...) rc = TSS_Hash_GetMd(&algo, digest->hashAlg); if (rc) { - fprintf(stderr, "TSS_HASH_GENERATE: Unknown hash %d\n", - digest->hashAlg); + log_error ("TSS_Hash_Generate: Unknown hash %d\n", digest->hashAlg); goto out; } rc = gcry_md_open (&md, algo, 0); if (rc != 0) { - fprintf(stderr, "TSS_Hash_Generate: EVP_MD_CTX_create failed\n"); + log_error ("TSS_Hash_Generate: EVP_MD_CTX_create failed: %s\n", + gpg_strerror (rc)); rc = TPM_RC_FAILURE; goto out; } @@ -374,7 +374,7 @@ TSS_Hash_Generate(TPMT_HA *digest, ...) break; if (length < 0) { - fprintf(stderr, "TSS_Hash_Generate: Length is negative\n"); + log_error ("TSS_Hash_Generate: Length is negative\n"); goto out_free; } if (length != 0) @@ -408,9 +408,8 @@ tpm2_error(TPM_RC rc, const char *reason) { const char *msg; - fprintf(stderr, "%s failed with %d\n", reason, rc); msg = Tss2_RC_Decode(rc); - fprintf(stderr, "%s\n", msg); + log_error ("%s failed with error %d (%s)\n", reason, rc, msg); } static inline int From d631c8198c254107c0a4e704511fa0f33d3dda5f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 28 May 2024 12:45:21 +0200 Subject: [PATCH 489/869] tpm: Improve error handling and check returned lengths. * tpm2d/command.c (cmd_pkdecrypt): Handle unknown algo. Also slightly rework error handling. * tpm2d/tpm2.c (sexp_to_tpm2_public_ecc): Check length before checking for 0x04. Rework error handling. (tpm2_ObjectPublic_GetName): Check the return value of TSS_GetDigestSize before use. Erro handling rework. (tpm2_SensitiveToDuplicate): Ditto. (tpm2_import_key): Ditto. * tpm2d/intel-tss.h (TSS_Hash_Generate): Check passed length for negative values. Check return value of TSS_GetDigestSize. Use dedicated 16 bit length variable. -- These are reworked and improved fixes as reported in GnuPG-bug-id: 7129 --- tpm2d/command.c | 12 ++-- tpm2d/intel-tss.h | 23 +++++--- tpm2d/tpm2.c | 141 +++++++++++++++++++++++++++++----------------- 3 files changed, 110 insertions(+), 66 deletions(-) diff --git a/tpm2d/command.c b/tpm2d/command.c index 6f8cb5506..8f69a5e11 100644 --- a/tpm2d/command.c +++ b/tpm2d/command.c @@ -291,12 +291,12 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int rc; - unsigned char *shadow_info; + unsigned char *shadow_info = NULL; size_t len; TSS_CONTEXT *tssc; TPM_HANDLE key; TPMI_ALG_PUBLIC type; - unsigned char *crypto; + unsigned char *crypto = NULL; size_t cryptolen; char *buf; size_t buflen; @@ -313,7 +313,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) rc = assuan_inquire (ctx, "EXTRA", &crypto, &cryptolen, MAXLEN_KEYDATA); if (rc) - goto out_freeshadow; + goto out; rc = tpm2_start (&tssc); if (rc) @@ -329,6 +329,11 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) else if (type == TPM_ALG_ECC) rc = tpm2_ecc_decrypt (ctrl, tssc, key, pin_cb, crypto, cryptolen, &buf, &buflen); + else + { + rc = GPG_ERR_PUBKEY_ALGO; + goto end_out; + } tpm2_flush_handle (tssc, key); @@ -343,7 +348,6 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) out: xfree (crypto); - out_freeshadow: xfree (shadow_info); return rc; diff --git a/tpm2d/intel-tss.h b/tpm2d/intel-tss.h index 1649cca05..da085fac7 100644 --- a/tpm2d/intel-tss.h +++ b/tpm2d/intel-tss.h @@ -344,7 +344,7 @@ TSS_Hash_Generate(TPMT_HA *digest, ...) int length; uint8_t *buffer; int algo; - gcry_md_hd_t md; + gcry_md_hd_t md = NULL; va_list ap; va_start(ap, digest); @@ -353,7 +353,7 @@ TSS_Hash_Generate(TPMT_HA *digest, ...) if (rc) { log_error ("TSS_Hash_Generate: Unknown hash %d\n", digest->hashAlg); - goto out; + goto leave; } rc = gcry_md_open (&md, algo, 0); @@ -362,7 +362,7 @@ TSS_Hash_Generate(TPMT_HA *digest, ...) log_error ("TSS_Hash_Generate: EVP_MD_CTX_create failed: %s\n", gpg_strerror (rc)); rc = TPM_RC_FAILURE; - goto out; + goto leave; } rc = TPM_RC_FAILURE; @@ -374,19 +374,24 @@ TSS_Hash_Generate(TPMT_HA *digest, ...) break; if (length < 0) { - log_error ("TSS_Hash_Generate: Length is negative\n"); - goto out_free; + log_error ("%s: Length is negative\n", "TSS_Hash_Generate"); + goto leave; } if (length != 0) gcry_md_write (md, buffer, length); } - memcpy (&digest->digest, gcry_md_read (md, algo), - TSS_GetDigestSize(digest->hashAlg)); + length = TSS_GetDigestSize(digest->hashAlg); + if (length < 0) + { + log_error ("%s: Length is negative\n", "TSS_GetDigestSize"); + goto leave; + } + memcpy (&digest->digest, gcry_md_read (md, algo), length); rc = TPM_RC_SUCCESS; - out_free: + + leave: gcry_md_close (md); - out: va_end(ap); return rc; } diff --git a/tpm2d/tpm2.c b/tpm2d/tpm2.c index d0b32ed35..2a49bf99b 100644 --- a/tpm2d/tpm2.c +++ b/tpm2d/tpm2.c @@ -446,46 +446,55 @@ static int sexp_to_tpm2_public_ecc (TPMT_PUBLIC *p, gcry_sexp_t key) { const char *q; - gcry_sexp_t l; - int rc = GPG_ERR_BAD_PUBKEY; + gcry_sexp_t l = NULL; + int rc; size_t len; TPMI_ECC_CURVE curve; - char *curve_name; + char *curve_name = NULL; l = gcry_sexp_find_token (key, "curve", 0); if (!l) - return rc; + { + rc = GPG_ERR_NO_PUBKEY; + goto leave; + } curve_name = gcry_sexp_nth_string (l, 1); if (!curve_name) - goto out; + { + rc = GPG_ERR_INV_CURVE; + goto leave; + } rc = tpm2_ecc_curve (curve_name, &curve); - gcry_free (curve_name); if (rc) - goto out; - gcry_sexp_release (l); + goto leave; + gcry_sexp_release (l); l = gcry_sexp_find_token (key, "q", 0); if (!l) - return rc; + { + rc = GPG_ERR_NO_PUBKEY; + goto leave; + } q = gcry_sexp_nth_data (l, 1, &len); /* This is a point representation, the first byte tells you what * type. The only format we understand is uncompressed (0x04) * which has layout 0x04 | x | y */ - if (q[0] != 0x04) + if (!q || len < 2 || q[0] != 0x04) { - log_error ("Point format for q is not uncompressed\n"); - goto out; + log_error ("tss: point format for q is not uncompressed\n"); + rc = GPG_ERR_BAD_PUBKEY; + goto leave; } q++; len--; /* now should have to equal sized big endian point numbers */ if ((len & 0x01) == 1) { - log_error ("Point format for q has incorrect length\n"); - goto out; + log_error ("tss: point format for q has incorrect length\n"); + rc = GPG_ERR_BAD_PUBKEY; + goto leave; } - - len >>= 1; + len >>= 1; /* Compute length of one coordinate. */ p->type = TPM_ALG_ECC; p->nameAlg = TPM_ALG_SHA256; @@ -502,7 +511,9 @@ sexp_to_tpm2_public_ecc (TPMT_PUBLIC *p, gcry_sexp_t key) VAL_2B (p->unique.ecc.x, size) = len; memcpy (VAL_2B (p->unique.ecc.y, buffer), q + len, len); VAL_2B (p->unique.ecc.y, size) = len; - out: + + leave: + gcry_free (curve_name); gcry_sexp_release (l); return rc; } @@ -637,36 +648,42 @@ tpm2_ObjectPublic_GetName (NAME_2B *name, uint16_t written = 0; TPMT_HA digest; uint32_t sizeInBytes; + INT32 size = MAX_RESPONSE_SIZE; uint8_t buffer[MAX_RESPONSE_SIZE]; + uint8_t *buffer1 = buffer; + TPMI_ALG_HASH nameAlgNbo; + int length; /* marshal the TPMT_PUBLIC */ - if (rc == 0) - { - INT32 size = MAX_RESPONSE_SIZE; - uint8_t *buffer1 = buffer; - rc = TSS_TPMT_PUBLIC_Marshal (tpmtPublic, &written, &buffer1, &size); - } - /* hash the public area */ - if (rc == 0) - { - sizeInBytes = TSS_GetDigestSize (tpmtPublic->nameAlg); - digest.hashAlg = tpmtPublic->nameAlg; /* Name digest algorithm */ - /* generate the TPMT_HA */ - rc = TSS_Hash_Generate (&digest, written, buffer, 0, NULL); - } - if (rc == 0) - { - TPMI_ALG_HASH nameAlgNbo; + rc = TSS_TPMT_PUBLIC_Marshal (tpmtPublic, &written, &buffer1, &size); + if (rc) + goto leave; - /* copy the digest */ - memcpy (name->name + sizeof (TPMI_ALG_HASH), - (uint8_t *)&digest.digest, sizeInBytes); - /* copy the hash algorithm */ - nameAlgNbo = htons (tpmtPublic->nameAlg); - memcpy (name->name, (uint8_t *)&nameAlgNbo, sizeof (TPMI_ALG_HASH)); - /* set the size */ - name->size = sizeInBytes + sizeof (TPMI_ALG_HASH); + /* hash the public area */ + length = TSS_GetDigestSize (tpmtPublic->nameAlg); + if (length < 0) + { + rc = TPM_RC_VALUE; + goto leave; } + sizeInBytes = length; + digest.hashAlg = tpmtPublic->nameAlg; /* Name digest algorithm */ + + /* generate the TPMT_HA */ + rc = TSS_Hash_Generate (&digest, written, buffer, 0, NULL); + if (rc) + goto leave; + + /* copy the digest */ + memcpy (name->name + sizeof (TPMI_ALG_HASH), + (uint8_t *)&digest.digest, sizeInBytes); + /* copy the hash algorithm */ + nameAlgNbo = htons (tpmtPublic->nameAlg); + memcpy (name->name, (uint8_t *)&nameAlgNbo, sizeof (TPMI_ALG_HASH)); + /* set the size */ + name->size = sizeInBytes + sizeof (TPMI_ALG_HASH); + + leave: return rc; } @@ -694,7 +711,7 @@ TPM_RC tpm2_SensitiveToDuplicate (TPMT_SENSITIVE *s, && symdef->mode.aes == TPM_ALG_CFB) { TPMT_HA hash; - const int hlen = TSS_GetDigestSize (nalg); + int hlen; BYTE *digest; BYTE *s2b; int32_t size; @@ -706,6 +723,14 @@ TPM_RC tpm2_SensitiveToDuplicate (TPMT_SENSITIVE *s, * the AES routines alter the passed in iv */ memset (null_iv, 0, sizeof (null_iv)); + hlen = TSS_GetDigestSize (nalg); + if (hlen < 0) + { + log_error ("%s: unknown symmetric algo id %d\n", + "TSS_GetDigestSize", (int)nalg); + return TPM_RC_SYMMETRIC; + } + /* reserve space for hash before the encrypted sensitive */ digest = buf; bsize = sizeof (uint16_t /* TPM2B.size */) + hlen; @@ -765,7 +790,7 @@ TPM_RC tpm2_SensitiveToDuplicate (TPMT_SENSITIVE *s, } else { - log_error ("Unknown symmetric algorithm\n"); + log_error ("tss: Unknown symmetric algorithm\n"); return TPM_RC_SYMMETRIC; } @@ -795,7 +820,9 @@ tpm2_import_key (ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_RC rc; uint32_t size; - uint16_t len; + uint16_t u16len; + size_t len; + int dlen; BYTE *buffer; int ret; char *passphrase; @@ -817,14 +844,22 @@ tpm2_import_key (ctrl_t ctrl, TSS_CONTEXT *tssc, /* add an authorization password to the key which the TPM will check */ - ret = pin_cb (ctrl, _("Please enter the TPM Authorization passphrase for the key."), &passphrase); + ret = pin_cb (ctrl, + _("Please enter the TPM Authorization passphrase for the key."), + &passphrase); if (ret) return ret; len = strlen(passphrase); - if (len > TSS_GetDigestSize(objectPublic.publicArea.nameAlg)) + dlen = TSS_GetDigestSize(objectPublic.publicArea.nameAlg); + if (dlen < 0) { - len = TSS_GetDigestSize(objectPublic.publicArea.nameAlg); - log_error ("Truncating Passphrase to TPM allowed %d\n", len); + log_error ("%s: error getting digest size\n", "TSS_GetDigestSize"); + return GPG_ERR_DIGEST_ALGO; + } + if (len > dlen) + { + len = dlen; + log_info ("tss: truncating Passphrase to TPM allowed size of %zu\n", len); } VAL_2B (s.authValue, size) = len; memcpy (VAL_2B (s.authValue, buffer), passphrase, len); @@ -885,16 +920,16 @@ tpm2_import_key (ctrl_t ctrl, TSS_CONTEXT *tssc, size = sizeof (pub); buffer = pub; - len = 0; + u16len = 0; TSS_TPM2B_PUBLIC_Marshal (&objectPublic, - &len, &buffer, &size); + &u16len, &buffer, &size); pub_len = len; size = sizeof (priv); buffer = priv; - len = 0; + u16len = 0; TSS_TPM2B_PRIVATE_Marshal ((TPM2B_PRIVATE *)&outPrivate, - &len, &buffer, &size); + &u16len, &buffer, &size); priv_len = len; *shadow_info = make_tpm2_shadow_info (parent, pub, pub_len, From bcc002cd45d1c6bd51c2b2093f92d396970c082e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 28 May 2024 13:46:36 +0200 Subject: [PATCH 490/869] gpg: Avoid a double free on error in the key generation. * g10/keygen.c (card_store_key_with_backup): Avoid double free and simplify error handling. -- This is part of GnuPG-bug-id: 7129 Co-authored-by: Jakub Jelen --- g10/keygen.c | 53 +++++++++++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/g10/keygen.c b/g10/keygen.c index 4bdb9f53a..0c37f27f8 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -5846,11 +5846,10 @@ static gpg_error_t card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk, const char *backup_dir) { + gpg_error_t err; PKT_public_key *sk; gnupg_isotime_t timestamp; - gpg_error_t err; - char *hexgrip; - int rc; + char *hexgrip = NULL; struct agent_card_info_s info; gcry_cipher_hd_t cipherhd = NULL; char *cache_nonce = NULL; @@ -5858,9 +5857,14 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk, size_t keklen; char *ecdh_param_str = NULL; + memset (&info, 0, sizeof (info)); + sk = copy_public_key (NULL, sub_psk); if (!sk) - return gpg_error_from_syserror (); + { + err = gpg_error_from_syserror (); + goto leave; + } epoch2isotime (timestamp, (time_t)sk->timestamp); if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) @@ -5868,37 +5872,23 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk, ecdh_param_str = ecdh_param_str_from_pk (sk); if (!ecdh_param_str) { - free_public_key (sk); - return gpg_error_from_syserror (); + err = gpg_error_from_syserror (); + goto leave; } } err = hexkeygrip_from_pk (sk, &hexgrip); if (err) - { - xfree (ecdh_param_str); - free_public_key (sk); - goto leave; - } + goto leave; - memset(&info, 0, sizeof (info)); - rc = agent_scd_getattr ("SERIALNO", &info); - if (rc) - { - xfree (ecdh_param_str); - free_public_key (sk); - err = (gpg_error_t)rc; - goto leave; - } + err = agent_scd_getattr ("SERIALNO", &info); + if (err) + goto leave; - rc = agent_keytocard (hexgrip, 2, 1, info.serialno, - timestamp, ecdh_param_str); - xfree (info.serialno); - if (rc) - { - err = (gpg_error_t)rc; - goto leave; - } + err = agent_keytocard (hexgrip, 2, 1, info.serialno, + timestamp, ecdh_param_str); + if (err) + goto leave; err = agent_keywrap_key (ctrl, 1, &kek, &keklen); if (err) @@ -5931,10 +5921,13 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk, if (err) log_error ("writing card key to backup file: %s\n", gpg_strerror (err)); else - /* Remove secret key data in agent side. */ - agent_scd_learn (NULL, 1); + { + /* Remove secret key data in agent side. */ + agent_scd_learn (NULL, 1); + } leave: + xfree (info.serialno); xfree (ecdh_param_str); xfree (cache_nonce); gcry_cipher_close (cipherhd); From 021c27510b52f86a95ae70b5f4ed5d2c3886c3e8 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 28 May 2024 13:54:57 +0200 Subject: [PATCH 491/869] wks: Make sure that ERR is always initialized. * tools/wks-util.c (install_key_from_spec_file): Initialize ERR in case the loop is never run. -- This is part of GnuPG-bug-id: 7129 Co-authored-by: Jakub Jelen --- tools/wks-util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/wks-util.c b/tools/wks-util.c index 4a15d672a..fed568873 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -1185,6 +1185,7 @@ install_key_from_spec_file (const char *fname) goto leave; } + err = 0; while (es_read_line (fp, &line, &linelen, &maxlen) > 0) { if (!maxlen) From fdc5003956407da1984f40fc27115e4704587e15 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 28 May 2024 16:37:25 +0200 Subject: [PATCH 492/869] agent: Make sure to return success in ephemeral store mode. * agent/genkey.c (store_key): Clear ERR on success. -- This fixes a real problem which might let ephemeral store mode fail randomly. This is part of GnuPG-bug-id: 7129 Co-authored-by: Jakub Jelen --- agent/genkey.c | 1 + 1 file changed, 1 insertion(+) diff --git a/agent/genkey.c b/agent/genkey.c index 503a7eb53..bb7e74e9b 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -116,6 +116,7 @@ store_key (ctrl_t ctrl, gcry_sexp_t private, ek->keybuf = buf; buf = NULL; ek->keybuflen = len; + err = 0; } else err = agent_write_private_key (ctrl, grip, buf, len, force, From bdbf5cee2ff5bc0773011abde4074003ef9dac70 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 28 May 2024 16:44:18 +0200 Subject: [PATCH 493/869] agent: Avoid double free of empty string in the PIN caching. * agent/call-scd.c (handle_pincache_get): Set PIN to NULL. Also add DBG_CACHE conditionals and don't return the pin in the debug output. -- This is part of GnuPG-bug-id: 7129 Co-authored-by: Jakub Jelen --- agent/call-scd.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/agent/call-scd.c b/agent/call-scd.c index 3da16e619..ed6bd687e 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -196,7 +196,8 @@ handle_pincache_get (const char *args, assuan_context_t ctx) const char *key; char *pin = NULL; - log_debug ("%s: enter '%s'\n", __func__, args); + if (DBG_CACHE) + log_debug ("%s: enter '%s'\n", __func__, args); key = args; if (strlen (key) < 5) { @@ -210,11 +211,14 @@ handle_pincache_get (const char *args, assuan_context_t ctx) if (!pin || !*pin) { xfree (pin); + pin = NULL; err = 0; /* Not found is indicated by sending no data back. */ - log_debug ("%s: not cached\n", __func__); + if (DBG_CACHE) + log_debug ("%s: not cached\n", __func__); goto leave; } - log_debug ("%s: cache returned '%s'\n", __func__, pin); + if (DBG_CACHE) + log_debug ("%s: cache returned '%s'\n", __func__, "[hidden]"/*pin*/); err = assuan_send_data (ctx, pin, strlen (pin)); leave: From 379fc5569d604c4a7b5f12b2bbfc4106893c2a9e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 28 May 2024 16:50:59 +0200 Subject: [PATCH 494/869] agent: Avoid uninitialized access in GENKEY command on parameter error. * agent/command.c (cmd_genkey): Moved init_membuf to the top. -- Signed-off-by: Jakub Jelen This is part of GnuPG-bug-id: 7129 --- agent/command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/command.c b/agent/command.c index b152a5ea4..417a8815f 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1170,6 +1170,8 @@ cmd_genkey (assuan_context_t ctx, char *line) int c; unsigned int flags = 0; + init_membuf (&outbuf, 512); + if (ctrl->restricted) return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); @@ -1227,8 +1229,6 @@ cmd_genkey (assuan_context_t ctx, char *line) if (rc) goto leave; - init_membuf (&outbuf, 512); - /* If requested, ask for the password to be used for the key. If this is not used the regular Pinentry mechanism is used. */ if (opt_inq_passwd && !(flags & GENKEY_FLAG_NO_PROTECTION)) From 4c1b0070354db0b9b0516d9e5453e47fc03a0aac Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 28 May 2024 16:57:41 +0200 Subject: [PATCH 495/869] scd: Avoid buffer overrun with more than 16 PC/SC readers. * scd/apdu.c (apdu_dev_list_start): Fix end condition. -- Signed-off-by: Jakub Jelen This is part of GnuPG-bug-id: 7129 Fixes-commit: e8534f899915a039610973a84042cbe25a5e7ce2 --- scd/apdu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scd/apdu.c b/scd/apdu.c index 98158648b..2e38a273a 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2094,7 +2094,7 @@ apdu_dev_list_start (const char *portstr, struct dev_list **l_p) nreader -= n + 1; p += n + 1; dl->idx_max++; - if (dl->idx_max > MAX_READER) + if (dl->idx_max >= MAX_READER) { log_error ("too many readers from pcsc_list_readers\n"); dl->idx_max--; From 28c705a3be5c4aec477719d652b503568abc88a0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 28 May 2024 17:08:12 +0200 Subject: [PATCH 496/869] gpgsm: Silence a lint warning * sm/keydb.c (keydb_search): Init skipped. -- Skipped is not actually used. This is part of GnuPG-bug-id: 7129 Reported-by: Jakub Jelen --- sm/keydb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sm/keydb.c b/sm/keydb.c index 151ae8103..9d704a110 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -1611,7 +1611,7 @@ keydb_search (ctrl_t ctrl, KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) { gpg_error_t err = gpg_error (GPG_ERR_EOF); - unsigned long skipped; + unsigned long skipped = 0; int i; if (!hd) From dcb0b6fd4822107d68bcb046d4d0650d02c82522 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 28 May 2024 17:15:03 +0200 Subject: [PATCH 497/869] gpgsm: Avoid double free when checking rsaPSS signatures. * sm/certcheck.c (gpgsm_check_cms_signature): Do not free s_sig on error. Its owned and freed by the caller. -- This is part of GnuPG-bug-id: 7129 Signed-off-by: Jakub Jelen Fixes-commit: 969abcf40cdfc65f3ee859c5e62889e1a8ccde91 --- sm/certcheck.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sm/certcheck.c b/sm/certcheck.c index f4db858c3..ef1b6ec54 100644 --- a/sm/certcheck.c +++ b/sm/certcheck.c @@ -630,13 +630,11 @@ gpgsm_check_cms_signature (ksba_cert_t cert, gcry_sexp_t s_sig, rc = extract_pss_params (s_sig, &algo, &saltlen); if (rc) { - gcry_sexp_release (s_sig); return rc; } 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); } } From 9adaa79ab43e2f87178b8ee5ab1a353cba384606 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 28 May 2024 17:19:37 +0200 Subject: [PATCH 498/869] gpg-auth: Fix use after free. * tools/gpg-auth.c (ssh_authorized_keys): Move free after printing error message. -- Signed-off-by: Jakub Jelen This is part of GnuPG-bug-id: 7129 --- tools/gpg-auth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gpg-auth.c b/tools/gpg-auth.c index a818bee5d..c47bb4e54 100644 --- a/tools/gpg-auth.c +++ b/tools/gpg-auth.c @@ -818,7 +818,6 @@ ssh_authorized_keys (const char *user, struct ssh_key_list **r_ssh_key_list) xfree (fname); return err; } - xfree (fname); maxlen = 2048; /* Set limit. */ while ((len = es_read_line (fp, &line, &length_of_line, &maxlen)) > 0) @@ -861,6 +860,7 @@ ssh_authorized_keys (const char *user, struct ssh_key_list **r_ssh_key_list) *r_ssh_key_list = ssh_key_list; leave: + xfree (fname); xfree (line); es_fclose (fp); return err; From aedeef6acf5b824fd44bb012ef07e79f6937db65 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 30 May 2024 13:36:58 +0900 Subject: [PATCH 499/869] m4: Update from each library. * m4/ksba.m4: Update from its master. * m4/libassuan.m4: Ditto. * m4/libgcrypt.m4: Ditto. -- Signed-off-by: NIIBE Yutaka --- m4/ksba.m4 | 93 ++++++++++++++++++++++++++++++++++++++++++++++-- m4/libassuan.m4 | 91 +++++++++++++++++++++++++++++++++++++++++++++-- m4/libgcrypt.m4 | 94 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 270 insertions(+), 8 deletions(-) diff --git a/m4/ksba.m4 b/m4/ksba.m4 index 452c24588..c9dab35de 100644 --- a/m4/ksba.m4 +++ b/m4/ksba.m4 @@ -1,5 +1,5 @@ # ksba.m4 - autoconf macro to detect ksba -# Copyright (C) 2002, 2018 g10 Code GmbH +# Copyright (C) 2002, 2018, 2024 g10 Code GmbH # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without @@ -9,7 +9,93 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# Last-changed: 2022-11-01 +# Last-changed: 2024-05-14 + +dnl +dnl Find gpgrt-config, which uses .pc file +dnl (minimum pkg-config functionality, supporting cross build) +dnl +dnl _AM_PATH_GPGRT_CONFIG +AC_DEFUN([_AM_PATH_GPGRT_CONFIG],[dnl + AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no, [$prefix/bin:$PATH]) + if test "$GPGRT_CONFIG" != "no"; then + # Determine gpgrt_libdir + # + # Get the prefix of gpgrt-config assuming it's something like: + # /bin/gpgrt-config + gpgrt_prefix=${GPGRT_CONFIG%/*/*} + possible_libdir1=${gpgrt_prefix}/lib + # Determine by using system libdir-format with CC, it's like: + # Normal style: /usr/lib + # GNU cross style: /usr//lib + # Debian style: /usr/lib/ + # Fedora/openSUSE style: /usr/lib, /usr/lib32 or /usr/lib64 + # It is assumed that CC is specified to the one of host on cross build. + if libdir_candidates=$(${CC:-cc} -print-search-dirs | \ + sed -n -e "/^libraries/{s/libraries: =//;s/:/\\ +/g;p;}"); then + # From the output of -print-search-dirs, select valid pkgconfig dirs. + libdir_candidates=$(for dir in $libdir_candidates; do + if p=$(cd $dir 2>/dev/null && pwd); then + test -d "$p/pkgconfig" && echo $p; + fi + done) + + for possible_libdir0 in $libdir_candidates; do + # possible_libdir0: + # Fallback candidate, the one of system-installed (by $CC) + # (/usr//lib, /usr/lib/ or /usr/lib32) + # possible_libdir1: + # Another candidate, user-locally-installed + # (/lib) + # possible_libdir2 + # Most preferred + # (//lib, + # /lib/ or /lib32) + if test "${possible_libdir0##*/}" = "lib"; then + possible_prefix0=${possible_libdir0%/lib} + possible_prefix0_triplet=${possible_prefix0##*/} + if test -z "$possible_prefix0_triplet"; then + continue + fi + possible_libdir2=${gpgrt_prefix}/$possible_prefix0_triplet/lib + else + possible_prefix0=${possible_libdir0%%/lib*} + possible_libdir2=${gpgrt_prefix}${possible_libdir0#$possible_prefix0} + fi + if test -f ${possible_libdir2}/pkgconfig/gpg-error.pc; then + gpgrt_libdir=${possible_libdir2} + elif test -f ${possible_libdir1}/pkgconfig/gpg-error.pc; then + gpgrt_libdir=${possible_libdir1} + elif test -f ${possible_libdir0}/pkgconfig/gpg-error.pc; then + gpgrt_libdir=${possible_libdir0} + fi + if test -n "$gpgrt_libdir"; then break; fi + done + fi + if test -z "$gpgrt_libdir"; then + # No valid pkgconfig dir in any of the system directories, fallback + gpgrt_libdir=${possible_libdir1} + fi + else + unset GPGRT_CONFIG + fi + + if test -n "$gpgrt_libdir"; then + GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir" + if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then + GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error" + AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config]) + gpg_error_config_version=`$GPG_ERROR_CONFIG --modversion` + else + gpg_error_config_version=`$GPG_ERROR_CONFIG --version` + unset GPGRT_CONFIG + fi + elif test "$GPG_ERROR_CONFIG" != "no"; then + gpg_error_config_version=`$GPG_ERROR_CONFIG --version` + unset GPGRT_CONFIG + fi +]) dnl AM_PATH_KSBA([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) @@ -22,7 +108,8 @@ dnl this features allows to prevent build against newer versions of libksba dnl with a changed API. dnl AC_DEFUN([AM_PATH_KSBA], -[ AC_REQUIRE([AC_CANONICAL_HOST]) +[ AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([_AM_PATH_GPGRT_CONFIG])dnl dnl --with-libksba-prefix=PFX is the preferred name for this option, dnl since that is consistent with how our three siblings use the directory/ dnl package name in --with-$dir_name-prefix=PFX. diff --git a/m4/libassuan.m4 b/m4/libassuan.m4 index a2eb5d973..c1da8a9a8 100644 --- a/m4/libassuan.m4 +++ b/m4/libassuan.m4 @@ -9,14 +9,101 @@ dnl This file is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dnl SPDX-License-Identifier: FSFULLR -# Last-changed: 2023-07-26 +# Last-changed: 2024-05-14 + +dnl +dnl Find gpgrt-config, which uses .pc file +dnl (minimum pkg-config functionality, supporting cross build) +dnl +dnl _AM_PATH_GPGRT_CONFIG +AC_DEFUN([_AM_PATH_GPGRT_CONFIG],[dnl + AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no, [$prefix/bin:$PATH]) + if test "$GPGRT_CONFIG" != "no"; then + # Determine gpgrt_libdir + # + # Get the prefix of gpgrt-config assuming it's something like: + # /bin/gpgrt-config + gpgrt_prefix=${GPGRT_CONFIG%/*/*} + possible_libdir1=${gpgrt_prefix}/lib + # Determine by using system libdir-format with CC, it's like: + # Normal style: /usr/lib + # GNU cross style: /usr//lib + # Debian style: /usr/lib/ + # Fedora/openSUSE style: /usr/lib, /usr/lib32 or /usr/lib64 + # It is assumed that CC is specified to the one of host on cross build. + if libdir_candidates=$(${CC:-cc} -print-search-dirs | \ + sed -n -e "/^libraries/{s/libraries: =//;s/:/\\ +/g;p;}"); then + # From the output of -print-search-dirs, select valid pkgconfig dirs. + libdir_candidates=$(for dir in $libdir_candidates; do + if p=$(cd $dir 2>/dev/null && pwd); then + test -d "$p/pkgconfig" && echo $p; + fi + done) + + for possible_libdir0 in $libdir_candidates; do + # possible_libdir0: + # Fallback candidate, the one of system-installed (by $CC) + # (/usr//lib, /usr/lib/ or /usr/lib32) + # possible_libdir1: + # Another candidate, user-locally-installed + # (/lib) + # possible_libdir2 + # Most preferred + # (//lib, + # /lib/ or /lib32) + if test "${possible_libdir0##*/}" = "lib"; then + possible_prefix0=${possible_libdir0%/lib} + possible_prefix0_triplet=${possible_prefix0##*/} + if test -z "$possible_prefix0_triplet"; then + continue + fi + possible_libdir2=${gpgrt_prefix}/$possible_prefix0_triplet/lib + else + possible_prefix0=${possible_libdir0%%/lib*} + possible_libdir2=${gpgrt_prefix}${possible_libdir0#$possible_prefix0} + fi + if test -f ${possible_libdir2}/pkgconfig/gpg-error.pc; then + gpgrt_libdir=${possible_libdir2} + elif test -f ${possible_libdir1}/pkgconfig/gpg-error.pc; then + gpgrt_libdir=${possible_libdir1} + elif test -f ${possible_libdir0}/pkgconfig/gpg-error.pc; then + gpgrt_libdir=${possible_libdir0} + fi + if test -n "$gpgrt_libdir"; then break; fi + done + fi + if test -z "$gpgrt_libdir"; then + # No valid pkgconfig dir in any of the system directories, fallback + gpgrt_libdir=${possible_libdir1} + fi + else + unset GPGRT_CONFIG + fi + + if test -n "$gpgrt_libdir"; then + GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir" + if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then + GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error" + AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config]) + gpg_error_config_version=`$GPG_ERROR_CONFIG --modversion` + else + gpg_error_config_version=`$GPG_ERROR_CONFIG --version` + unset GPGRT_CONFIG + fi + elif test "$GPG_ERROR_CONFIG" != "no"; then + gpg_error_config_version=`$GPG_ERROR_CONFIG --version` + unset GPGRT_CONFIG + fi +]) dnl dnl Common code used for libassuan detection [internal] dnl Returns ok set to yes or no. dnl AC_DEFUN([_AM_PATH_LIBASSUAN_COMMON], -[ AC_REQUIRE([AC_CANONICAL_HOST]) +[ AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([_AM_PATH_GPGRT_CONFIG])dnl AC_ARG_WITH(libassuan-prefix, AS_HELP_STRING([--with-libassuan-prefix=PFX], [prefix where LIBASSUAN is installed (optional)]), diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 index cd4249e87..309d941a2 100644 --- a/m4/libgcrypt.m4 +++ b/m4/libgcrypt.m4 @@ -1,5 +1,6 @@ # libgcrypt.m4 - Autoconf macros to detect libgcrypt -# Copyright (C) 2002, 2003, 2004, 2011, 2014, 2018, 2020 g10 Code GmbH +# Copyright (C) 2002, 2003, 2004, 2011, 2014, 2018, 2020, +# 2024 g10 Code GmbH # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without @@ -9,9 +10,95 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# Last-changed: 2022-11-01 +# Last-changed: 2024-05-14 +dnl +dnl Find gpgrt-config, which uses .pc file +dnl (minimum pkg-config functionality, supporting cross build) +dnl +dnl _AM_PATH_GPGRT_CONFIG +AC_DEFUN([_AM_PATH_GPGRT_CONFIG],[dnl + AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no, [$prefix/bin:$PATH]) + if test "$GPGRT_CONFIG" != "no"; then + # Determine gpgrt_libdir + # + # Get the prefix of gpgrt-config assuming it's something like: + # /bin/gpgrt-config + gpgrt_prefix=${GPGRT_CONFIG%/*/*} + possible_libdir1=${gpgrt_prefix}/lib + # Determine by using system libdir-format with CC, it's like: + # Normal style: /usr/lib + # GNU cross style: /usr//lib + # Debian style: /usr/lib/ + # Fedora/openSUSE style: /usr/lib, /usr/lib32 or /usr/lib64 + # It is assumed that CC is specified to the one of host on cross build. + if libdir_candidates=$(${CC:-cc} -print-search-dirs | \ + sed -n -e "/^libraries/{s/libraries: =//;s/:/\\ +/g;p;}"); then + # From the output of -print-search-dirs, select valid pkgconfig dirs. + libdir_candidates=$(for dir in $libdir_candidates; do + if p=$(cd $dir 2>/dev/null && pwd); then + test -d "$p/pkgconfig" && echo $p; + fi + done) + + for possible_libdir0 in $libdir_candidates; do + # possible_libdir0: + # Fallback candidate, the one of system-installed (by $CC) + # (/usr//lib, /usr/lib/ or /usr/lib32) + # possible_libdir1: + # Another candidate, user-locally-installed + # (/lib) + # possible_libdir2 + # Most preferred + # (//lib, + # /lib/ or /lib32) + if test "${possible_libdir0##*/}" = "lib"; then + possible_prefix0=${possible_libdir0%/lib} + possible_prefix0_triplet=${possible_prefix0##*/} + if test -z "$possible_prefix0_triplet"; then + continue + fi + possible_libdir2=${gpgrt_prefix}/$possible_prefix0_triplet/lib + else + possible_prefix0=${possible_libdir0%%/lib*} + possible_libdir2=${gpgrt_prefix}${possible_libdir0#$possible_prefix0} + fi + if test -f ${possible_libdir2}/pkgconfig/gpg-error.pc; then + gpgrt_libdir=${possible_libdir2} + elif test -f ${possible_libdir1}/pkgconfig/gpg-error.pc; then + gpgrt_libdir=${possible_libdir1} + elif test -f ${possible_libdir0}/pkgconfig/gpg-error.pc; then + gpgrt_libdir=${possible_libdir0} + fi + if test -n "$gpgrt_libdir"; then break; fi + done + fi + if test -z "$gpgrt_libdir"; then + # No valid pkgconfig dir in any of the system directories, fallback + gpgrt_libdir=${possible_libdir1} + fi + else + unset GPGRT_CONFIG + fi + + if test -n "$gpgrt_libdir"; then + GPGRT_CONFIG="$GPGRT_CONFIG --libdir=$gpgrt_libdir" + if $GPGRT_CONFIG gpg-error >/dev/null 2>&1; then + GPG_ERROR_CONFIG="$GPGRT_CONFIG gpg-error" + AC_MSG_NOTICE([Use gpgrt-config with $gpgrt_libdir as gpg-error-config]) + gpg_error_config_version=`$GPG_ERROR_CONFIG --modversion` + else + gpg_error_config_version=`$GPG_ERROR_CONFIG --version` + unset GPGRT_CONFIG + fi + elif test "$GPG_ERROR_CONFIG" != "no"; then + gpg_error_config_version=`$GPG_ERROR_CONFIG --version` + unset GPGRT_CONFIG + fi +]) + dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. @@ -28,7 +115,8 @@ dnl config script does not match the host specification the script dnl is added to the gpg_config_script_warn variable. dnl AC_DEFUN([AM_PATH_LIBGCRYPT], -[ AC_REQUIRE([AC_CANONICAL_HOST]) +[ AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([_AM_PATH_GPGRT_CONFIG])dnl AC_ARG_WITH(libgcrypt-prefix, AS_HELP_STRING([--with-libgcrypt-prefix=PFX], [prefix where LIBGCRYPT is installed (optional)]), From 34045ed9e1235d0d31fde218bb286e4b0d96a73e Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 30 May 2024 13:39:31 +0900 Subject: [PATCH 500/869] common: Fix process termination check at release. * src/exechelp-posix.c (gnupg_process_release): When NOT terminated, terminate and wait. * src/exechelp-w32.c (gnupg_process_release): Likewise. -- Signed-off-by: NIIBE Yutaka --- common/exechelp-posix.c | 2 +- common/exechelp-w32.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index d90b4e8c7..3f124ab80 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -997,7 +997,7 @@ gnupg_process_release (gnupg_process_t process) if (!process) return; - if (process->terminated) + if (!process->terminated) { gnupg_process_terminate (process); gnupg_process_wait (process, 1); diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 08290e442..d1764d1f6 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -1209,7 +1209,7 @@ gnupg_process_release (gnupg_process_t process) if (!process) return; - if (process->terminated) + if (!process->terminated) { gnupg_process_terminate (process); gnupg_process_wait (process, 1); From fc3fde1bdeb260c92b0a3ea7489536129e9a8a93 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 31 May 2024 15:36:39 +0900 Subject: [PATCH 501/869] spawn: Remove spawn callback, introduce gnupg_spawn_actions. * common/exechelp-posix.c (call_spawn_cb): Remove. (gnupg_spawn_actions_new, gnupg_spawn_actions_release) (gnupg_spawn_actions_set_environ, gnupg_spawn_actions_set_atfork) (gnupg_spawn_actions_set_redirect) (gnupg_spawn_actions_set_inherit_fds): New. (my_exec, spawn_detached): Use spawn actions. (gnupg_spawn_helper): Remove. (gnupg_process_spawn): Remove callback, introduce gnupg_spawn_actions. * common/exechelp-w32.c: Ditto. * common/exechelp.h: Ditto. * agent/genkey.c (do_check_passphrase_pattern): Follow the change of gnupg_process_spawn API. * common/asshelp.c (start_new_service): Likewise. * common/exectool.c (gnupg_exec_tool_stream): Likewise. * common/t-exechelp.c (test_pipe_stream): Likewise. * dirmngr/ldap-wrapper.c (ldap_wrapper): Likewise. * g10/photoid.c (run_with_pipe): Likewise. * scd/app.c (report_change): Likewise. * tests/gpgscm/ffi.c (do_process_spawn_io, do_process_spawn_fd): Likewise. * tools/gpg-card.c (cmd_gpg): Likewise. * tools/gpgconf-comp.c (gpg_agent_runtime_change): Likewise. (scdaemon_runtime_change, tpm2daemon_runtime_change) (dirmngr_runtime_change, keyboxd_runtime_change) (gc_component_launch, gc_component_check_options) (retrieve_options_from_program): Likewise. * tools/gpgconf.c (show_versions_via_dirmngr): Likewise. * tools/gpgtar-create.c (gpgtar_create): Likewise. * tools/gpgtar-extract.c (gpgtar_extract): Likewise. * tools/gpgtar-list.c (gpgtar_list): Likewise. -- Signed-off-by: NIIBE Yutaka --- agent/genkey.c | 2 +- common/asshelp.c | 5 +- common/exechelp-posix.c | 142 ++++++++++++++++++++++++----------- common/exechelp-w32.c | 161 +++++++++++++++++++++++++++------------- common/exechelp.h | 37 ++++----- common/exectool.c | 14 +++- common/t-exechelp.c | 2 +- dirmngr/ldap-wrapper.c | 2 +- g10/photoid.c | 4 +- scd/app.c | 25 ++++--- tests/gpgscm/ffi.c | 53 +++++++------ tools/gpg-card.c | 2 +- tools/gpgconf-comp.c | 27 +++---- tools/gpgconf.c | 5 +- tools/gpgtar-create.c | 17 ++++- tools/gpgtar-extract.c | 17 ++++- tools/gpgtar-list.c | 17 ++++- 17 files changed, 351 insertions(+), 181 deletions(-) diff --git a/agent/genkey.c b/agent/genkey.c index bb7e74e9b..9a8b3c2aa 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -207,7 +207,7 @@ do_check_passphrase_pattern (ctrl_t ctrl, const char *pw, unsigned int flags) if (gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDIN_PIPE, - NULL, NULL, &proc)) + NULL, &proc)) result = 1; /* Execute error - assume password should no be used. */ else { diff --git a/common/asshelp.c b/common/asshelp.c index 5a40e0380..957ca994d 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -525,11 +525,10 @@ start_new_service (assuan_context_t *r_ctx, { #ifdef HAVE_W32_SYSTEM err = gnupg_process_spawn (program? program : program_name, argv, - GNUPG_PROCESS_DETACHED, - NULL, NULL, NULL); + GNUPG_PROCESS_DETACHED, NULL, NULL); #else /*!W32*/ err = gnupg_process_spawn (program? program : program_name, argv, - 0, NULL, NULL, NULL); + 0, NULL, NULL); #endif /*!W32*/ if (err) log_error ("failed to start %s '%s': %s\n", diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index 3f124ab80..97d8fa4ad 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -182,7 +182,7 @@ get_max_fds (void) which shall not be closed. This list shall be sorted in ascending order with the end marked by -1. */ void -close_all_fds (int first, int *except) +close_all_fds (int first, const int *except) { int max_fd = get_max_fds (); int fd, i, except_start; @@ -429,46 +429,105 @@ posix_open_null (int for_write) return fd; } -static void -call_spawn_cb (struct spawn_cb_arg *sca, - int fd_in, int fd_out, int fd_err, - void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) +struct gnupg_spawn_actions { + int fd[3]; + const int *except_fds; + char **environ; + void (*atfork) (void *); + void *atfork_arg; +}; + +gpg_err_code_t +gnupg_spawn_actions_new (gnupg_spawn_actions_t *r_act) { - sca->fds[0] = fd_in; - sca->fds[1] = fd_out; - sca->fds[2] = fd_err; - sca->except_fds = NULL; - sca->arg = spawn_cb_arg; - if (spawn_cb) - (*spawn_cb) (sca); + gnupg_spawn_actions_t act; + int i; + + *r_act = NULL; + + act = xtrycalloc (1, sizeof (struct gnupg_spawn_actions)); + if (act == NULL) + return gpg_err_code_from_syserror (); + + for (i = 0; i <= 2; i++) + act->fd[i] = -1; + + *r_act = act; + return 0; +} + +void +gnupg_spawn_actions_release (gnupg_spawn_actions_t act) +{ + if (!act) + return; + + xfree (act); +} + +void +gnupg_spawn_actions_set_environ (gnupg_spawn_actions_t act, + char **environ_for_child) +{ + act->environ = environ_for_child; +} + +void +gnupg_spawn_actions_set_atfork (gnupg_spawn_actions_t act, + void (*atfork)(void *), void *arg) +{ + act->atfork = atfork; + act->atfork_arg = arg; +} + +void +gnupg_spawn_actions_set_redirect (gnupg_spawn_actions_t act, + int in, int out, int err) +{ + act->fd[0] = in; + act->fd[1] = out; + act->fd[2] = err; +} + +void +gnupg_spawn_actions_set_inherit_fds (gnupg_spawn_actions_t act, + const int *fds) +{ + act->except_fds = fds; } static void -my_exec (const char *pgmname, const char *argv[], struct spawn_cb_arg *sca) +my_exec (const char *pgmname, const char *argv[], gnupg_spawn_actions_t act) { int i; /* Assign /dev/null to unused FDs. */ for (i = 0; i <= 2; i++) - if (sca->fds[i] == -1) - sca->fds[i] = posix_open_null (i); + if (act->fd[i] == -1) + act->fd[i] = posix_open_null (i); /* Connect the standard files. */ for (i = 0; i <= 2; i++) - if (sca->fds[i] != i) + if (act->fd[i] != i) { - if (dup2 (sca->fds[i], i) == -1) + if (dup2 (act->fd[i], i) == -1) log_fatal ("dup2 std%s failed: %s\n", i==0?"in":i==1?"out":"err", strerror (errno)); /* - * We don't close sca.fds[i] here, but close them by + * We don't close act->fd[i] here, but close them by * close_all_fds. Note that there may be same one in three of - * sca->fds[i]. + * act->fd[i]. */ } /* Close all other files. */ - close_all_fds (3, sca->except_fds); + close_all_fds (3, act->except_fds); + + if (act->environ) + environ = act->environ; + + if (act->atfork) + act->atfork (act->atfork_arg); execv (pgmname, (char *const *)argv); /* No way to print anything, as we have may have closed all streams. */ @@ -477,7 +536,7 @@ my_exec (const char *pgmname, const char *argv[], struct spawn_cb_arg *sca) static gpg_err_code_t spawn_detached (const char *pgmname, const char *argv[], - void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) + gnupg_spawn_actions_t act) { gpg_err_code_t ec; pid_t pid; @@ -510,7 +569,6 @@ spawn_detached (const char *pgmname, const char *argv[], if (!pid) { pid_t pid2; - struct spawn_cb_arg sca; if (setsid() == -1 || chdir ("/")) _exit (1); @@ -521,9 +579,7 @@ spawn_detached (const char *pgmname, const char *argv[], if (pid2) _exit (0); /* Let the parent exit immediately. */ - call_spawn_cb (&sca, -1, -1, -1, spawn_cb, spawn_cb_arg); - - my_exec (pgmname, argv, &sca); + my_exec (pgmname, argv, act); /*NOTREACHED*/ } @@ -532,7 +588,7 @@ spawn_detached (const char *pgmname, const char *argv[], { post_syscall (); ec = gpg_err_code_from_syserror (); - log_error ("waitpid failed in gpgrt_spawn_process_detached: %s", + log_error ("waitpid failed in spawn_detached: %s", gpg_strerror (ec)); return ec; } @@ -542,18 +598,9 @@ spawn_detached (const char *pgmname, const char *argv[], return 0; } -void -gnupg_spawn_helper (struct spawn_cb_arg *sca) -{ - int *user_except = sca->arg; - sca->except_fds = user_except; -} - gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv1[], - unsigned int flags, - void (*spawn_cb) (struct spawn_cb_arg *), - void *spawn_cb_arg, + unsigned int flags, gnupg_spawn_actions_t act, gnupg_process_t *r_process) { gpg_err_code_t ec; @@ -564,6 +611,15 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], pid_t pid; const char **argv; int i, j; + struct gnupg_spawn_actions act_default; + + if (!act) + { + memset (&act_default, 0, sizeof (act_default)); + for (i = 0; i <= 2; i++) + act_default.fd[i] = -1; + act = &act_default; + } check_syscall_func (); @@ -603,7 +659,7 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], return GPG_ERR_INV_ARG; } - return spawn_detached (pgmname, argv, spawn_cb, spawn_cb_arg); + return spawn_detached (pgmname, argv, act); } process = xtrycalloc (1, sizeof (struct gnupg_process)); @@ -732,8 +788,6 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], if (!pid) { - struct spawn_cb_arg sca; - if (fd_in[1] >= 0) close (fd_in[1]); if (fd_out[0] >= 0) @@ -741,11 +795,15 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], if (fd_err[0] >= 0) close (fd_err[0]); - call_spawn_cb (&sca, fd_in[0], fd_out[1], fd_err[1], - spawn_cb, spawn_cb_arg); + if (act->fd[0] < 0) + act->fd[0] = fd_in[0]; + if (act->fd[1] < 0) + act->fd[1] = fd_out[1]; + if (act->fd[2] < 0) + act->fd[2] = fd_err[1]; /* Run child. */ - my_exec (pgmname, argv, &sca); + my_exec (pgmname, argv, act); /*NOTREACHED*/ } diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index d1764d1f6..46fb9ae92 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -65,7 +65,6 @@ #include "util.h" #include "i18n.h" #include "sysutils.h" -#define NEED_STRUCT_SPAWN_CB_ARG #include "exechelp.h" #include @@ -126,7 +125,7 @@ get_max_fds (void) /* Under Windows this is a dummy function. */ void -close_all_fds (int first, int *except) +close_all_fds (int first, const int *except) { (void)first; (void)except; @@ -410,6 +409,12 @@ gnupg_close_pipe (int fd) close (fd); } +struct gnupg_spawn_actions { + void *hd[3]; + void **inherit_hds; + char *env; +}; + struct gnupg_process { const char *pgmname; unsigned int terminated :1; /* or detached */ @@ -479,8 +484,7 @@ check_windows_version (void) static gpg_err_code_t -spawn_detached (const char *pgmname, char *cmdline, - void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) +spawn_detached (const char *pgmname, char *cmdline, gnupg_spawn_actions_t act) { SECURITY_ATTRIBUTES sec_attr; PROCESS_INFORMATION pi = { NULL, 0, 0, 0 }; @@ -490,8 +494,8 @@ spawn_detached (const char *pgmname, char *cmdline, wchar_t *wpgmname = NULL; gpg_err_code_t ec; int ret; - struct spawn_cb_arg sca; BOOL ask_inherit = FALSE; + int i; ec = gnupg_access (pgmname, X_OK); if (ec) @@ -502,22 +506,27 @@ spawn_detached (const char *pgmname, char *cmdline, memset (&si, 0, sizeof si); - sca.allow_foreground_window = FALSE; - sca.hd[0] = INVALID_HANDLE_VALUE; - sca.hd[1] = INVALID_HANDLE_VALUE; - sca.hd[2] = INVALID_HANDLE_VALUE; - sca.inherit_hds = NULL; - sca.arg = spawn_cb_arg; - if (spawn_cb) - (*spawn_cb) (&sca); + i = 0; + if (act->hd[0] != INVALID_HANDLE_VALUE) + i++; + if (act->hd[1] != INVALID_HANDLE_VALUE) + i++; + if (act->hd[2] != INVALID_HANDLE_VALUE) + i++; - if (sca.inherit_hds) + if (i != 0 || act->inherit_hds) { SIZE_T attr_list_size = 0; HANDLE hd[16]; - HANDLE *hd_p = sca.inherit_hds; + HANDLE *hd_p = act->inherit_hds; int j = 0; + if (act->hd[0] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[0]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[1]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[2]; if (hd_p) { while (*hd_p != INVALID_HANDLE_VALUE) @@ -559,7 +568,8 @@ spawn_detached (const char *pgmname, char *cmdline, /* Start the process. */ si.StartupInfo.cb = sizeof (si); - si.StartupInfo.dwFlags = STARTF_USESHOWWINDOW; + si.StartupInfo.dwFlags = ((i > 0 ? STARTF_USESTDHANDLES : 0) + | STARTF_USESHOWWINDOW); si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; cr_flags = (CREATE_DEFAULT_ERROR_MODE @@ -579,7 +589,7 @@ spawn_detached (const char *pgmname, char *cmdline, &sec_attr, /* Thread security attributes. */ ask_inherit, /* Inherit handles. */ cr_flags, /* Creation flags. */ - NULL, /* Environment. */ + act->env, /* Environment. */ NULL, /* Use current drive/directory. */ (STARTUPINFOW *)&si, /* Startup information. */ &pi /* Returns process information. */ @@ -617,18 +627,60 @@ spawn_detached (const char *pgmname, char *cmdline, } -void -gnupg_spawn_helper (struct spawn_cb_arg *sca) +gpg_err_code_t +gnupg_spawn_actions_new (gnupg_spawn_actions_t *r_act) { - HANDLE *user_except = sca->arg; - sca->inherit_hds = user_except; + gnupg_spawn_actions_t act; + int i; + + *r_act = NULL; + + act = xtrycalloc (1, sizeof (struct gnupg_spawn_actions)); + if (act == NULL) + return gpg_err_code_from_syserror (); + + for (i = 0; i <= 2; i++) + act->hd[i] = INVALID_HANDLE_VALUE; + + *r_act = act; + return 0; } +void +gnupg_spawn_actions_release (gnupg_spawn_actions_t act) +{ + if (!act) + return; + + xfree (act); +} + +void +gnupg_spawn_actions_set_envvars (gnupg_spawn_actions_t act, char *env) +{ + act->env = env; +} + +void +gnupg_spawn_actions_set_redirect (gnupg_spawn_actions_t act, + void *in, void *out, void *err) +{ + act->hd[0] = in; + act->hd[1] = out; + act->hd[2] = err; +} + +void +gnupg_spawn_actions_set_inherit_handles (gnupg_spawn_actions_t act, + void **handles) +{ + act->inherit_hds = handles; +} + + gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv[], - unsigned int flags, - void (*spawn_cb) (struct spawn_cb_arg *), - void *spawn_cb_arg, + unsigned int flags, gnupg_spawn_actions_t act, gnupg_process_t *r_process) { gpg_err_code_t ec; @@ -644,9 +696,18 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], HANDLE hd_in[2]; HANDLE hd_out[2]; HANDLE hd_err[2]; - struct spawn_cb_arg sca; int i; BOOL ask_inherit = FALSE; + BOOL allow_foreground_window = FALSE; + struct gnupg_spawn_actions act_default; + + if (!act) + { + memset (&act_default, 0, sizeof (act_default)); + for (i = 0; i <= 2; i++) + act_default.hd[i] = INVALID_HANDLE_VALUE; + act = &act_default; + } check_syscall_func (); @@ -670,7 +731,7 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], return GPG_ERR_INV_ARG; } - return spawn_detached (pgmname, cmdline, spawn_cb, spawn_cb_arg); + return spawn_detached (pgmname, cmdline, act); } if (r_process) @@ -770,36 +831,34 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], memset (&si, 0, sizeof si); - sca.allow_foreground_window = FALSE; - sca.hd[0] = hd_in[0]; - sca.hd[1] = hd_out[1]; - sca.hd[2] = hd_err[1]; - sca.inherit_hds = NULL; - sca.arg = spawn_cb_arg; - if (spawn_cb) - (*spawn_cb) (&sca); + if (act->hd[0] == INVALID_HANDLE_VALUE) + act->hd[0] = hd_in[0]; + if (act->hd[1] == INVALID_HANDLE_VALUE) + act->hd[1] = hd_out[1]; + if (act->hd[2] == INVALID_HANDLE_VALUE) + act->hd[2] = hd_err[1]; i = 0; - if (sca.hd[0] != INVALID_HANDLE_VALUE) + if (act->hd[0] != INVALID_HANDLE_VALUE) i++; - if (sca.hd[1] != INVALID_HANDLE_VALUE) + if (act->hd[1] != INVALID_HANDLE_VALUE) i++; - if (sca.hd[2] != INVALID_HANDLE_VALUE) + if (act->hd[2] != INVALID_HANDLE_VALUE) i++; - if (i != 0 || sca.inherit_hds) + if (i != 0 || act->inherit_hds) { SIZE_T attr_list_size = 0; HANDLE hd[16]; - HANDLE *hd_p = sca.inherit_hds; + HANDLE *hd_p = act->inherit_hds; int j = 0; - if (sca.hd[0] != INVALID_HANDLE_VALUE) - hd[j++] = sca.hd[0]; - if (sca.hd[1] != INVALID_HANDLE_VALUE) - hd[j++] = sca.hd[1]; - if (sca.hd[1] != INVALID_HANDLE_VALUE) - hd[j++] = sca.hd[2]; + if (act->hd[0] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[0]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[1]; + if (act->hd[1] != INVALID_HANDLE_VALUE) + hd[j++] = act->hd[2]; if (hd_p) { while (*hd_p != INVALID_HANDLE_VALUE) @@ -858,9 +917,9 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], si.StartupInfo.cb = sizeof (si); si.StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.StartupInfo.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_HIDE; - si.StartupInfo.hStdInput = sca.hd[0]; - si.StartupInfo.hStdOutput = sca.hd[1]; - si.StartupInfo.hStdError = sca.hd[2]; + si.StartupInfo.hStdInput = act->hd[0]; + si.StartupInfo.hStdOutput = act->hd[1]; + si.StartupInfo.hStdError = act->hd[2]; /* log_debug ("CreateProcess, path='%s' cmdline='%s'\n", pgmname, cmdline); */ cr_flags = (CREATE_DEFAULT_ERROR_MODE @@ -877,9 +936,9 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], &sec_attr, /* Thread security attributes. */ ask_inherit, /* Inherit handles. */ cr_flags, /* Creation flags. */ - NULL, /* Environment. */ + act->env, /* Environment. */ NULL, /* Use current drive/directory. */ - (STARTUPINFOW *)&si, /* Startup information. */ + (STARTUPINFOW *)&si, /* Startup information. */ &pi /* Returns process information. */ ); if (!ret) @@ -933,7 +992,7 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], /* pi.hProcess, pi.hThread, */ /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - if (sca.allow_foreground_window) + if (allow_foreground_window) { /* Fixme: For unknown reasons AllowSetForegroundWindow returns * an invalid argument error if we pass it the correct diff --git a/common/exechelp.h b/common/exechelp.h index 0370b23a4..93ba12eeb 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -42,7 +42,7 @@ int get_max_fds (void); EXCEPT is not NULL, it is expected to be a list of file descriptors which are not to close. This list shall be sorted in ascending order with its end marked by -1. */ -void close_all_fds (int first, int *except); +void close_all_fds (int first, const int *except); /* Returns an array with all currently open file descriptors. The end @@ -75,22 +75,21 @@ void gnupg_close_pipe (int fd); /* The opaque type for a subprocess. */ typedef struct gnupg_process *gnupg_process_t; +typedef struct gnupg_spawn_actions *gnupg_spawn_actions_t; +gpg_err_code_t gnupg_spawn_actions_new (gnupg_spawn_actions_t *r_act); +void gnupg_spawn_actions_release (gnupg_spawn_actions_t act); #ifdef HAVE_W32_SYSTEM -struct spawn_cb_arg; -#ifdef NEED_STRUCT_SPAWN_CB_ARG -struct spawn_cb_arg { - HANDLE hd[3]; - HANDLE *inherit_hds; - BOOL allow_foreground_window; - void *arg; -}; -#endif +void gnupg_spawn_actions_set_envvars (gnupg_spawn_actions_t, char *); +void gnupg_spawn_actions_set_redirect (gnupg_spawn_actions_t, + void *, void *, void *); +void gnupg_spawn_actions_set_inherit_handles (gnupg_spawn_actions_t, void **); #else -struct spawn_cb_arg { - int fds[3]; - int *except_fds; - void *arg; -}; +void gnupg_spawn_actions_set_environ (gnupg_spawn_actions_t, char **); +void gnupg_spawn_actions_set_redirect (gnupg_spawn_actions_t, int, int, int); +void gnupg_spawn_actions_set_inherit_fds (gnupg_spawn_actions_t, + const int *); +void gnupg_spawn_actions_set_atfork (gnupg_spawn_actions_t, + void (*atfork)(void *), void *arg); #endif #define GNUPG_PROCESS_DETACHED (1 << 1) @@ -110,14 +109,10 @@ struct spawn_cb_arg { #define GNUPG_PROCESS_STREAM_NONBLOCK (1 << 16) -/* Spawn helper. */ -void gnupg_spawn_helper (struct spawn_cb_arg *sca); - /* Spawn PGMNAME. */ -gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv[], +gpg_err_code_t gnupg_process_spawn (const char *pgmname, const char *argv1[], unsigned int flags, - void (*spawn_cb) (struct spawn_cb_arg *), - void *spawn_cb_arg, + gnupg_spawn_actions_t act, gnupg_process_t *r_process); /* Get FDs for subprocess I/O. It is the caller which should care diff --git a/common/exectool.c b/common/exectool.c index 3505c25f1..05504de98 100644 --- a/common/exectool.c +++ b/common/exectool.c @@ -338,6 +338,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], read_and_log_buffer_t fderrstate; struct copy_buffer *cpbuf_in = NULL, *cpbuf_out = NULL, *cpbuf_extra = NULL; int quiet = 0; + gnupg_spawn_actions_t act = NULL; memset (fds, 0, sizeof fds); memset (&fderrstate, 0, sizeof fderrstate); @@ -413,13 +414,21 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], else exceptclose[0] = -1; + err = gnupg_spawn_actions_new (&act); + if (err) + goto leave; + +#ifdef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_inherit_handles (act, exceptclose); +#else + gnupg_spawn_actions_set_inherit_fds (act, exceptclose); +#endif err = gnupg_process_spawn (pgmname, argv, ((input ? GNUPG_PROCESS_STDIN_PIPE : 0) | GNUPG_PROCESS_STDOUT_PIPE - | GNUPG_PROCESS_STDERR_PIPE), - gnupg_spawn_helper, exceptclose, &proc); + | GNUPG_PROCESS_STDERR_PIPE), act, &proc); gnupg_process_get_streams (proc, GNUPG_PROCESS_STREAM_NONBLOCK, input? &infp : NULL, &outfp, &errfp); if (extrapipe[0] != -1) @@ -572,6 +581,7 @@ gnupg_exec_tool_stream (const char *pgmname, const char *argv[], es_fclose (outfp); es_fclose (errfp); gnupg_process_release (proc); + gnupg_spawn_actions_release (act); copy_buffer_shred (cpbuf_in); xfree (cpbuf_in); diff --git a/common/t-exechelp.c b/common/t-exechelp.c index 2179ef2a0..f25c91d3a 100644 --- a/common/t-exechelp.c +++ b/common/t-exechelp.c @@ -266,7 +266,7 @@ test_pipe_stream (const char *pgmname) err = gnupg_process_spawn (pgmname, argv, (GNUPG_PROCESS_STDOUT_PIPE |GNUPG_PROCESS_STDERR_KEEP), - NULL, NULL, &proc); + NULL, &proc); if (err) { fprintf (stderr, "gnupg_process_spawn failed\n"); diff --git a/dirmngr/ldap-wrapper.c b/dirmngr/ldap-wrapper.c index 2ec944c72..a6d58d3b2 100644 --- a/dirmngr/ldap-wrapper.c +++ b/dirmngr/ldap-wrapper.c @@ -851,7 +851,7 @@ ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[]) err = gnupg_process_spawn (pgmname, arg_list, (GNUPG_PROCESS_STDOUT_PIPE | GNUPG_PROCESS_STDERR_PIPE), - NULL, NULL, &process); + NULL, &process); if (err) { xfree (arg_list); diff --git a/g10/photoid.c b/g10/photoid.c index 8cc7e3a20..b226cbedd 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -601,7 +601,7 @@ run_with_pipe (struct spawn_info *info, const void *image, u32 len) fill_command_argv (argv, info->command); err = gnupg_process_spawn (argv[0], argv+1, GNUPG_PROCESS_STDIN_PIPE, - NULL, NULL, &proc); + NULL, &proc); if (err) log_error (_("unable to execute shell '%s': %s\n"), argv[0], gpg_strerror (err)); @@ -695,7 +695,7 @@ show_photo (const char *command, const char *name, const void *image, u32 len) const char *argv[4]; fill_command_argv (argv, spawn->command); - err = gnupg_process_spawn (argv[0], argv+1, 0, NULL, NULL, NULL); + err = gnupg_process_spawn (argv[0], argv+1, 0, NULL, NULL); if (err) log_error (_("unnatural exit of external program\n")); #endif diff --git a/scd/app.c b/scd/app.c index a9591a12c..09a148416 100644 --- a/scd/app.c +++ b/scd/app.c @@ -2383,18 +2383,15 @@ app_check_pin (card_t card, ctrl_t ctrl, const char *keyidstr, return err; } - +#ifndef HAVE_W32_SYSTEM static void -setup_env (struct spawn_cb_arg *sca) +setup_env (void *arg) { -#ifdef HAVE_W32_SYSTEM - (void)sca; /* Not supported on Windows. */ -#else - char *v = sca->arg; + char *v = arg; putenv (v); -#endif } +#endif static void report_change (int slot, int old_status, int cur_status) @@ -2425,6 +2422,7 @@ report_change (int slot, int old_status, int cur_status) gpg_error_t err; const char *args[9]; char numbuf1[30], numbuf2[30], numbuf3[30]; + gnupg_spawn_actions_t act = NULL; sprintf (numbuf1, "%d", slot); sprintf (numbuf2, "0x%04X", old_status); @@ -2442,9 +2440,16 @@ report_change (int slot, int old_status, int cur_status) args[8] = NULL; fname = make_filename (gnupg_homedir (), "scd-event", NULL); - err = gnupg_process_spawn (fname, args, - GNUPG_PROCESS_DETACHED, - setup_env, envstr, NULL); + err = gnupg_spawn_actions_new (&act); + if (!err) + { +#ifndef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_atfork (act, setup_env, envstr); +#endif + err = gnupg_process_spawn (fname, args, GNUPG_PROCESS_DETACHED, + act, NULL); + gnupg_spawn_actions_release (act); + } if (err && gpg_err_code (err) != GPG_ERR_ENOENT) log_error ("failed to run event handler '%s': %s\n", fname, gpg_strerror (err)); diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c index 36b0b98d2..510dc4088 100644 --- a/tests/gpgscm/ffi.c +++ b/tests/gpgscm/ffi.c @@ -938,7 +938,7 @@ do_process_spawn_io (scheme *sc, pointer args) } err = gnupg_process_spawn (argv[0], (const char **) &argv[1], - flags, NULL, NULL, &proc); + flags, NULL, &proc); err = gnupg_process_get_streams (proc, 0, &infp, NULL, NULL); err = es_write (infp, a_input, strlen (a_input), NULL); @@ -1137,25 +1137,6 @@ do_process_spawn_io (scheme *sc, pointer args) FFI_RETURN_ERR (sc, err); } -static void -setup_std_fds (struct spawn_cb_arg *sca) -{ - int *std_fds = sca->arg; - -#ifdef HAVE_W32_SYSTEM - sca->hd[0] = std_fds[0] == -1? - INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[0]); - sca->hd[1] = std_fds[1] == -1? - INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[1]); - sca->hd[2] = std_fds[2] == -1? - INVALID_HANDLE_VALUE : (HANDLE)_get_osfhandle (std_fds[2]); -#else - sca->fds[0] = std_fds[0]; - sca->fds[1] = std_fds[1]; - sca->fds[2] = std_fds[2]; -#endif -} - static pointer do_process_spawn_fd (scheme *sc, pointer args) { @@ -1165,6 +1146,7 @@ do_process_spawn_fd (scheme *sc, pointer args) size_t len; int std_fds[3]; gnupg_process_t proc = NULL; + gnupg_spawn_actions_t act = NULL; FFI_ARG_OR_RETURN (sc, pointer, arguments, list, args); FFI_ARG_OR_RETURN (sc, int, std_fds[0], number, args); @@ -1189,8 +1171,35 @@ do_process_spawn_fd (scheme *sc, pointer args) fprintf (stderr, " (%d %d %d)\n", std_fds[0], std_fds[1], std_fds[2]); } - err = gnupg_process_spawn (argv[0], (const char **) &argv[1], - 0, setup_std_fds, std_fds, &proc); + err = gnupg_spawn_actions_new (&act); + if (err) + { + FFI_RETURN_ERR (sc, err); + } +#ifdef HAVE_W32_SYSTEM + { + HANDLE std_in, std_out, std_err; + + if (std_fds[0] == -1) + std_in = INVALID_HANDLE_VALUE; + else + std_in = (HANDLE)_get_osfhandle (std_fds[0]); + if (std_fds[1] == -1) + std_out = INVALID_HANDLE_VALUE; + else + std_out = (HANDLE)_get_osfhandle (std_fds[1]); + if (std_fds[2] == -1) + std_err = INVALID_HANDLE_VALUE; + else + std_err = (HANDLE)_get_osfhandle (std_fds[2]); + + gnupg_spawn_actions_set_redirect (act, std_in, std_out, std_err); + } +#else + gnupg_spawn_actions_set_redirect (act, std_fds[0], std_fds[1], std_fds[2]); +#endif + err = gnupg_process_spawn (argv[0], (const char **)&argv[1], 0, act, &proc); + gnupg_spawn_actions_release (act); xfree (argv); FFI_RETURN_POINTER (sc, proc_wrap (sc, proc)); } diff --git a/tools/gpg-card.c b/tools/gpg-card.c index 8b3a3082b..3d66033bf 100644 --- a/tools/gpg-card.c +++ b/tools/gpg-card.c @@ -3835,7 +3835,7 @@ cmd_gpg (card_info_t info, char *argstr, int use_gpgsm) argv, (GNUPG_PROCESS_STDOUT_KEEP | GNUPG_PROCESS_STDERR_KEEP), - NULL, NULL, &proc); + NULL, &proc); if (!err) { err = gnupg_process_wait (proc, 1); diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index d6aa9d61b..b54b52c69 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -761,7 +761,7 @@ gpg_agent_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -805,7 +805,7 @@ scdaemon_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -850,7 +850,7 @@ tpm2daemon_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -885,7 +885,7 @@ dirmngr_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -919,7 +919,7 @@ keyboxd_runtime_change (int killflag) log_assert (i < DIM(argv)); if (!err) - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -985,7 +985,7 @@ gc_component_launch (int component) argv[i] = NULL; log_assert (i < DIM(argv)); - err = gnupg_process_spawn (pgmname, argv, 0, NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, 0, NULL, &proc); if (!err) err = gnupg_process_wait (proc, 1); if (err) @@ -1369,9 +1369,8 @@ gc_component_check_options (int component, estream_t out, const char *conf_file) result = 0; errlines = NULL; - err = gnupg_process_spawn (pgmname, argv, - GNUPG_PROCESS_STDERR_PIPE, - NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDERR_PIPE, + NULL, &proc); if (err) result |= 1; /* Program could not be run. */ else @@ -1763,9 +1762,8 @@ retrieve_options_from_program (gc_component_id_t component, int only_installed) /* First we need to read the option table from the program. */ argv[0] = "--dump-option-table"; argv[1] = NULL; - err = gnupg_process_spawn (pgmname, argv, - GNUPG_PROCESS_STDOUT_PIPE, - NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDOUT_PIPE, + NULL, &proc); if (err) { gc_error (1, 0, "could not gather option table from '%s': %s", @@ -1952,9 +1950,8 @@ retrieve_options_from_program (gc_component_id_t component, int only_installed) /* Now read the default options. */ argv[0] = "--gpgconf-list"; argv[1] = NULL; - err = gnupg_process_spawn (pgmname, argv, - GNUPG_PROCESS_STDOUT_PIPE, - NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDOUT_PIPE, + NULL, &proc); if (err) { gc_error (1, 0, "could not gather active options from '%s': %s", diff --git a/tools/gpgconf.c b/tools/gpgconf.c index ac709ae21..301c1838f 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -1311,9 +1311,8 @@ show_versions_via_dirmngr (estream_t fp) pgmname = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR); argv[0] = "--gpgconf-versions"; argv[1] = NULL; - err = gnupg_process_spawn (pgmname, argv, - GNUPG_PROCESS_STDOUT_PIPE, - NULL, NULL, &proc); + err = gnupg_process_spawn (pgmname, argv, GNUPG_PROCESS_STDOUT_PIPE, + NULL, &proc); if (err) { log_error ("error spawning %s: %s", pgmname, gpg_strerror (err)); diff --git a/tools/gpgtar-create.c b/tools/gpgtar-create.c index 7af5a2ede..76eb47449 100644 --- a/tools/gpgtar-create.c +++ b/tools/gpgtar-create.c @@ -1234,6 +1234,7 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, int except[2] = { -1, -1 }; #endif const char **argv; + gnupg_spawn_actions_t act = NULL; /* '--encrypt' may be combined with '--symmetric', but 'encrypt' * is set either way. Clear it if no recipients are specified. @@ -1296,11 +1297,23 @@ gpgtar_create (char **inpattern, const char *files_from, int null_names, goto leave; } + err = gnupg_spawn_actions_new (&act); + if (err) + { + xfree (argv); + goto leave; + } + +#ifdef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_inherit_handles (act, except); +#else + gnupg_spawn_actions_set_inherit_fds (act, except); +#endif err = gnupg_process_spawn (opt.gpg_program, argv, (GNUPG_PROCESS_STDIN_PIPE | GNUPG_PROCESS_STDOUT_KEEP - | GNUPG_PROCESS_STDERR_KEEP), - gnupg_spawn_helper, except, &proc); + | GNUPG_PROCESS_STDERR_KEEP), act, &proc); + gnupg_spawn_actions_release (act); xfree (argv); if (err) goto leave; diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index 87113b054..e93ffdc37 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -390,6 +390,7 @@ gpgtar_extract (const char *filename, int decrypt) int except[2] = { -1, -1 }; #endif const char **argv; + gnupg_spawn_actions_t act = NULL; ccparray_init (&ccp, 0); if (opt.batch) @@ -435,10 +436,22 @@ gpgtar_extract (const char *filename, int decrypt) goto leave; } + err = gnupg_spawn_actions_new (&act); + if (err) + { + xfree (argv); + goto leave; + } + +#ifdef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_inherit_handles (act, except); +#else + gnupg_spawn_actions_set_inherit_fds (act, except); +#endif err = gnupg_process_spawn (opt.gpg_program, argv, ((filename ? 0 : GNUPG_PROCESS_STDIN_KEEP) - | GNUPG_PROCESS_STDOUT_PIPE), - gnupg_spawn_helper, except, &proc); + | GNUPG_PROCESS_STDOUT_PIPE), act, &proc); + gnupg_spawn_actions_release (act); xfree (argv); if (err) goto leave; diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c index 0c5e474f3..55d9246af 100644 --- a/tools/gpgtar-list.c +++ b/tools/gpgtar-list.c @@ -474,6 +474,7 @@ gpgtar_list (const char *filename, int decrypt) int except[2] = { -1, -1 }; #endif const char **argv; + gnupg_spawn_actions_t act = NULL; ccparray_init (&ccp, 0); if (opt.batch) @@ -513,10 +514,22 @@ gpgtar_list (const char *filename, int decrypt) goto leave; } + err = gnupg_spawn_actions_new (&act); + if (err) + { + xfree (argv); + goto leave; + } + +#ifdef HAVE_W32_SYSTEM + gnupg_spawn_actions_set_inherit_handles (act, except); +#else + gnupg_spawn_actions_set_inherit_fds (act, except); +#endif err = gnupg_process_spawn (opt.gpg_program, argv, ((filename ? 0 : GNUPG_PROCESS_STDIN_KEEP) - | GNUPG_PROCESS_STDOUT_PIPE), - gnupg_spawn_helper, except, &proc); + | GNUPG_PROCESS_STDOUT_PIPE), act, &proc); + gnupg_spawn_actions_release (act); xfree (argv); if (err) goto leave; From 253a701ed74903a63ceb22519d9e43360f1106a4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 31 May 2024 12:28:16 +0200 Subject: [PATCH 502/869] g13: Adjust for changed gnupg_process_spawn. * g13/be-encfs.c (run_umount_helper): Adjust gnupg_process_spawn. (run_encfs_tool): Ditto: --- g13/be-encfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g13/be-encfs.c b/g13/be-encfs.c index ac6d6d6cd..04b0b632a 100644 --- a/g13/be-encfs.c +++ b/g13/be-encfs.c @@ -83,7 +83,7 @@ run_umount_helper (const char *mountpoint) err = gnupg_process_spawn (pgmname, args, GNUPG_PROCESS_DETACHED, - NULL, NULL, NULL); + NULL, NULL); if (err) log_error ("failed to run '%s': %s\n", pgmname, gpg_strerror (err)); @@ -262,7 +262,7 @@ run_encfs_tool (ctrl_t ctrl, enum encfs_cmds cmd, err = gnupg_process_spawn (pgmname, argv, (GNUPG_PROCESS_STDIN_PIPE | GNUPG_PROCESS_STDERR_PIPE), - NULL, NULL, &proc); + NULL, &proc); if (err) { log_error ("error spawning '%s': %s\n", pgmname, gpg_strerror (err)); From 42b0e9558a308dbc954ee60c3d346b5cabcd2fdb Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Sun, 12 May 2024 18:09:23 -0400 Subject: [PATCH 503/869] indent: Fix spelling -- These are non-substantive corrections for minor spelling mistakes within the GnuPG codebase. With something like this applied to the codebase, and a judiciously tuned spellchecker integrated as part of a standard test suite, it should be possible to keep a uniform orthography within the project. GnuPG-bug-id: 7116 --- agent/agent.h | 4 ++-- agent/call-pinentry.c | 2 +- agent/command.c | 2 +- agent/divert-scd.c | 2 +- agent/findkey.c | 2 +- agent/gpg-agent.c | 4 ++-- agent/protect.c | 2 +- agent/sexp-secret.c | 2 +- agent/trustlist.c | 4 ++-- build-aux/speedo.mk | 6 +++--- build-aux/speedo/w32/README.txt | 2 +- build-aux/speedo/w32/g4wihelp.c | 2 +- common/asshelp.c | 2 +- common/audit.c | 2 +- common/audit.h | 2 +- common/compliance.c | 2 +- common/dotlock.c | 2 +- common/gettime.c | 2 +- common/homedir.c | 4 ++-- common/iobuf.c | 2 +- common/iobuf.h | 2 +- common/mkdir_p.h | 2 +- common/openpgp-fpr.c | 2 +- common/openpgp-oid.c | 2 +- common/session-env.c | 4 ++-- common/sexp-parse.h | 2 +- common/sexputil.c | 4 ++-- common/sysutils.c | 4 ++-- common/t-iobuf.c | 2 +- common/tlv-builder.c | 2 +- common/tlv-parser.c | 2 +- common/tlv.h | 2 +- common/util.h | 2 +- configure.ac | 4 ++-- dirmngr/ONEWS | 4 ++-- dirmngr/certcache.c | 2 +- dirmngr/dirmngr.c | 6 +++--- dirmngr/dirmngr.h | 2 +- dirmngr/dns.c | 2 +- dirmngr/http-ntbtls.c | 2 +- dirmngr/http.c | 16 ++++++++-------- dirmngr/ks-engine-ldap.c | 14 +++++++------- dirmngr/ldap-misc.c | 2 +- dirmngr/ldap.c | 8 ++++---- dirmngr/ldapserver.c | 2 +- dirmngr/ocsp.c | 8 ++++---- dirmngr/server.c | 2 +- dirmngr/t-ldap-parse-uri.c | 2 +- dirmngr/validate.c | 6 +++--- doc/DETAILS | 14 +++++++------- doc/HACKING | 4 ++-- doc/dirmngr.texi | 2 +- doc/examples/common.conf | 4 ++-- doc/examples/trustlist.txt | 2 +- doc/gnupg.texi | 2 +- doc/gpg-card.texi | 2 +- doc/gpg.texi | 6 +++--- doc/help.txt | 2 +- doc/ldap/README.ldap | 8 ++++---- doc/ldap/gnupg-ldap-ad-schema.ldif | 4 ++-- doc/ldap/gnupg-ldap-schema.ldif | 4 ++-- doc/tools.texi | 2 +- g10/armor.c | 4 ++-- g10/call-agent.c | 6 +++--- g10/call-dirmngr.c | 2 +- g10/call-keyboxd.c | 4 ++-- g10/card-util.c | 2 +- g10/encrypt.c | 6 +++--- g10/export.c | 2 +- g10/getkey.c | 6 +++--- g10/gpg.c | 6 +++--- g10/import.c | 2 +- g10/key-clean.c | 2 +- g10/keyedit.c | 6 +++--- g10/keygen.c | 4 ++-- g10/keyid.c | 6 +++--- g10/options.h | 2 +- g10/packet.h | 2 +- g10/pkclist.c | 2 +- g10/pkglue.c | 2 +- g10/sig-check.c | 2 +- g10/sign.c | 4 ++-- g10/tofu.c | 2 +- g10/trustdb.c | 2 +- g13/g13-syshelp.c | 2 +- g13/g13.c | 4 ++-- g13/sh-dmcrypt.c | 2 +- kbx/backend-sqlite.c | 2 +- kbx/backend-support.c | 4 ++-- kbx/frontend.c | 2 +- kbx/kbxserver.c | 2 +- kbx/keybox-init.c | 2 +- kbx/keybox-search-desc.h | 2 +- kbx/keyboxd.c | 2 +- m4/gpg-error.m4 | 2 +- m4/ksba.m4 | 4 ++-- m4/ntbtls.m4 | 4 ++-- regexp/jimregexp.c | 2 +- scd/apdu.c | 2 +- scd/app-nks.c | 2 +- scd/app-openpgp.c | 2 +- scd/app-p15.c | 10 +++++----- scd/app-piv.c | 4 ++-- scd/app.c | 2 +- scd/ccid-driver.c | 2 +- scd/command.c | 4 ++-- scd/iso7816.c | 4 ++-- scd/scdaemon.c | 4 ++-- sm/call-agent.c | 2 +- sm/certchain.c | 2 +- sm/certreqgen.c | 4 ++-- sm/decrypt.c | 4 ++-- sm/export.c | 4 ++-- sm/gpgsm.c | 6 +++--- sm/gpgsm.h | 2 +- sm/import.c | 2 +- sm/keydb.c | 6 +++--- sm/keylist.c | 2 +- sm/minip12.c | 4 ++-- sm/misc.c | 2 +- tests/asschk.c | 4 ++-- tests/openpgp/all-tests.scm | 2 +- tests/openpgp/defs.scm | 2 +- tests/openpgp/fake-pinentry.c | 2 +- tests/tpm2dtests/all-tests.scm | 2 +- tools/call-dirmngr.c | 2 +- tools/card-yubikey.c | 2 +- tools/gpg-authcode-sign.sh | 4 ++-- tools/gpg-card.c | 2 +- tools/gpg-check-pattern.c | 2 +- tools/gpgconf-comp.c | 12 ++++++------ tools/gpgconf.c | 2 +- tools/gpgtar-list.c | 8 ++++---- tools/gpgtar.c | 2 +- tpm2d/Makefile.am | 2 +- tpm2d/tpm2daemon.c | 6 +++--- 136 files changed, 233 insertions(+), 233 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index dbb3000dd..7ffbd5cc2 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -121,7 +121,7 @@ struct /* Flag disallowing bypassing of the warning. */ int enforce_passphrase_constraints; - /* The require minmum length of a passphrase. */ + /* The required minimum length of a passphrase. */ unsigned int min_passphrase_len; /* The minimum number of non-alpha characters in a passphrase. */ @@ -286,7 +286,7 @@ struct server_control_s int algo; unsigned char value[MAX_DIGEST_LEN]; unsigned int raw_value: 1; - unsigned int is_pss: 1; /* DATA holds PSS formated data. */ + unsigned int is_pss: 1; /* DATA holds PSS formatted data. */ } digest; unsigned int have_keygrip: 1; unsigned int have_keygrip1: 1; diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 4a999ca9a..ba37a775e 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -884,7 +884,7 @@ struct inq_cb_parm_s }; -/* Return true if PIN is indentical to the last generated pin. */ +/* Return true if PIN is identical to the last generated pin. */ static int is_generated_pin (struct inq_cb_parm_s *parm, const char *pin) { diff --git a/agent/command.c b/agent/command.c index 417a8815f..3012680a1 100644 --- a/agent/command.c +++ b/agent/command.c @@ -251,7 +251,7 @@ reset_notify (assuan_context_t ctx, char *line) clear_nonce_cache (ctrl); - /* Note that a RESET does not clear the ephemeral store becuase + /* Note that a RESET does not clear the ephemeral store because * clients are used to issue a RESET on a connection. */ return 0; diff --git a/agent/divert-scd.c b/agent/divert-scd.c index d8c2bcca7..d390ebb06 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -90,7 +90,7 @@ has_percent0A_suffix (const char *string) INFO gets displayed as part of a generic string. However if the first character of INFO is a vertical bar all up to the next - verical bar are considered flags and only everything after the + vertical bar are considered flags and only everything after the second vertical bar gets displayed as the full prompt. Flags: diff --git a/agent/findkey.c b/agent/findkey.c index 1f2938ea3..c0cbce7a2 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -1550,7 +1550,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, { memcpy (*shadow_info, s, n); /* - * When it's a key on card (not on tpm2), maks sure + * When it's a key on card (not on tpm2), make sure * it's available. */ if (strcmp (shadow_type, "t1-v1") == 0 && !grip) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 3c71ba65d..3e1fb5d5b 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1216,7 +1216,7 @@ main (int argc, char **argv) * Now we are now working under our real uid */ - /* The configuraton directories for use by gpgrt_argparser. */ + /* The configuration directories for use by gpgrt_argparser. */ gpgrt_set_confdir (GPGRT_CONFDIR_SYS, gnupg_sysconfdir ()); gpgrt_set_confdir (GPGRT_CONFDIR_USER, gnupg_homedir ()); @@ -1225,7 +1225,7 @@ main (int argc, char **argv) pargs.argc = &argc; pargs.argv = &argv; /* We are re-using the struct, thus the reset flag. We OR the - * flags so that the internal intialized flag won't be cleared. */ + * flags so that the internal initialized flag won't be cleared. */ pargs.flags |= (ARGPARSE_FLAG_RESET | ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_SYS diff --git a/agent/protect.c b/agent/protect.c index 7197cf7e6..6c9bbaebc 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -509,7 +509,7 @@ do_encryption (const unsigned char *hashbegin, size_t hashlen, ((sha1 salt no_of_iterations) 16byte_iv) encrypted_octet_string) - in canoncical format of course. We use asprintf and %n modifier + in canonical format of course. We use asprintf and %n modifier and dummy values as placeholders. */ { char countbuf[35]; diff --git a/agent/sexp-secret.c b/agent/sexp-secret.c index ac8daa910..661681620 100644 --- a/agent/sexp-secret.c +++ b/agent/sexp-secret.c @@ -22,7 +22,7 @@ #include "../common/sexp-parse.h" /* - * When it's for ECC, fixup private key part in the cannonical SEXP + * When it's for ECC, fixup private key part in the canonical SEXP * representation in BUF. If not ECC, do nothing. */ gpg_error_t diff --git a/agent/trustlist.c b/agent/trustlist.c index fce23de15..a37705b8e 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -63,7 +63,7 @@ static const char headerblurb[] = "# well as empty lines are ignored. Lines have a length limit but this\n" "# is not a serious limitation as the format of the entries is fixed and\n" "# checked by gpg-agent. A non-comment line starts with optional white\n" -"# space, followed by the SHA-1 fingerpint in hex, followed by a flag\n" +"# space, followed by the SHA-1 fingerprint in hex, followed by a flag\n" "# which may be one of 'P', 'S' or '*' and optionally followed by a list of\n" "# other flags. The fingerprint may be prefixed with a '!' to mark the\n" "# key as not trusted. You should give the gpg-agent a HUP or run the\n" @@ -736,7 +736,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag) insert a line break. The double percent sign is actually needed because it is also a printf format string. If you need to insert a plain % sign, you need to encode it as - "%%25". The second "%s" gets replaced by a hexdecimal + "%%25". The second "%s" gets replaced by a hexadecimal fingerprint string whereas the first one receives the name as stored in the certificate. */ L_("Please verify that the certificate identified as:%%0A" diff --git a/build-aux/speedo.mk b/build-aux/speedo.mk index e92a94231..a98d61f71 100644 --- a/build-aux/speedo.mk +++ b/build-aux/speedo.mk @@ -188,13 +188,13 @@ MAKE_J=6 INST_NAME=gnupg-w32 -# Use this to override the installaion directory for native builds. +# Use this to override the installation directory for native builds. INSTALL_PREFIX=none # Set this to the location of wixtools WIXPREFIX=$(shell readlink -f ~/w32root/wixtools) -# If patchelf(1) is not availale disable the command. +# If patchelf(1) is not available disable the command. PATCHELF := $(shell patchelf --version 2>/dev/null >/dev/null || echo "echo please run: ")patchelf # Read signing information from ~/.gnupg-autogen.rc @@ -1401,7 +1401,7 @@ endif # -# Check availibility of standard tools and prepare everything. +# Check availability of standard tools and prepare everything. # check-tools: $(stampdir)/stamp-directories diff --git a/build-aux/speedo/w32/README.txt b/build-aux/speedo/w32/README.txt index 7c2909507..df7b3a807 100644 --- a/build-aux/speedo/w32/README.txt +++ b/build-aux/speedo/w32/README.txt @@ -60,7 +60,7 @@ Below is the README file as distributed with the GnuPG source. 4. Software Versions of the Included Packages ============================================= -GnuPG for Windows depends on several independet developed packages +GnuPG for Windows depends on several independent developed packages which are part of the installation. These packages along with their version numbers and the SHA-1 checksums of their compressed tarballs are listed here: diff --git a/build-aux/speedo/w32/g4wihelp.c b/build-aux/speedo/w32/g4wihelp.c index bae4b837c..33d186c40 100644 --- a/build-aux/speedo/w32/g4wihelp.c +++ b/build-aux/speedo/w32/g4wihelp.c @@ -24,7 +24,7 @@ ************************************************************ * The code for the splash screen has been taken from the Splash * plugin of the NSIS 2.04 distribution. That code comes without - * explicit copyright notices in tyhe source files or author names, it + * explicit copyright notices in the source files or author names, it * seems that it has been written by Justin Frankel; not sure about * the year, though. [wk 2005-11-28] * diff --git a/common/asshelp.c b/common/asshelp.c index 957ca994d..f17a32e52 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -695,7 +695,7 @@ get_assuan_server_version (assuan_context_t ctx, int mode, char **r_version) /* Print a warning if the server's version number is less than our * version number. Returns an error code on a connection problem. - * CTX is the Assuan context, SERVERNAME is the name of teh server, + * CTX is the Assuan context, SERVERNAME is the name of the server, * STATUS_FUNC and STATUS_FUNC_DATA is a callback to emit status * messages. If PRINT_HINTS is set additional hints are printed. For * MODE see get_assuan_server_version. */ diff --git a/common/audit.c b/common/audit.c index 42a2cf6d6..551563c61 100644 --- a/common/audit.c +++ b/common/audit.c @@ -44,7 +44,7 @@ struct log_item_s gpg_error_t err; /* The logged error code. */ int intvalue; /* A logged integer value. */ char *string; /* A malloced string or NULL. */ - ksba_cert_t cert; /* A certifciate or NULL. */ + ksba_cert_t cert; /* A certificate or NULL. */ unsigned int have_err:1; unsigned int have_intvalue:1; }; diff --git a/common/audit.h b/common/audit.h index 05f39533d..9fadba1b2 100644 --- a/common/audit.h +++ b/common/audit.h @@ -76,7 +76,7 @@ typedef enum /* The signature is a detached one. */ AUDIT_CERT_ONLY_SIG, - /* A certifciate only signature has been detected. */ + /* A certificate only signature has been detected. */ AUDIT_DATA_HASH_ALGO, /* int */ /* The hash algo given as argument is used for the data. This diff --git a/common/compliance.c b/common/compliance.c index 2df10d2e2..d421b0371 100644 --- a/common/compliance.c +++ b/common/compliance.c @@ -42,7 +42,7 @@ static int module; /* This value is used by DSA and RSA checks in addition to the hard * coded length checks. It allows one to increase the required key length - * using a confue file. */ + * using a config file. */ static unsigned int min_compliant_rsa_length; /* Return the address of a compliance cache variable for COMPLIANCE. diff --git a/common/dotlock.c b/common/dotlock.c index fe6d7fe71..ae77fad8a 100644 --- a/common/dotlock.c +++ b/common/dotlock.c @@ -1450,7 +1450,7 @@ dotlock_take_unix (dotlock_t h, long timeout) int wtimereal; if (ownerchanged) - wtime = 0; /* Reset because owner chnaged. */ + wtime = 0; /* Reset because owner changed. */ wtimereal = next_wait_interval (&wtime, &timeout); if (!timeout) diff --git a/common/gettime.c b/common/gettime.c index 136c47ca7..180f388bb 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -124,7 +124,7 @@ timegm (struct tm *tm) /* Version of the GNU timegm which returns an unsigned 64 bit integer * instead of the usually signed time_t. On error (uint64_t)(-1) is - * returned. This function is mostly here becuase on 32 bit Windows + * returned. This function is mostly here because on 32 bit Windows * we have an internal API to get the system time even after * 2023-01-19. For 32 bit Unix we need to suffer from the too short * time_t and no system function to construct the time from a tm. */ diff --git a/common/homedir.c b/common/homedir.c index deb6f3616..392910867 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -1089,7 +1089,7 @@ gnupg_daemon_rootdir (void) n = GetSystemDirectoryA (path, sizeof path); if (!n || n >= sizeof path) - name = xstrdup ("/"); /* Error - use the curret top dir instead. */ + name = xstrdup ("/"); /* Error - use the current top dir instead. */ else name = xstrdup (path); gpgrt_annotate_leaked_object (name); @@ -1306,7 +1306,7 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info) strcat (prefixbuffer, gnupgname); } - /* Check whether the gnupg sub directory (or the specified diretory) + /* Check whether the gnupg sub directory (or the specified directory) * has proper permissions. */ if (stat (prefix, &sb)) { diff --git a/common/iobuf.c b/common/iobuf.c index e46eeac95..7aaf3a878 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -1670,7 +1670,7 @@ iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval) /* Peek at a justed opened file. Use this only directly after a * file has been opened for reading. Don't use it after you did * a seek. This works only if just file filter has been - * pushed. Expects a buffer wit size INTVAL at PTRVAL and returns + * pushed. Expects a buffer with size INTVAL at PTRVAL and returns * the number of bytes put into the buffer. */ if (DBG_IOBUF) log_debug ("iobuf-%d.%d: ioctl '%s' peek\n", diff --git a/common/iobuf.h b/common/iobuf.h index 4354c718d..5fa064c20 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -204,7 +204,7 @@ struct iobuf_struct byte *buf; } d; - /* A external drain buffer for reading/writting data skipping internal + /* A external drain buffer for reading/writing data skipping internal draint buffer D.BUF. This allows zerocopy operation reducing processing overhead across filter stack. diff --git a/common/mkdir_p.h b/common/mkdir_p.h index 1e939b32b..08f388916 100644 --- a/common/mkdir_p.h +++ b/common/mkdir_p.h @@ -34,7 +34,7 @@ /* Create a directory as well as any missing parents. - The arguments must be NULL termianted. If DIRECTORY_COMPONENTS... + The arguments must be NULL terminated. If DIRECTORY_COMPONENTS... consists of two elements, "foo/bar" and "xyzzy", this function will first try to create the directory "foo/bar" and then the directory "foo/bar/xyzzy". On success returns 0, otherwise an error code is diff --git a/common/openpgp-fpr.c b/common/openpgp-fpr.c index 7b110085f..7860d3872 100644 --- a/common/openpgp-fpr.c +++ b/common/openpgp-fpr.c @@ -136,7 +136,7 @@ compute_openpgp_fpr (int keyversion, int pgpalgo, unsigned long timestamp, /* log_printhex (iov[i].data, iov[i].len, "cmpfpr i=%d: ", i); */ err = gcry_md_hash_buffers (hashalgo, 0, result, iov, iovcnt); - /* log_printhex (result, 20, "fingerpint: "); */ + /* log_printhex (result, 20, "fingerprint: "); */ /* Better clear the first element because it was set by us. */ iov[0].size = 0; diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index 92f0dfbcd..0a7aae000 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -129,7 +129,7 @@ make_flagged_int (unsigned long value, char *buf, size_t buflen) /* fixme: figure out the number of bits in an ulong and start with that value as shift (after making it a multiple of 7) a more - straigtforward implementation is to do it in reverse order using + straightforward implementation is to do it in reverse order using a temporary buffer - saves a lot of compares */ for (more=0, shift=28; shift > 0; shift -= 7) { diff --git a/common/session-env.c b/common/session-env.c index e774c1d9b..3ffe3f0f5 100644 --- a/common/session-env.c +++ b/common/session-env.c @@ -315,7 +315,7 @@ session_env_putenv (session_env_t se, const char *string) } -/* Same as session_env_putenv but with name and value given as distict +/* Same as session_env_putenv but with name and value given as distinct values. */ gpg_error_t session_env_setenv (session_env_t se, const char *name, const char *value) @@ -355,7 +355,7 @@ session_env_getenv (session_env_t se, const char *name) object. The returned value is valid as long as SE is valid and as long it has not been removed or updated by a call to session_env_putenv. If the variable does not exist, the function - tries to return the value trough a call to getenv; if that returns + tries to return the value through a call to getenv; if that returns a value, this value is recorded and used. If no value could be found, returns NULL. The caller must not change the returned value. */ diff --git a/common/sexp-parse.h b/common/sexp-parse.h index 0403d65f5..86372e028 100644 --- a/common/sexp-parse.h +++ b/common/sexp-parse.h @@ -104,7 +104,7 @@ smatch (unsigned char const **buf, size_t buflen, const char *token) return 1; } -/* Format VALUE for use as the length indicatior of an S-expression. +/* Format VALUE for use as the length indicator of an S-expression. The caller needs to provide a buffer HELP_BUFFER with a length of HELP_BUFLEN. The return value is a pointer into HELP_BUFFER with the formatted length string. The colon and a trailing nul are diff --git a/common/sexputil.c b/common/sexputil.c index 15fd7cf1d..f9842391e 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -199,7 +199,7 @@ make_canon_sexp_pad (gcry_sexp_t sexp, int secure, } /* Return the so called "keygrip" which is the SHA-1 hash of the - public key parameters expressed in a way dependend on the algorithm. + public key parameters expressed in a way dependent on the algorithm. KEY is expected to be an canonical encoded S-expression with a public or private key. KEYLEN is the length of that buffer. @@ -1195,7 +1195,7 @@ cipher_mode_to_string (int mode) } } -/* Return the cannonical name of the ECC curve in KEY. */ +/* Return the canonical name of the ECC curve in KEY. */ const char * get_ecc_curve_from_key (gcry_sexp_t key) { diff --git a/common/sysutils.c b/common/sysutils.c index 780af58bd..2bacae2ea 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -588,7 +588,7 @@ translate_sys2libc_fd_int (int fd, int for_write) /* * Parse the string representation of a file reference (file handle on * Windows or file descriptor on POSIX) in FDSTR. The string - * representation may be either of folllowing: + * representation may be either of following: * (1) 0, 1, or 2 which means stdin, stdout, and stderr, respectively. * (2) Integer representation (by %d of printf). @@ -1106,7 +1106,7 @@ modestr_to_mode (const char *modestr, mode_t oldmode) int gnupg_mkdir (const char *name, const char *modestr) { - /* Note that gpgrt_mkdir also sets ERRNO in addition to returing an + /* Note that gpgrt_mkdir also sets ERRNO in addition to returning an * gpg-error style error code. */ return gpgrt_mkdir (name, modestr); } diff --git a/common/t-iobuf.c b/common/t-iobuf.c index aacf27a8b..9aa0720f6 100644 --- a/common/t-iobuf.c +++ b/common/t-iobuf.c @@ -29,7 +29,7 @@ */ /* The whole code here does not very fill into our general test frame - * work patter. But let's keep it as it is. */ + * work pattern. But let's keep it as it is. */ #include #include diff --git a/common/tlv-builder.c b/common/tlv-builder.c index 59e2691e0..0fa5fc2cc 100644 --- a/common/tlv-builder.c +++ b/common/tlv-builder.c @@ -95,7 +95,7 @@ ensure_space (tlv_builder_t tb) * element is described by CLASS, TAG, VALUE, and VALUEEN. CLASS and * TAG must describe a primitive element and (VALUE,VALUELEN) specify * its value. The value is a pointer and its object must not be - * changed as long as the instance TB exists. For a TAG_NULL no vlaue + * changed as long as the instance TB exists. For a TAG_NULL no value * is expected. Errors are not returned but recorded for later * retrieval. */ void diff --git a/common/tlv-parser.c b/common/tlv-parser.c index c9b33d4b6..2cafac3e9 100644 --- a/common/tlv-parser.c +++ b/common/tlv-parser.c @@ -42,7 +42,7 @@ struct bufferlist_s /* An object to control the ASN.1 parsing. */ struct tlv_parser_s { - /* The orginal buffer with the entire pkcs#12 object and its length. */ + /* The original buffer with the entire pkcs#12 object and its length. */ const unsigned char *origbuffer; size_t origbufsize; diff --git a/common/tlv.h b/common/tlv.h index afaa649d9..3136195a5 100644 --- a/common/tlv.h +++ b/common/tlv.h @@ -141,7 +141,7 @@ void tlv_builder_add_end (tlv_builder_t tb); gpg_error_t tlv_builder_finalize (tlv_builder_t tb, void **r_obj, size_t *r_objlen); -/* Wite a TLV header to MEMBUF. */ +/* Write a TLV header to MEMBUF. */ void put_tlv_to_membuf (membuf_t *membuf, int class, int tag, int constructed, size_t length); diff --git a/common/util.h b/common/util.h index f8447aea7..671ffbcb7 100644 --- a/common/util.h +++ b/common/util.h @@ -323,7 +323,7 @@ void setup_libgcrypt_logging (void); /* Print an out of core message and die. */ void xoutofcore (void); -/* Wrapper aroung gpgrt_reallocarray. Uses the gpgrt alloc function +/* Wrapper around gpgrt_reallocarray. Uses the gpgrt alloc function * which redirects to the Libgcrypt versions via * init_common_subsystems. Thus this can be used interchangeable with * the other alloc functions. */ diff --git a/configure.ac b/configure.ac index 1f0142140..71c061481 100644 --- a/configure.ac +++ b/configure.ac @@ -1601,7 +1601,7 @@ if test "$build_tpm2d" = "yes"; then # until version 2.4.0. # # Note: the missing API is fairly serious and is also easily backportable - # so keep the check below as is intead of going by library version number. + # so keep the check below as is instead of going by library version number. ## AC_CHECK_LIB(tss2-esys, Esys_TR_GetTpmHandle, [], [ AC_MSG_WARN([Need Esys_TR_GetTpmHandle API (usually requires Intel TSS 2.4.0 or later, disabling TPM support)]) @@ -1638,7 +1638,7 @@ if test "$GCC" = yes; then mycflags= mycflags_save=$CFLAGS - # Check whether gcc does not emit a diagnositc for unknown -Wno-* + # Check whether gcc does not emit a diagnostic for unknown -Wno-* # options. This is the case for gcc >= 4.6 AC_MSG_CHECKING([if gcc ignores unknown -Wno-* options]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ diff --git a/dirmngr/ONEWS b/dirmngr/ONEWS index cb2050748..154d8e0bf 100644 --- a/dirmngr/ONEWS +++ b/dirmngr/ONEWS @@ -55,7 +55,7 @@ Noteworthy changes in version 1.0.1 (2007-08-16) Noteworthy changes in version 1.0.0 (2006-11-29) ------------------------------------------------ - * Bumbed the version number. + * Bumped the version number. * Removed included gettext. We now require the system to provide a suitable installation. @@ -174,7 +174,7 @@ Noteworthy changes in version 0.5.4 (2004-04-29) ------------------------------------------------ * New commands --ocsp-responder and --ocsp-signer to define a default - OCSP reponder if a certificate does not contain an assigned OCSP + OCSP responder if a certificate does not contain an assigned OCSP responder. diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c index b7b5b3d15..07a47a525 100644 --- a/dirmngr/certcache.c +++ b/dirmngr/certcache.c @@ -225,7 +225,7 @@ cert_compute_fpr (ksba_cert_t cert, unsigned char *digest) -/* Cleanup one slot. This releases all resourses but keeps the actual +/* Cleanup one slot. This releases all resources but keeps the actual slot in the cache marked for reuse. */ static void clean_cache_slot (cert_item_t ci) diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index d58a27372..5a2a45bc1 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -1104,12 +1104,12 @@ main (int argc, char **argv) socket_name = dirmngr_socket_name (); - /* The configuraton directories for use by gpgrt_argparser. */ + /* The configuration directories for use by gpgrt_argparser. */ gpgrt_set_confdir (GPGRT_CONFDIR_SYS, gnupg_sysconfdir ()); gpgrt_set_confdir (GPGRT_CONFDIR_USER, gnupg_homedir ()); /* We are re-using the struct, thus the reset flag. We OR the - * flags so that the internal intialized flag won't be cleared. */ + * flags so that the internal initialized flag won't be cleared. */ argc = orig_argc; argv = orig_argv; pargs.argc = &argc; @@ -1748,7 +1748,7 @@ dirmngr_deinit_default_ctrl (ctrl_t ctrl) The format of such a file is line oriented where empty lines and lines starting with a hash mark are ignored. All other lines are - assumed to be colon seprated with these fields: + assumed to be colon separated with these fields: 1. field: Hostname 2. field: Portnumber diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index 50c97f140..ace40e6d5 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -241,7 +241,7 @@ struct server_control_s int audit_events; /* Send audit events to client. */ char *http_proxy; /* The used http_proxy or NULL. */ - nvc_t rootdse; /* Container wit the rootDSE properties. */ + nvc_t rootdse; /* Container with the rootDSE properties. */ unsigned int timeout; /* Timeout for connect calls in ms. */ diff --git a/dirmngr/dns.c b/dirmngr/dns.c index e0eb33244..f023e7395 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -9761,7 +9761,7 @@ struct dns_addrinfo *dns_ai_open(const char *host, const char *serv, enum dns_ty /* * FIXME: If an explicit A or AAAA record type conflicts with * .ai_family or with resconf.family (i.e. AAAA specified but - * AF_INET6 not in interection of .ai_family and resconf.family), + * AF_INET6 not in intersection of .ai_family and resconf.family), * then what? */ switch (ai->qtype) { diff --git a/dirmngr/http-ntbtls.c b/dirmngr/http-ntbtls.c index 2191acb60..c251f57ef 100644 --- a/dirmngr/http-ntbtls.c +++ b/dirmngr/http-ntbtls.c @@ -78,7 +78,7 @@ gnupg_http_tls_verify_cb (void *opaque, validate_flags = VALIDATE_FLAG_TLS; /* If we are using the standard hkps:// pool use the dedicated root - * certificate. Note that this differes from the GnuTLS + * certificate. Note that this differs from the GnuTLS * implementation which uses this special certificate only if no * other certificates are configured. */ /* Disabled for 2.3.2 to due problems with the standard hkps pool. */ diff --git a/dirmngr/http.c b/dirmngr/http.c index 6ae9029be..5723a13f2 100644 --- a/dirmngr/http.c +++ b/dirmngr/http.c @@ -295,7 +295,7 @@ struct http_session_s } verify; char *servername; /* Malloced server name. */ - /* A callback function to log details of TLS certifciates. */ + /* A callback function to log details of TLS certificates. */ void (*cert_log_cb) (http_session_t, gpg_error_t, const char *, const void **, size_t *); @@ -2018,7 +2018,7 @@ w32_get_proxy (const char *url) * If OVERRIDE_PROXY is not NULL and not empty, this proxy will be * used instead of any configured or dynamically determined proxy. If * the function runs into an error an error code is returned and NULL - * is stored at R_PROXY. If the fucntion was successful and a proxy + * is stored at R_PROXY. If the function was successful and a proxy * is to be used, information on the procy is stored at R_PROXY; if no * proxy shall be used R_PROXY is set to NULL. Caller should always * use release_proxy_info on the value stored at R_PROXY. */ @@ -2358,8 +2358,8 @@ run_gnutls_handshake (http_t hd, const char *server) #endif /*HTTP_USE_GNUTLS*/ -/* It INPUTSTRING is NULL get the intial token. If INPUTSTRING is not - * NULL, decode the string and use this as input from teh server. On +/* It INPUTSTRING is NULL get the initial token. If INPUTSTRING is not + * NULL, decode the string and use this as input from the server. On * success the final output token is stored at PROXY->OUTTOKEN and * OUTTOKLEN. IF the authentication succeeded OUTTOKLEN is zero. */ static gpg_error_t @@ -2379,7 +2379,7 @@ proxy_get_token (proxy_info_t proxy, const char *inputstring) if (inputstring) { - /* The input is expected in the token parameter but the paremter + /* The input is expected in the token parameter but the parameter * name is often forgotten. Thus we simply detect the parameter * name and skip it, assuming no other parameters are given. */ if (!strncmp (inputstring, "token=", 6)) @@ -4424,8 +4424,8 @@ same_host_p (parsed_uri_t a, parsed_uri_t b) /* Prepare a new URL for a HTTP redirect. INFO has flags controlling * the operation, STATUS_CODE is used for diagnostics, LOCATION is the - * value of the "Location" header, and R_URL reveives the new URL on - * success or NULL or error. Note that INFO->ORIG_URL is + * value of the "Location" header, and R_URL receives the new URL on + * success or NULL on error. Note that INFO->ORIG_URL is * required. */ gpg_error_t http_prepare_redirect (http_redir_info_t *info, unsigned int status_code, @@ -4596,7 +4596,7 @@ http_status2string (unsigned int status) } -/* Fucntion called on SIGHUP to flush internal variables. */ +/* Function called on SIGHUP to flush internal variables. */ void http_reinitialize (void) { diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index 688972a89..c2c57d819 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -53,7 +53,7 @@ #define SERVERINFO_PGPKEYV2 2 /* Needs "pgpKeyV2" instead of "pgpKey"*/ #define SERVERINFO_SCHEMAV2 4 /* Version 2 of the Schema. */ #define SERVERINFO_NTDS 8 /* Server is an Active Directory. */ -#define SERVERINFO_GENERIC 16 /* Connected in genric mode. */ +#define SERVERINFO_GENERIC 16 /* Connected in generic mode. */ /* The page size requested from the server. */ @@ -1257,7 +1257,7 @@ return_all_attributes (LDAP *ld, LDAPMessage *msg, estream_t *fp) } /* Always print the DN - note that by using only unbkown attributes - * it is pissible to list just the DNs with out addiional + * it is possible to list just the DNs with out additional * linefeeds. */ es_fprintf (*fp, "Dn: %s\n", mydn? mydn : "[oops DN missing]"); @@ -1307,7 +1307,7 @@ return_all_attributes (LDAP *ld, LDAPMessage *msg, estream_t *fp) len = values[idx]->bv_len; while (len && (s = memchr (val, '\n', len))) { - s++; /* We als want to print the LF. */ + s++; /* We also want to print the LF. */ if (es_fwrite (val, s - val, 1, *fp) != 1) goto fwrite_failed; len -= (s-val); @@ -2361,7 +2361,7 @@ modlist_free (LDAPMod **modlist) LDAPMod *mod = *ml; char **ptr; - /* The list of values is a NULL termianted array of pointers. + /* The list of values is a NULL terminated array of pointers. If the list is NULL, there are no values. */ if (mod->mod_values) @@ -2460,7 +2460,7 @@ uncescape (char *str) /* Given one line from an info block (`gpg --list-{keys,sigs} --with-colons KEYID'), pull it apart and fill in the modlist with the relevant (for the LDAP schema) attributes. EXTRACT_STATE - should initally be set to 0 by the caller. SCHEMAV2 is set if the + should initially be set to 0 by the caller. SCHEMAV2 is set if the server supports the version 2 schema. */ static void extract_attributes (LDAPMod ***modlist, int *extract_state, @@ -2620,7 +2620,7 @@ extract_attributes (LDAPMod ***modlist, int *extract_state, memset (&tm, 0, sizeof (tm)); - /* parse_timestamp handles both seconds fromt he epoch and + /* parse_timestamp handles both seconds from the epoch and ISO 8601 format. We also need to handle YYYY-MM-DD format (as generated by gpg1 --with-colons --list-key). Check that first and then if it fails, then try @@ -2668,7 +2668,7 @@ extract_attributes (LDAPMod ***modlist, int *extract_state, memset (&tm, 0, sizeof (tm)); - /* parse_timestamp handles both seconds fromt he epoch and + /* parse_timestamp handles both seconds from the epoch and ISO 8601 format. We also need to handle YYYY-MM-DD format (as generated by gpg1 --with-colons --list-key). Check that first and then if it fails, then try diff --git a/dirmngr/ldap-misc.c b/dirmngr/ldap-misc.c index c3a659d5c..a3aef0e62 100644 --- a/dirmngr/ldap-misc.c +++ b/dirmngr/ldap-misc.c @@ -220,7 +220,7 @@ ldap_to_gpg_err (LDAP *ld) * ^&SCOPE&(objectClasses=*) * * Give a scope and a filter. Note that R_SCOPE is only changed if a - * STRING has scope parameter. Setting this initally to -1 allows to + * STRING has scope parameter. Setting this initially to -1 allows to * detect this case. */ gpg_error_t diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c index b80012d03..c1ea04979 100644 --- a/dirmngr/ldap.c +++ b/dirmngr/ldap.c @@ -256,7 +256,7 @@ url_fetch_ldap (ctrl_t ctrl, const char *url, ksba_reader_t *reader) } if (ludp->lud_scheme && !strcmp (ludp->lud_scheme, "ldaps")) - tls_mode = 2; /* LDAP-over-TLS here becuase we get it from certs. */ + tls_mode = 2; /* LDAP-over-TLS here because we get it from certs. */ else tls_mode = 0; @@ -524,7 +524,7 @@ make_one_filter (const char *pattern, char **r_result) if (*pattern) { /* We need just the BaseDN. This assumes that the Subject - * is correcly stored in the DT. This is however not always + * is correctly stored in the DT. This is however not always * the case and the actual DN is different from the * subject. In this case we won't find anything. */ if (extfilt_need_escape (pattern) @@ -606,7 +606,7 @@ make_one_filter (const char *pattern, char **r_result) /* Prepare an LDAP query to return the cACertificate attribute for DN. * All configured default servers are queried until one responds. * This function returns an error code or 0 and stored a newly - * allocated contect object at CONTEXT on success. */ + * allocated context object at CONTEXT on success. */ gpg_error_t start_cacert_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *r_context, const char *dn) @@ -778,7 +778,7 @@ start_cert_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *r_context, if (argc >= DIM (argv) - 1) { /* Too many patterns. It does not make sense to allow an - arbitrary number of patters because the length of the + arbitrary number of patterns because the length of the command line is limited anyway. */ err = gpg_error (GPG_ERR_RESOURCE_LIMIT); goto leave; diff --git a/dirmngr/ldapserver.c b/dirmngr/ldapserver.c index ed38c7101..8cd193f86 100644 --- a/dirmngr/ldapserver.c +++ b/dirmngr/ldapserver.c @@ -60,7 +60,7 @@ ldapserver_list_free (ldap_server_t servers) * Flags are: * * starttls := Use STARTTLS with a default port of 389 - * ldaptls := Tunnel LDAP trough a TLS tunnel with default port 636 + * ldaptls := Tunnel LDAP through a TLS tunnel with default port 636 * plain := Switch to plain unsecured LDAP. * (The last of these 3 flags is the effective one) * ntds := Use Active Directory authentication diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c index ad7ed962a..7de8b10e4 100644 --- a/dirmngr/ocsp.c +++ b/dirmngr/ocsp.c @@ -31,7 +31,7 @@ #include "certcache.h" #include "ocsp.h" -/* The maximum size we allow as a response from an OCSP reponder. */ +/* The maximum size we allow as a response from an OCSP responder. */ #define MAX_RESPONSE_SIZE 65536 @@ -526,7 +526,7 @@ check_signature_core (ctrl_t ctrl, ksba_cert_t cert, gcry_sexp_t s_sig, /* Check the signature of an OCSP response. OCSP is the context, S_SIG the signature value and MD the handle of the hash we used for the response. This function automagically finds the correct public - key. If SIGNER_FPR_LIST is not NULL, the default OCSP reponder has been + key. If SIGNER_FPR_LIST is not NULL, the default OCSP responder has been used and thus the certificate is one of those identified by the fingerprints. */ static gpg_error_t @@ -651,7 +651,7 @@ check_signature (ctrl_t ctrl, or directly through the CERT object is valid by running an OCSP transaction. With FORCE_DEFAULT_RESPONDER set only the configured default responder is used. If R_REVOKED_AT or R_REASON are not - NULL and the certificat has been revoked the revocation time and + NULL and the certificate has been revoked the revocation time and the reasons are stored there. */ gpg_error_t ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr, @@ -723,7 +723,7 @@ ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr, } /* Figure out the OCSP responder to use. - 1. Try to get the reponder from the certificate. + 1. Try to get the responder from the certificate. We do only take http and https style URIs into account. 2. If this fails use the default responder, if any. */ diff --git a/dirmngr/server.c b/dirmngr/server.c index 32c85d07b..710317e5e 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -932,7 +932,7 @@ proc_wkd_get (ctrl_t ctrl, assuan_context_t ctx, char *line) err = get_dns_srv (ctrl, domain, "openpgpkey", NULL, &srvs, &srvscount); if (err) { - /* Ignore server failed becuase there are too many resolvers + /* Ignore server failed because there are too many resolvers * which do not work as expected. */ if (gpg_err_code (err) == GPG_ERR_SERVER_FAILED) err = 0; /*(srvcount is guaranteed to be 0)*/ diff --git a/dirmngr/t-ldap-parse-uri.c b/dirmngr/t-ldap-parse-uri.c index 984e1412f..e46bbee83 100644 --- a/dirmngr/t-ldap-parse-uri.c +++ b/dirmngr/t-ldap-parse-uri.c @@ -291,7 +291,7 @@ main (int argc, char **argv) } if (argc) { - fprintf (stderr, PGM ": no argumenst are expected\n"); + fprintf (stderr, PGM ": no arguments are expected\n"); exit (1); } diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 02db3c270..94a468b38 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -42,7 +42,7 @@ enum cert_usage_modes CERT_USAGE_MODE_VRFY, /* Usable for verification. */ CERT_USAGE_MODE_DECR, /* Usable for decryption. */ CERT_USAGE_MODE_CERT, /* Usable for cert signing. */ - CERT_USAGE_MODE_OCSP, /* Usable for OCSP respone signing. */ + CERT_USAGE_MODE_OCSP, /* Usable for OCSP response signing. */ CERT_USAGE_MODE_CRL /* Usable for CRL signing. */ }; @@ -56,7 +56,7 @@ struct chain_item_s ksba_cert_t cert; /* The certificate. */ unsigned char fpr[20]; /* Fingerprint of the certificate. */ int is_self_signed; /* This certificate is self-signed. */ - int is_valid; /* The certifiate is valid except for revocations. */ + int is_valid; /* The certificate is valid except for revocations. */ }; typedef struct chain_item_s *chain_item_t; @@ -173,7 +173,7 @@ check_cert_policy (ksba_cert_t cert) if (err) return err; - /* STRING is a line delimited list of certifiate policies as stored + /* STRING is a line delimited list of certificate policies as stored in the certificate. The line itself is colon delimited where the first field is the OID of the policy and the second field either N or C for normal or critical extension */ diff --git a/doc/DETAILS b/doc/DETAILS index a278d045f..c689046be 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -132,7 +132,7 @@ described here. *** Field 5 - KeyID This is the 64 bit keyid as specified by OpenPGP and the last 64 - bit of the SHA-1 fingerprint of an X.509 certifciate. + bit of the SHA-1 fingerprint of an X.509 certificate. *** Field 6 - Creation date @@ -1101,7 +1101,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: gpg-agent. - keyedit.passwd :: Changing the password failed. - nomdc_with_legacy_cipher :: The message was not MDC protected. - Use the command line to lern about a workaround. + Use the command line to learn about a workaround. - random-compliance :: The random number generator or the used version of Libgcrypt do not fulfill the requirements of the current compliance setting. The error code is often @@ -1179,7 +1179,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: . For example "B", "KiB", or "MiB". *** BACKUP_KEY_CREATED - A backup of a key identified by has been writte to + A backup of a key identified by has been written to the file ; is percent-escaped. *** MOUNTPOINT @@ -1263,7 +1263,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: *** CERTINFO [