mirror of
git://git.gnupg.org/gnupg.git
synced 2024-05-27 21:41:23 +02:00
Compute the fingerprint for ECDH only on demand.
This also fixes a failed assertion when using a v3 key where the fingerprint size is not 20.
This commit is contained in:
parent
4659c923a0
commit
20f429f735
|
@ -1,5 +1,11 @@
|
||||||
2011-02-02 Werner Koch <wk@g10code.com>
|
2011-02-02 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* encrypt.c (write_pubkey_enc_from_list): Don't compute the
|
||||||
|
fingerprint.
|
||||||
|
* pkglue.c (pk_encrypt): Replace PK_FP by PK and compute the
|
||||||
|
fingerprint only when needed.
|
||||||
|
* pkglue.h: Include packet.h.
|
||||||
|
|
||||||
* import.c (transfer_secret_keys): Make sure keyids are available.
|
* import.c (transfer_secret_keys): Make sure keyids are available.
|
||||||
|
|
||||||
* keyid.c (hash_public_key): Adjust for the ECC case.
|
* keyid.c (hash_public_key): Adjust for the ECC case.
|
||||||
|
|
129
g10/encrypt.c
129
g10/encrypt.c
|
@ -84,7 +84,7 @@ encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey)
|
||||||
/* The encrypted session key is prefixed with a one-octet algorithm id. */
|
/* The encrypted session key is prefixed with a one-octet algorithm id. */
|
||||||
buf[0] = (*seskey)->algo;
|
buf[0] = (*seskey)->algo;
|
||||||
memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen );
|
memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen );
|
||||||
|
|
||||||
/* We only pass already checked values to the following fucntion,
|
/* We only pass already checked values to the following fucntion,
|
||||||
thus we consider any failure as fatal. */
|
thus we consider any failure as fatal. */
|
||||||
if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
|
if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
|
||||||
|
@ -119,7 +119,7 @@ use_mdc(PK_LIST pk_list,int algo)
|
||||||
|
|
||||||
if(select_mdc_from_pklist(pk_list))
|
if(select_mdc_from_pklist(pk_list))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* The keys don't support MDC, so now we do a bit of a hack - if any
|
/* The keys don't support MDC, so now we do a bit of a hack - if any
|
||||||
of the AESes or TWOFISH are in the prefs, we assume that the user
|
of the AESes or TWOFISH are in the prefs, we assume that the user
|
||||||
can handle a MDC. This is valid for PGP 7, which can handle MDCs
|
can handle a MDC. This is valid for PGP 7, which can handle MDCs
|
||||||
|
@ -181,7 +181,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
||||||
memset( &zfx, 0, sizeof zfx);
|
memset( &zfx, 0, sizeof zfx);
|
||||||
memset( &tfx, 0, sizeof tfx);
|
memset( &tfx, 0, sizeof tfx);
|
||||||
init_packet(&pkt);
|
init_packet(&pkt);
|
||||||
|
|
||||||
/* Prepare iobufs. */
|
/* Prepare iobufs. */
|
||||||
inp = iobuf_open(filename);
|
inp = iobuf_open(filename);
|
||||||
if (inp)
|
if (inp)
|
||||||
|
@ -200,23 +200,23 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
||||||
release_progress_context (pfx);
|
release_progress_context (pfx);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_progress (pfx, inp, filename);
|
handle_progress (pfx, inp, filename);
|
||||||
|
|
||||||
if (opt.textmode)
|
if (opt.textmode)
|
||||||
iobuf_push_filter( inp, text_filter, &tfx );
|
iobuf_push_filter( inp, text_filter, &tfx );
|
||||||
|
|
||||||
/* Due the the fact that we use don't use an IV to encrypt the
|
/* Due the the fact that we use don't use an IV to encrypt the
|
||||||
session key we can't use the new mode with RFC1991 because it has
|
session key we can't use the new mode with RFC1991 because it has
|
||||||
no S2K salt. RFC1991 always uses simple S2K. */
|
no S2K salt. RFC1991 always uses simple S2K. */
|
||||||
if ( RFC1991 && use_seskey )
|
if ( RFC1991 && use_seskey )
|
||||||
use_seskey = 0;
|
use_seskey = 0;
|
||||||
|
|
||||||
cfx.dek = NULL;
|
cfx.dek = NULL;
|
||||||
if ( mode )
|
if ( mode )
|
||||||
{
|
{
|
||||||
int canceled;
|
int canceled;
|
||||||
|
|
||||||
s2k = xmalloc_clear( sizeof *s2k );
|
s2k = xmalloc_clear( sizeof *s2k );
|
||||||
s2k->mode = RFC1991? 0:opt.s2k_mode;
|
s2k->mode = RFC1991? 0:opt.s2k_mode;
|
||||||
s2k->hash_algo = S2K_DIGEST_ALGO;
|
s2k->hash_algo = S2K_DIGEST_ALGO;
|
||||||
|
@ -233,37 +233,37 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
||||||
release_progress_context (pfx);
|
release_progress_context (pfx);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if (use_seskey && s2k->mode != 1 && s2k->mode != 3)
|
if (use_seskey && s2k->mode != 1 && s2k->mode != 3)
|
||||||
{
|
{
|
||||||
use_seskey = 0;
|
use_seskey = 0;
|
||||||
log_info (_("can't use a symmetric ESK packet "
|
log_info (_("can't use a symmetric ESK packet "
|
||||||
"due to the S2K mode\n"));
|
"due to the S2K mode\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( use_seskey )
|
if ( use_seskey )
|
||||||
{
|
{
|
||||||
DEK *dek = NULL;
|
DEK *dek = NULL;
|
||||||
|
|
||||||
seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ());
|
seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ());
|
||||||
encrypt_seskey( cfx.dek, &dek, enckey );
|
encrypt_seskey( cfx.dek, &dek, enckey );
|
||||||
xfree( cfx.dek ); cfx.dek = dek;
|
xfree( cfx.dek ); cfx.dek = dek;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info(_("using cipher %s\n"),
|
log_info(_("using cipher %s\n"),
|
||||||
openpgp_cipher_algo_name (cfx.dek->algo));
|
openpgp_cipher_algo_name (cfx.dek->algo));
|
||||||
|
|
||||||
cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
|
cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_compress && cfx.dek && cfx.dek->use_mdc
|
if (do_compress && cfx.dek && cfx.dek->use_mdc
|
||||||
&& is_file_compressed(filename, &rc))
|
&& is_file_compressed(filename, &rc))
|
||||||
{
|
{
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info(_("`%s' already compressed\n"), filename);
|
log_info(_("`%s' already compressed\n"), filename);
|
||||||
do_compress = 0;
|
do_compress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, &out )))
|
if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, &out )))
|
||||||
{
|
{
|
||||||
iobuf_cancel (inp);
|
iobuf_cancel (inp);
|
||||||
|
@ -272,7 +272,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
||||||
release_progress_context (pfx);
|
release_progress_context (pfx);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( opt.armor )
|
if ( opt.armor )
|
||||||
{
|
{
|
||||||
afx = new_armor_context ();
|
afx = new_armor_context ();
|
||||||
|
@ -296,7 +296,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
||||||
log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
|
log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
|
||||||
xfree (enc);
|
xfree (enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opt.no_literal)
|
if (!opt.no_literal)
|
||||||
pt = setup_plaintext_name (filename, inp);
|
pt = setup_plaintext_name (filename, inp);
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
||||||
pkt.pkttype = 0;
|
pkt.pkttype = 0;
|
||||||
pkt.pkt.generic = NULL;
|
pkt.pkt.generic = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register the cipher filter. */
|
/* Register the cipher filter. */
|
||||||
if (mode)
|
if (mode)
|
||||||
iobuf_push_filter ( out, cipher_filter, &cfx );
|
iobuf_push_filter ( out, cipher_filter, &cfx );
|
||||||
|
@ -359,14 +359,14 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
||||||
zfx.new_ctb = 1;
|
zfx.new_ctb = 1;
|
||||||
push_compress_filter (out, &zfx, default_compress_algo());
|
push_compress_filter (out, &zfx, default_compress_algo());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the work. */
|
/* Do the work. */
|
||||||
if (!opt.no_literal)
|
if (!opt.no_literal)
|
||||||
{
|
{
|
||||||
if ( (rc = build_packet( out, &pkt )) )
|
if ( (rc = build_packet( out, &pkt )) )
|
||||||
log_error("build_packet failed: %s\n", g10_errstr(rc) );
|
log_error("build_packet failed: %s\n", g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* User requested not to create a literal packet, so we copy the
|
/* User requested not to create a literal packet, so we copy the
|
||||||
plain data. */
|
plain data. */
|
||||||
|
@ -380,12 +380,12 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
||||||
}
|
}
|
||||||
wipememory (copy_buffer, 4096); /* burn buffer */
|
wipememory (copy_buffer, 4096); /* burn buffer */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish the stuff. */
|
/* Finish the stuff. */
|
||||||
iobuf_close (inp);
|
iobuf_close (inp);
|
||||||
if (rc)
|
if (rc)
|
||||||
iobuf_cancel(out);
|
iobuf_cancel(out);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
iobuf_close (out); /* fixme: check returncode */
|
iobuf_close (out); /* fixme: check returncode */
|
||||||
if (mode)
|
if (mode)
|
||||||
|
@ -425,7 +425,7 @@ setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
||||||
iobuf_t out)
|
iobuf_t out)
|
||||||
{
|
{
|
||||||
int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo);
|
int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo);
|
||||||
|
@ -492,7 +492,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
memset( &tfx, 0, sizeof tfx);
|
memset( &tfx, 0, sizeof tfx);
|
||||||
init_packet(&pkt);
|
init_packet(&pkt);
|
||||||
|
|
||||||
if (use_symkey
|
if (use_symkey
|
||||||
&& (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
|
&& (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
|
||||||
{
|
{
|
||||||
release_progress_context (pfx);
|
release_progress_context (pfx);
|
||||||
|
@ -509,7 +509,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(PGP2)
|
if(PGP2)
|
||||||
{
|
{
|
||||||
for (work_list=pk_list; work_list; work_list=work_list->next)
|
for (work_list=pk_list; work_list; work_list=work_list->next)
|
||||||
|
@ -560,17 +560,17 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
rc = open_outfile (outputfd, filename, opt.armor? 1:0, &out);
|
rc = open_outfile (outputfd, filename, opt.armor? 1:0, &out);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
if (opt.armor)
|
if (opt.armor)
|
||||||
{
|
{
|
||||||
afx = new_armor_context ();
|
afx = new_armor_context ();
|
||||||
push_armor_filter (afx, out);
|
push_armor_filter (afx, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a session key. */
|
/* Create a session key. */
|
||||||
cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
|
cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
|
||||||
if (!opt.def_cipher_algo)
|
if (!opt.def_cipher_algo)
|
||||||
{
|
{
|
||||||
/* Try to get it from the prefs. */
|
/* Try to get it from the prefs. */
|
||||||
cfx.dek->algo = select_algo_from_prefs (pk_list, PREFTYPE_SYM, -1, NULL);
|
cfx.dek->algo = select_algo_from_prefs (pk_list, PREFTYPE_SYM, -1, NULL);
|
||||||
/* The only way select_algo_from_prefs can fail here is when
|
/* The only way select_algo_from_prefs can fail here is when
|
||||||
|
@ -582,7 +582,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
if (cfx.dek->algo == -1)
|
if (cfx.dek->algo == -1)
|
||||||
{
|
{
|
||||||
cfx.dek->algo = CIPHER_ALGO_3DES;
|
cfx.dek->algo = CIPHER_ALGO_3DES;
|
||||||
|
|
||||||
if (PGP2)
|
if (PGP2)
|
||||||
{
|
{
|
||||||
log_info(_("unable to use the IDEA cipher for all of the keys "
|
log_info(_("unable to use the IDEA cipher for all of the keys "
|
||||||
|
@ -610,12 +610,12 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
openpgp_cipher_algo_name (opt.def_cipher_algo),
|
openpgp_cipher_algo_name (opt.def_cipher_algo),
|
||||||
opt.def_cipher_algo);
|
opt.def_cipher_algo);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfx.dek->algo = opt.def_cipher_algo;
|
cfx.dek->algo = opt.def_cipher_algo;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo);
|
cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo);
|
||||||
|
|
||||||
/* Only do the is-file-already-compressed check if we are using a
|
/* Only do the is-file-already-compressed check if we are using a
|
||||||
MDC. This forces compressed files to be re-compressed if we do
|
MDC. This forces compressed files to be re-compressed if we do
|
||||||
not have a MDC to give some protection against chosen ciphertext
|
not have a MDC to give some protection against chosen ciphertext
|
||||||
|
@ -625,7 +625,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
{
|
{
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info(_("`%s' already compressed\n"), filename);
|
log_info(_("`%s' already compressed\n"), filename);
|
||||||
do_compress = 0;
|
do_compress = 0;
|
||||||
}
|
}
|
||||||
if (rc2)
|
if (rc2)
|
||||||
{
|
{
|
||||||
|
@ -636,7 +636,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
make_session_key (cfx.dek);
|
make_session_key (cfx.dek);
|
||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
||||||
|
|
||||||
rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out);
|
rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
@ -647,16 +647,16 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
secret key needed to decrypt. */
|
secret key needed to decrypt. */
|
||||||
if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
|
if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
if (!opt.no_literal)
|
if (!opt.no_literal)
|
||||||
pt = setup_plaintext_name (filename, inp);
|
pt = setup_plaintext_name (filename, inp);
|
||||||
|
|
||||||
if (filefd != -1
|
if (filefd != -1
|
||||||
&& !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
|
&& !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
|
||||||
{
|
{
|
||||||
off_t tmpsize;
|
off_t tmpsize;
|
||||||
int overflow;
|
int overflow;
|
||||||
|
|
||||||
if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
|
if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
|
||||||
&& !overflow && opt.verbose)
|
&& !overflow && opt.verbose)
|
||||||
log_info(_("WARNING: `%s' is an empty file\n"), filename );
|
log_info(_("WARNING: `%s' is an empty file\n"), filename );
|
||||||
|
@ -672,7 +672,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
else
|
else
|
||||||
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
|
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
|
||||||
|
|
||||||
if (!opt.no_literal)
|
if (!opt.no_literal)
|
||||||
{
|
{
|
||||||
pt->timestamp = make_timestamp();
|
pt->timestamp = make_timestamp();
|
||||||
pt->mode = opt.textmode ? 't' : 'b';
|
pt->mode = opt.textmode ? 't' : 'b';
|
||||||
|
@ -693,7 +693,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
if (do_compress)
|
if (do_compress)
|
||||||
{
|
{
|
||||||
int compr_algo = opt.compress_algo;
|
int compr_algo = opt.compress_algo;
|
||||||
|
|
||||||
if (compr_algo == -1)
|
if (compr_algo == -1)
|
||||||
{
|
{
|
||||||
compr_algo = select_algo_from_prefs (pk_list, PREFTYPE_ZIP, -1, NULL);
|
compr_algo = select_algo_from_prefs (pk_list, PREFTYPE_ZIP, -1, NULL);
|
||||||
|
@ -702,7 +702,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
/* Theoretically impossible to get here since uncompressed
|
/* Theoretically impossible to get here since uncompressed
|
||||||
is implicit. */
|
is implicit. */
|
||||||
}
|
}
|
||||||
else if (!opt.expert
|
else if (!opt.expert
|
||||||
&& select_algo_from_prefs(pk_list, PREFTYPE_ZIP,
|
&& select_algo_from_prefs(pk_list, PREFTYPE_ZIP,
|
||||||
compr_algo, NULL) != compr_algo)
|
compr_algo, NULL) != compr_algo)
|
||||||
{
|
{
|
||||||
|
@ -710,7 +710,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
" violates recipient preferences\n"),
|
" violates recipient preferences\n"),
|
||||||
compress_algo_to_string(compr_algo), compr_algo);
|
compress_algo_to_string(compr_algo), compr_algo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Algo 0 means no compression. */
|
/* Algo 0 means no compression. */
|
||||||
if (compr_algo)
|
if (compr_algo)
|
||||||
{
|
{
|
||||||
|
@ -719,7 +719,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
push_compress_filter (out,&zfx,compr_algo);
|
push_compress_filter (out,&zfx,compr_algo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the work. */
|
/* Do the work. */
|
||||||
if (!opt.no_literal)
|
if (!opt.no_literal)
|
||||||
{
|
{
|
||||||
|
@ -750,7 +750,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||||
iobuf_close (inp);
|
iobuf_close (inp);
|
||||||
if (rc)
|
if (rc)
|
||||||
iobuf_cancel (out);
|
iobuf_cancel (out);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
iobuf_close (out); /* fixme: check returncode */
|
iobuf_close (out); /* fixme: check returncode */
|
||||||
write_status (STATUS_END_ENCRYPTION);
|
write_status (STATUS_END_ENCRYPTION);
|
||||||
|
@ -779,7 +779,7 @@ encrypt_filter (void *opaque, int control,
|
||||||
size_t size = *ret_len;
|
size_t size = *ret_len;
|
||||||
encrypt_filter_context_t *efx = opaque;
|
encrypt_filter_context_t *efx = opaque;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */
|
if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */
|
||||||
{
|
{
|
||||||
BUG(); /* not used */
|
BUG(); /* not used */
|
||||||
|
@ -789,19 +789,19 @@ encrypt_filter (void *opaque, int control,
|
||||||
if ( !efx->header_okay )
|
if ( !efx->header_okay )
|
||||||
{
|
{
|
||||||
efx->cfx.dek = xmalloc_secure_clear ( sizeof *efx->cfx.dek );
|
efx->cfx.dek = xmalloc_secure_clear ( sizeof *efx->cfx.dek );
|
||||||
if ( !opt.def_cipher_algo )
|
if ( !opt.def_cipher_algo )
|
||||||
{
|
{
|
||||||
/* Try to get it from the prefs. */
|
/* Try to get it from the prefs. */
|
||||||
efx->cfx.dek->algo =
|
efx->cfx.dek->algo =
|
||||||
select_algo_from_prefs (efx->pk_list, PREFTYPE_SYM, -1, NULL);
|
select_algo_from_prefs (efx->pk_list, PREFTYPE_SYM, -1, NULL);
|
||||||
if (efx->cfx.dek->algo == -1 )
|
if (efx->cfx.dek->algo == -1 )
|
||||||
{
|
{
|
||||||
/* Because 3DES is implicitly in the prefs, this can
|
/* Because 3DES is implicitly in the prefs, this can
|
||||||
only happen if we do not have any public keys in
|
only happen if we do not have any public keys in
|
||||||
the list. */
|
the list. */
|
||||||
efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
|
efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In case 3DES has been selected, print a warning if
|
/* In case 3DES has been selected, print a warning if
|
||||||
any key does not have a preference for AES. This
|
any key does not have a preference for AES. This
|
||||||
should help to indentify why encrypting to several
|
should help to indentify why encrypting to several
|
||||||
|
@ -810,7 +810,7 @@ encrypt_filter (void *opaque, int control,
|
||||||
&& efx->cfx.dek->algo == CIPHER_ALGO_3DES)
|
&& efx->cfx.dek->algo == CIPHER_ALGO_3DES)
|
||||||
warn_missing_aes_from_pklist (efx->pk_list);
|
warn_missing_aes_from_pklist (efx->pk_list);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!opt.expert
|
if (!opt.expert
|
||||||
&& select_algo_from_prefs (efx->pk_list,PREFTYPE_SYM,
|
&& select_algo_from_prefs (efx->pk_list,PREFTYPE_SYM,
|
||||||
|
@ -820,12 +820,12 @@ encrypt_filter (void *opaque, int control,
|
||||||
"violates recipient preferences\n"),
|
"violates recipient preferences\n"),
|
||||||
openpgp_cipher_algo_name (opt.def_cipher_algo),
|
openpgp_cipher_algo_name (opt.def_cipher_algo),
|
||||||
opt.def_cipher_algo);
|
opt.def_cipher_algo);
|
||||||
|
|
||||||
efx->cfx.dek->algo = opt.def_cipher_algo;
|
efx->cfx.dek->algo = opt.def_cipher_algo;
|
||||||
}
|
}
|
||||||
|
|
||||||
efx->cfx.dek->use_mdc = use_mdc (efx->pk_list,efx->cfx.dek->algo);
|
efx->cfx.dek->use_mdc = use_mdc (efx->pk_list,efx->cfx.dek->algo);
|
||||||
|
|
||||||
make_session_key ( efx->cfx.dek );
|
make_session_key ( efx->cfx.dek );
|
||||||
if (DBG_CIPHER)
|
if (DBG_CIPHER)
|
||||||
log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen);
|
log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen);
|
||||||
|
@ -841,13 +841,13 @@ encrypt_filter (void *opaque, int control,
|
||||||
if(rc)
|
if(rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
iobuf_push_filter (a, cipher_filter, &efx->cfx);
|
iobuf_push_filter (a, cipher_filter, &efx->cfx);
|
||||||
|
|
||||||
efx->header_okay = 1;
|
efx->header_okay = 1;
|
||||||
}
|
}
|
||||||
rc = iobuf_write (a, buf, size);
|
rc = iobuf_write (a, buf, size);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (control == IOBUFCTRL_FREE)
|
else if (control == IOBUFCTRL_FREE)
|
||||||
{
|
{
|
||||||
|
@ -876,11 +876,9 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
|
||||||
for ( ; pk_list; pk_list = pk_list->next )
|
for ( ; pk_list; pk_list = pk_list->next )
|
||||||
{
|
{
|
||||||
gcry_mpi_t frame;
|
gcry_mpi_t frame;
|
||||||
byte fp[MAX_FINGERPRINT_LEN];
|
|
||||||
size_t fpn;
|
|
||||||
|
|
||||||
pk = pk_list->pk;
|
pk = pk_list->pk;
|
||||||
|
|
||||||
print_pubkey_algo_note ( pk->pubkey_algo );
|
print_pubkey_algo_note ( pk->pubkey_algo );
|
||||||
enc = xmalloc_clear ( sizeof *enc );
|
enc = xmalloc_clear ( sizeof *enc );
|
||||||
enc->pubkey_algo = pk->pubkey_algo;
|
enc->pubkey_algo = pk->pubkey_algo;
|
||||||
|
@ -894,9 +892,6 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
|
||||||
compliance_failure();
|
compliance_failure();
|
||||||
}
|
}
|
||||||
|
|
||||||
fingerprint_from_pk (pk, fp, &fpn);
|
|
||||||
assert (fpn == 20);
|
|
||||||
|
|
||||||
/* Okay, what's going on: We have the session key somewhere in
|
/* Okay, what's going on: We have the session key somewhere in
|
||||||
* the structure DEK and want to encode this session key in an
|
* the structure DEK and want to encode this session key in an
|
||||||
* integer value of n bits. pubkey_nbits gives us the number of
|
* integer value of n bits. pubkey_nbits gives us the number of
|
||||||
|
@ -909,9 +904,9 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
|
||||||
* for Elgamal). We don't need frame anymore because we have
|
* for Elgamal). We don't need frame anymore because we have
|
||||||
* everything now in enc->data which is the passed to
|
* everything now in enc->data which is the passed to
|
||||||
* build_packet(). */
|
* build_packet(). */
|
||||||
frame = encode_session_key (pk->pubkey_algo, dek,
|
frame = encode_session_key (pk->pubkey_algo, dek,
|
||||||
pubkey_nbits (pk->pubkey_algo, pk->pkey));
|
pubkey_nbits (pk->pubkey_algo, pk->pkey));
|
||||||
rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, fp, pk->pkey);
|
rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk, pk->pkey);
|
||||||
gcry_mpi_release (frame);
|
gcry_mpi_release (frame);
|
||||||
if (rc)
|
if (rc)
|
||||||
log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
|
log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
|
||||||
|
@ -932,7 +927,7 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
|
||||||
pkt.pkt.pubkey_enc = enc;
|
pkt.pkt.pubkey_enc = enc;
|
||||||
rc = build_packet (out, &pkt);
|
rc = build_packet (out, &pkt);
|
||||||
if (rc)
|
if (rc)
|
||||||
log_error ("build_packet(pubkey_enc) failed: %s\n",
|
log_error ("build_packet(pubkey_enc) failed: %s\n",
|
||||||
g10_errstr (rc));
|
g10_errstr (rc));
|
||||||
}
|
}
|
||||||
free_pubkey_enc(enc);
|
free_pubkey_enc(enc);
|
||||||
|
@ -951,9 +946,9 @@ encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr)
|
||||||
if (opt.outfile)
|
if (opt.outfile)
|
||||||
{
|
{
|
||||||
log_error(_("--output doesn't work for this command\n"));
|
log_error(_("--output doesn't work for this command\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nfiles)
|
if (!nfiles)
|
||||||
{
|
{
|
||||||
char line[2048];
|
char line[2048];
|
||||||
|
|
27
g10/pkglue.c
27
g10/pkglue.c
|
@ -37,7 +37,7 @@ mpi_from_sexp (gcry_sexp_t sexp, const char * item)
|
||||||
{
|
{
|
||||||
gcry_sexp_t list;
|
gcry_sexp_t list;
|
||||||
gcry_mpi_t data;
|
gcry_mpi_t data;
|
||||||
|
|
||||||
list = gcry_sexp_find_token (sexp, item, 0);
|
list = gcry_sexp_find_token (sexp, item, 0);
|
||||||
assert (list);
|
assert (list);
|
||||||
data = gcry_sexp_nth_mpi (list, 1, 0);
|
data = gcry_sexp_nth_mpi (list, 1, 0);
|
||||||
|
@ -151,10 +151,11 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey)
|
||||||
/****************
|
/****************
|
||||||
* Emulate our old PK interface here - sometime in the future we might
|
* Emulate our old PK interface here - sometime in the future we might
|
||||||
* change the internal design to directly fit to libgcrypt.
|
* change the internal design to directly fit to libgcrypt.
|
||||||
|
* PK is only required to compute the fingerprint for ECDH.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
|
pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
|
||||||
const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *pkey)
|
PKT_public_key *pk, gcry_mpi_t *pkey)
|
||||||
{
|
{
|
||||||
gcry_sexp_t s_ciph, s_data, s_pkey;
|
gcry_sexp_t s_ciph, s_data, s_pkey;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -179,15 +180,17 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
|
||||||
if (rc || gcry_sexp_build (&s_data, NULL, "%m", data))
|
if (rc || gcry_sexp_build (&s_data, NULL, "%m", data))
|
||||||
BUG ();
|
BUG ();
|
||||||
}
|
}
|
||||||
else if (algo == PUBKEY_ALGO_ECDH)
|
else if (algo == PUBKEY_ALGO_ECDH)
|
||||||
{
|
{
|
||||||
gcry_mpi_t k;
|
gcry_mpi_t k;
|
||||||
char *curve;
|
char *curve;
|
||||||
|
byte fp[MAX_FINGERPRINT_LEN];
|
||||||
|
size_t fpn;
|
||||||
|
|
||||||
rc = pk_ecdh_generate_ephemeral_key (pkey, &k);
|
rc = pk_ecdh_generate_ephemeral_key (pkey, &k);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
curve = openpgp_oid_to_str (pkey[0]);
|
curve = openpgp_oid_to_str (pkey[0]);
|
||||||
if (!curve)
|
if (!curve)
|
||||||
rc = gpg_error_from_syserror ();
|
rc = gpg_error_from_syserror ();
|
||||||
|
@ -215,12 +218,14 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
;
|
;
|
||||||
else if (algo == PUBKEY_ALGO_ECDH)
|
else if (algo == PUBKEY_ALGO_ECDH)
|
||||||
{
|
{
|
||||||
gcry_mpi_t shared, public, result;
|
gcry_mpi_t shared, public, result;
|
||||||
|
byte fp[MAX_FINGERPRINT_LEN];
|
||||||
|
size_t fpn;
|
||||||
|
|
||||||
/* Get the shared point and the ephemeral public key. */
|
/* Get the shared point and the ephemeral public key. */
|
||||||
shared = mpi_from_sexp (s_ciph, "s");
|
shared = mpi_from_sexp (s_ciph, "s");
|
||||||
public = mpi_from_sexp (s_ciph, "e");
|
public = mpi_from_sexp (s_ciph, "e");
|
||||||
gcry_sexp_release (s_ciph);
|
gcry_sexp_release (s_ciph);
|
||||||
s_ciph = NULL;
|
s_ciph = NULL;
|
||||||
|
@ -230,10 +235,14 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
|
||||||
gcry_mpi_dump (public);
|
gcry_mpi_dump (public);
|
||||||
log_printf ("\n");
|
log_printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
result = NULL;
|
result = NULL;
|
||||||
rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared,
|
fingerprint_from_pk (pk, fp, &fpn);
|
||||||
pk_fp, data, pkey, &result);
|
if (fpn != 20)
|
||||||
|
rc = gpg_error (GPG_ERR_INV_LENGTH);
|
||||||
|
else
|
||||||
|
rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared,
|
||||||
|
fp, data, pkey, &result);
|
||||||
gcry_mpi_release (shared);
|
gcry_mpi_release (shared);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,14 +20,15 @@
|
||||||
#ifndef GNUPG_G10_PKGLUE_H
|
#ifndef GNUPG_G10_PKGLUE_H
|
||||||
#define GNUPG_G10_PKGLUE_H
|
#define GNUPG_G10_PKGLUE_H
|
||||||
|
|
||||||
|
#include "packet.h" /* For PKT_public_key. */
|
||||||
|
|
||||||
/*-- pkglue.c --*/
|
/*-- pkglue.c --*/
|
||||||
gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item);
|
gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item);
|
||||||
|
|
||||||
int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
|
int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
|
||||||
gcry_mpi_t *pkey);
|
gcry_mpi_t *pkey);
|
||||||
int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
|
int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
|
||||||
const byte fp[MAX_FINGERPRINT_LEN],
|
PKT_public_key *pk, gcry_mpi_t *pkey);
|
||||||
gcry_mpi_t *pkey);
|
|
||||||
int pk_check_secret_key (int algo, gcry_mpi_t *skey);
|
int pk_check_secret_key (int algo, gcry_mpi_t *skey);
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ int pk_check_secret_key (int algo, gcry_mpi_t *skey);
|
||||||
gcry_mpi_t pk_ecdh_default_params (unsigned int qbits);
|
gcry_mpi_t pk_ecdh_default_params (unsigned int qbits);
|
||||||
gpg_error_t pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k);
|
gpg_error_t pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k);
|
||||||
gpg_error_t pk_ecdh_encrypt_with_shared_point
|
gpg_error_t pk_ecdh_encrypt_with_shared_point
|
||||||
/* */ (int is_encrypt, gcry_mpi_t shared_mpi,
|
/* */ (int is_encrypt, gcry_mpi_t shared_mpi,
|
||||||
const byte pk_fp[MAX_FINGERPRINT_LEN],
|
const byte pk_fp[MAX_FINGERPRINT_LEN],
|
||||||
gcry_mpi_t data, gcry_mpi_t *pkey,
|
gcry_mpi_t data, gcry_mpi_t *pkey,
|
||||||
gcry_mpi_t *out);
|
gcry_mpi_t *out);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user