diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/call-agent.c | 3 | ||||
-rw-r--r-- | g10/call-dirmngr.c | 3 | ||||
-rw-r--r-- | g10/call-keyboxd.c | 16 | ||||
-rw-r--r-- | g10/card-util.c | 24 | ||||
-rw-r--r-- | g10/cipher-aead.c | 7 | ||||
-rw-r--r-- | g10/cipher-cfb.c | 9 | ||||
-rw-r--r-- | g10/dearmor.c | 4 | ||||
-rw-r--r-- | g10/decrypt.c | 19 | ||||
-rw-r--r-- | g10/encrypt.c | 126 | ||||
-rw-r--r-- | g10/export.c | 22 | ||||
-rw-r--r-- | g10/filter.h | 4 | ||||
-rw-r--r-- | g10/gpg.c | 19 | ||||
-rw-r--r-- | g10/keygen.c | 31 | ||||
-rw-r--r-- | g10/keyid.c | 5 | ||||
-rw-r--r-- | g10/main.h | 18 | ||||
-rw-r--r-- | g10/mainproc.c | 30 | ||||
-rw-r--r-- | g10/mdfilter.c | 295 | ||||
-rw-r--r-- | g10/misc.c | 15 | ||||
-rw-r--r-- | g10/openfile.c | 10 | ||||
-rw-r--r-- | g10/options.h | 4 | ||||
-rw-r--r-- | g10/packet.h | 8 | ||||
-rw-r--r-- | g10/photoid.c | 67 | ||||
-rw-r--r-- | g10/plaintext.c | 27 | ||||
-rw-r--r-- | g10/revoke.c | 4 | ||||
-rw-r--r-- | g10/server.c | 31 | ||||
-rw-r--r-- | g10/sign.c | 83 | ||||
-rw-r--r-- | g10/tdbdump.c | 13 | ||||
-rw-r--r-- | g10/verify.c | 6 |
28 files changed, 618 insertions, 285 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index eb9f8e29b..cb7053396 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -249,7 +249,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 7f4d5f493..960979aae 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); } @@ -143,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) { @@ -223,7 +231,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/g10/card-util.c b/g10/card-util.c index b83472285..088ea824a 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -28,9 +28,7 @@ # include <readline/readline.h> #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) @@ -943,14 +937,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)); @@ -986,14 +972,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)); 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/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/decrypt.c b/g10/decrypt.c index cb9e36a93..b30359af4 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. */ @@ -138,13 +139,25 @@ decrypt_message_fd (ctrl_t ctrl, int input_fd, int output_fd) return err; } - opt.outfp = es_fdopen_nc (output_fd, "wb"); + if (is_secured_file (output_fd)) + { + char xname[64]; + + err = gpg_error (GPG_ERR_EPERM); + 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); + return err; + } + + opt.outfp = open_stream_nc (output_fd, "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]", 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 9aeafa292..62483fa16 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,18 +507,8 @@ 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 ))) + if (rc || (rc = open_outfile (GNUPG_INVALID_FD, filename, opt.armor? 1:0, + 0, &out ))) { iobuf_cancel (inp); xfree (cfx.dek); @@ -598,6 +578,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 +615,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 ) { @@ -773,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; @@ -783,7 +774,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,10 +783,8 @@ 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) + if (filefd != GNUPG_INVALID_FD && filename) return gpg_error (GPG_ERR_INV_ARG); /* Both given. */ do_compress = !!opt.compress_algo; @@ -826,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 { @@ -834,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"); @@ -852,8 +841,8 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, char xname[64]; rc = gpg_error_from_syserror (); - if (filefd != -1) - snprintf (xname, sizeof xname, "[fd %d]", filefd); + if (filefd != GNUPG_INVALID_FD) + snprintf (xname, sizeof xname, "[fd %d]", FD_DBG (filefd)); else if (!filename) strcpy (xname, "[stdin]"); else @@ -866,14 +855,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 +881,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 +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(); @@ -973,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) { @@ -1249,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) ); @@ -1261,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/export.c b/g10/export.c index b3ad69718..2c6eb7bff 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; @@ -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/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 --*/ @@ -1029,6 +1029,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 } }; @@ -1080,10 +1081,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*)) { @@ -3876,8 +3873,8 @@ 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); + assuan_control (ASSUAN_CONTROL_REINIT_SYSCALL_CLAMP, NULL); if (logfile) { @@ -4421,7 +4418,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", @@ -4446,7 +4444,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", @@ -5633,13 +5632,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/keygen.c b/g10/keygen.c index 2f8528278..9b0113c5a 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3309,6 +3309,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. */ @@ -3343,6 +3344,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) @@ -3591,8 +3618,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 4a041ce0e..ed76818a2 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -116,6 +116,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/main.h b/g10/main.h index b29e23e51..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 ); @@ -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, @@ -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); @@ -492,19 +492,21 @@ 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 --*/ 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 ce0fdaaac..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); @@ -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). */ { @@ -2629,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); @@ -2660,7 +2659,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 +2679,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) { @@ -2772,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)); @@ -2807,7 +2808,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); 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 <stdlib.h> #include <string.h> #include <errno.h> +#include <npth.h> #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/misc.c b/g10/misc.c index 2f4b452dd..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; @@ -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; } diff --git a/g10/openfile.c b/g10/openfile.c index 5ca168a13..01f323399 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]; @@ -193,12 +193,12 @@ open_outfile (int out_fd, const char *iname, int mode, int restrictedperm, if (!*a) { rc = gpg_error_from_syserror (); - snprintf (xname, sizeof xname, "[fd %d]", 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]", out_fd); + snprintf (xname, sizeof xname, "[fd %d]", FD_DBG (out_fd)); log_info (_("writing to '%s'\n"), xname); } } diff --git a/g10/options.h b/g10/options.h index e0ee99533..5326ac8d8 100644 --- a/g10/options.h +++ b/g10/options.h @@ -374,7 +374,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/packet.h b/g10/packet.h index 39dab96c9..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. */ @@ -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/photoid.c b/g10/photoid.c index fc8866121..8cc7e3a20 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -27,9 +27,6 @@ # include <winsock2.h> # endif # include <windows.h> -# ifndef VER_PLATFORM_WIN32_WINDOWS -# define VER_PLATFORM_WIN32_WINDOWS 1 -# endif #endif #include "gpg.h" @@ -95,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) { @@ -381,16 +385,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"; @@ -600,34 +595,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_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_wait_process (argv[0], pid, 1, NULL); + err = gnupg_process_wait (proc, 1); if (err) log_error (_("unnatural exit of external program\n")); + + gnupg_process_release (proc); } #endif /* !EXEC_TEMPFILE_ONLY */ } @@ -695,14 +691,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/g10/plaintext.c b/g10/plaintext.c index 5c21dd7f6..a96214994 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]", FD_DBG (fd)); log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (err)); goto leave; } @@ -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); @@ -146,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)) { @@ -729,8 +722,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; @@ -747,7 +740,7 @@ hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd, { 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/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/server.c b/g10/server.c index 60b447c41..24e525e7f 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; @@ -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/g10/sign.c b/g10/sign.c index f9984f811..ee3fac1df 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 = NULL; 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; @@ -1034,9 +1036,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 +1094,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); } @@ -1124,7 +1115,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; @@ -1137,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 @@ -1237,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; @@ -1260,7 +1262,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]"); @@ -1303,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) @@ -1343,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); @@ -1372,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) @@ -1389,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; @@ -1470,7 +1481,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; } @@ -1572,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; @@ -1648,22 +1661,32 @@ 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; /* 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) @@ -1705,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) */ @@ -1717,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) @@ -1734,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); 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; diff --git a/g10/verify.c b/g10/verify.c index e9792939d..f8abadd45 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; @@ -260,7 +261,8 @@ gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp) 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; } |