1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

Update head to match stable 1.0

This commit is contained in:
David Shaw 2002-06-29 13:46:34 +00:00
parent 151ee2f47b
commit 3f51f7db3d
155 changed files with 83872 additions and 37585 deletions

View file

@ -1,5 +1,5 @@
/* encode.c - encode data
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -30,69 +30,18 @@
#include "errors.h"
#include "iobuf.h"
#include "keydb.h"
#include <gcrypt.h>
#include "memory.h"
#include "util.h"
#include "main.h"
#include "filter.h"
#include "trustdb.h"
#include "i18n.h"
#include "status.h"
static int encode_simple( const char *filename, int mode );
static int encode_simple( const char *filename, int mode, int compat );
static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out );
/****************
* Emulate our old PK interface here - sometime in the future we might
* change the internal design to directly fit to libgcrypt.
*/
static int
pk_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
{
GCRY_SEXP s_ciph, s_data, s_pkey;
int rc;
/* make a sexp from pkey */
if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
rc = gcry_sexp_build ( &s_pkey, NULL,
"(public-key(elg(p%m)(g%m)(y%m)))",
pkey[0], pkey[1], pkey[2] );
}
else
return GPGERR_PUBKEY_ALGO;
if ( rc )
BUG ();
/* put the data into a simple list */
if ( gcry_sexp_build( &s_data, NULL, "%m", data ) )
BUG ();
/* pass it to libgcrypt */
rc = gcry_pk_encrypt( &s_ciph, s_data, s_pkey );
gcry_sexp_release( s_data );
gcry_sexp_release( s_pkey );
if( rc )
;
else { /* add better error handling or make gnupg use S-Exp directly */
GCRY_SEXP list = gcry_sexp_find_token( s_ciph, "a" , 0 );
assert( list );
resarr[0] = gcry_sexp_nth_mpi( list, 1, 0 );
assert( resarr[0] );
gcry_sexp_release ( list );
list = gcry_sexp_find_token( s_ciph, "b" , 0 );
assert( list );
resarr[1] = gcry_sexp_nth_mpi( list, 1, 0 );
assert( resarr[1] );
gcry_sexp_release ( list );
}
gcry_sexp_release( s_ciph );
return rc;
}
/****************
* Encode FILENAME with only the symmetric cipher. Take input from
@ -101,7 +50,11 @@ pk_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
int
encode_symmetric( const char *filename )
{
return encode_simple( filename, 1 );
int compat = 1;
if ( opt.expert )
compat = 0; /* PGP knows how to handle this mode. */
return encode_simple( filename, 1, compat );
}
/****************
@ -111,19 +64,49 @@ encode_symmetric( const char *filename )
int
encode_store( const char *filename )
{
return encode_simple( filename, 0 );
return encode_simple( filename, 0, 1 );
}
static void
encode_sesskey( DEK *dek, DEK **ret_dek, byte *enckey )
{
CIPHER_HANDLE hd;
DEK *c;
byte buf[33];
assert ( dek->keylen < 32 );
c = m_alloc_clear( sizeof *c );
c->keylen = dek->keylen;
c->algo = dek->algo;
make_session_key( c );
/*log_hexdump( "thekey", c->key, c->keylen );*/
buf[0] = c->algo;
memcpy( buf + 1, c->key, c->keylen );
hd = cipher_open( dek->algo, CIPHER_MODE_CFB, 1 );
cipher_setkey( hd, dek->key, dek->keylen );
cipher_setiv( hd, NULL, 0 );
cipher_encrypt( hd, buf, buf, c->keylen + 1 );
cipher_close( hd );
memcpy( enckey, buf, c->keylen + 1 );
memset( buf, 0, sizeof buf ); /* burn key */
*ret_dek = c;
}
static int
encode_simple( const char *filename, int mode )
encode_simple( const char *filename, int mode, int compat )
{
IOBUF inp, out;
PACKET pkt;
DEK *dek = NULL;
PKT_plaintext *pt = NULL;
STRING2KEY *s2k = NULL;
byte enckey[33];
int rc = 0;
int seskeylen = 0;
u32 filesize;
cipher_filter_context_t cfx;
armor_filter_context_t afx;
@ -136,40 +119,62 @@ encode_simple( const char *filename, int mode )
memset( &zfx, 0, sizeof zfx);
memset( &tfx, 0, sizeof tfx);
init_packet(&pkt);
if (opt.compress == -1 && is_file_compressed(filename, &rc))
{
if (opt.verbose)
log_info(_("`%s' already compressed\n"), filename);
do_compress = 0;
}
if (rc)
return rc;
/* prepare iobufs */
if( !(inp = iobuf_open(filename)) ) {
log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]",
strerror(errno) );
return GPGERR_OPEN_FILE;
return G10ERR_OPEN_FILE;
}
if( opt.textmode )
iobuf_push_filter( inp, text_filter, &tfx );
/* 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 no S2K salt. RFC1991 always uses simple S2K. */
if ( opt.rfc1991 && !compat )
compat = 1;
cfx.dek = NULL;
if( mode ) {
s2k = gcry_xcalloc( 1, sizeof *s2k );
s2k = m_alloc_clear( sizeof *s2k );
s2k->mode = opt.rfc1991? 0:opt.s2k_mode;
s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo
: opt.s2k_digest_algo;
cfx.dek = passphrase_to_dek( NULL, 0,
opt.def_cipher_algo ? opt.def_cipher_algo
: opt.s2k_cipher_algo , s2k, 2 );
opt.def_cipher_algo ? opt.def_cipher_algo
: opt.s2k_cipher_algo , s2k, 2, NULL );
if( !cfx.dek || !cfx.dek->keylen ) {
rc = GPGERR_PASSPHRASE;
gcry_free(cfx.dek);
gcry_free(s2k);
rc = G10ERR_PASSPHRASE;
m_free(cfx.dek);
m_free(s2k);
iobuf_close(inp);
log_error(_("error creating passphrase: %s\n"), gpg_errstr(rc) );
log_error(_("error creating passphrase: %s\n"), g10_errstr(rc) );
return rc;
}
if ( !compat ) {
seskeylen = cipher_get_keylen( opt.def_cipher_algo ?
opt.def_cipher_algo:
opt.s2k_cipher_algo ) / 8;
encode_sesskey( cfx.dek, &dek, enckey );
m_free( cfx.dek ); cfx.dek = dek;
}
}
if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
iobuf_cancel(inp);
gcry_free(cfx.dek);
gcry_free(s2k);
m_free(cfx.dek);
m_free(s2k);
return rc;
}
@ -184,15 +189,19 @@ encode_simple( const char *filename, int mode )
}
#endif
if( s2k && !opt.rfc1991 ) {
PKT_symkey_enc *enc = gcry_xcalloc( 1, sizeof *enc );
PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc + seskeylen + 1 );
enc->version = 4;
enc->cipher_algo = cfx.dek->algo;
enc->s2k = *s2k;
if ( !compat && seskeylen ) {
enc->seskeylen = seskeylen + 1; /* algo id */
memcpy( enc->seskey, enckey, seskeylen + 1 );
}
pkt.pkttype = PKT_SYMKEY_ENC;
pkt.pkt.symkey_enc = enc;
if( (rc = build_packet( out, &pkt )) )
log_error("build symkey packet failed: %s\n", gpg_errstr(rc) );
gcry_free(enc);
log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
m_free(enc);
}
if (!opt.no_literal) {
@ -200,30 +209,36 @@ encode_simple( const char *filename, int mode )
if( filename || opt.set_filename ) {
char *s = make_basename( opt.set_filename ? opt.set_filename
: filename );
pt = gcry_xmalloc( sizeof *pt + strlen(s) - 1 );
pt = m_alloc( sizeof *pt + strlen(s) - 1 );
pt->namelen = strlen(s);
memcpy(pt->name, s, pt->namelen );
gcry_free(s);
m_free(s);
}
else { /* no filename */
pt = gcry_xmalloc( sizeof *pt - 1 );
pt = m_alloc( sizeof *pt - 1 );
pt->namelen = 0;
}
}
/* pgp5 has problems to decrypt symmetrically encrypted data from
* GnuPG if the filelength is in the inner packet. It works
* when only partial length headers are use. Until we have
* tracked this problem down. We use this temporary fix
* (fixme: remove the && !mode )
*/
if( filename && !opt.textmode && !mode ) {
/* Note that PGP 5 has problems decrypting symmetrically encrypted
data if the file length is in the inner packet. It works when
only partial length headers are use. In the past, we always
used partial body length here, but since PGP 2, PGP 6, and PGP
7 need the file length, and nobody should be using PGP 5
nowadays anyway, this is now set to the file length. Note also
that this only applies to the RFC-1991 style symmetric
messages, and not the RFC-2440 style. PGP 6 and 7 work with
either partial length or fixed length with the new style
messages. */
if( filename && !opt.textmode ) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("%s: WARNING: empty file\n"), filename );
/* we can't yet encode the length of very large files,
* so we switch to partial length encoding in this case */
* so we switch to partial lengthn encoding in this case */
if ( filesize >= IOBUF_FILELENGTH_LIMIT )
filesize = 0;
}
else
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
@ -239,7 +254,11 @@ encode_simple( const char *filename, int mode )
cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
}
else
cfx.datalen = filesize && !do_compress ? filesize : 0;
{
cfx.datalen = filesize && !do_compress ? filesize : 0;
pkt.pkttype = 0;
pkt.pkt.generic = NULL;
}
/* register the cipher filter */
if( mode )
@ -251,7 +270,7 @@ encode_simple( const char *filename, int mode )
/* do the work */
if (!opt.no_literal) {
if( (rc = build_packet( out, &pkt )) )
log_error("build_packet failed: %s\n", gpg_errstr(rc) );
log_error("build_packet failed: %s\n", g10_errstr(rc) );
}
else {
/* user requested not to create a literal packet,
@ -260,8 +279,8 @@ encode_simple( const char *filename, int mode )
int bytes_copied;
while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
rc = GPGERR_WRITE_FILE;
log_error("copying input to output failed: %s\n", gpg_errstr(rc) );
rc = G10ERR_WRITE_FILE;
log_error("copying input to output failed: %s\n", g10_errstr(rc) );
break;
}
memset(copy_buffer, 0, 4096); /* burn buffer */
@ -271,13 +290,16 @@ encode_simple( const char *filename, int mode )
iobuf_close(inp);
if (rc)
iobuf_cancel(out);
else
else {
iobuf_close(out); /* fixme: check returncode */
if (mode)
write_status( STATUS_END_ENCRYPTION );
}
if (pt)
pt->buf = NULL;
free_packet(&pkt);
gcry_free(cfx.dek);
gcry_free(s2k);
m_free(cfx.dek);
m_free(s2k);
return rc;
}
@ -291,123 +313,203 @@ encode_crypt( const char *filename, STRLIST remusr )
IOBUF inp = NULL, out = NULL;
PACKET pkt;
PKT_plaintext *pt = NULL;
int rc = 0;
int rc = 0, rc2 = 0;
u32 filesize;
cipher_filter_context_t cfx;
armor_filter_context_t afx;
compress_filter_context_t zfx;
text_filter_context_t tfx;
encrypt_filter_context_t efx;
PK_LIST pk_list;
PK_LIST pk_list,work_list;
int do_compress = opt.compress && !opt.rfc1991;
memset( &cfx, 0, sizeof cfx);
memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx);
memset( &tfx, 0, sizeof tfx);
memset( &efx, 0, sizeof efx);
init_packet(&pkt);
if( (rc=build_pk_list( remusr, &pk_list, GCRY_PK_USAGE_ENCR)) )
if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
return rc;
if(opt.pgp2) {
for(work_list=pk_list; work_list; work_list=work_list->next)
if(!(is_RSA(work_list->pk->pubkey_algo) &&
nbits_from_pk(work_list->pk)<=2048))
{
log_info(_("you can only encrypt to RSA keys of 2048 bits or "
"less in --pgp2 mode\n"));
log_info(_("this message may not be usable by PGP 2.x\n"));
opt.pgp2=0;
break;
}
}
if (opt.compress == -1 && is_file_compressed(filename, &rc2))
{
if (opt.verbose)
log_info(_("`%s' already compressed\n"), filename);
do_compress = 0;
}
if (rc2)
{
rc = rc2;
goto leave;
}
/* prepare iobufs */
if( !(inp = iobuf_open(filename)) ) {
log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
strerror(errno) );
rc = GPGERR_OPEN_FILE;
rc = G10ERR_OPEN_FILE;
goto leave;
}
else if( opt.verbose )
log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
/* If the user selected textmode, push the text filter onto the input */
if( opt.textmode )
iobuf_push_filter( inp, text_filter, &tfx );
/* Now we can create the outputfile */
if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
goto leave;
/* The first thing we have to push on the output stream
* is the armor filter */
if( opt.armor )
iobuf_push_filter( out, armor_filter, &afx );
#ifdef ENABLE_COMMENT_PACKETS
else {
write_comment( out, "#created by GNUPG v" VERSION " ("
PRINTABLE_OS_NAME ")");
if( opt.comment_string )
write_comment( out, opt.comment_string );
}
#endif
/* create a session key */
cfx.dek = m_alloc_secure_clear (sizeof *cfx.dek);
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
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
mixing v3 and v4 keys, as v4 keys have an implicit
preference entry for 3DES, and the pk_list cannot be empty.
In this case, use 3DES anyway as it's the safest choice -
perhaps the v3 key is being used in an OpenPGP
implementation and we know that the implementation behind
any v4 key can handle 3DES. */
if( cfx.dek->algo == -1 ) {
cfx.dek->algo = CIPHER_ALGO_3DES;
/* Prepare the plaintext packet */
{
if (!opt.no_literal) {
if( filename || opt.set_filename ) {
char *s = make_basename( opt.set_filename ?
opt.set_filename : filename );
pt = gcry_xmalloc( sizeof *pt + strlen(s) - 1 );
pt->namelen = strlen(s);
memcpy(pt->name, s, pt->namelen );
gcry_free(s);
}
else { /* no filename */
pt = gcry_xmalloc( sizeof *pt - 1 );
pt->namelen = 0;
}
}
if( filename && !opt.textmode ) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("%s: WARNING: empty file\n"), filename );
/* we can't yet encode the length of very large files,
* so we switch to partial lengthn encoding in this case */
if ( filesize >= IOBUF_FILELENGTH_LIMIT )
filesize = 0;
}
else
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
if (!opt.no_literal) {
pt->timestamp = make_timestamp();
pt->mode = opt.textmode ? 't' : 'b';
pt->len = filesize;
pt->new_ctb = !pt->len && !opt.rfc1991;
pt->buf = inp;
pkt.pkttype = PKT_PLAINTEXT;
pkt.pkt.plaintext = pt;
efx.cfx.datalen = filesize && !do_compress?
calc_packet_length( &pkt ) : 0;
}
else
efx.cfx.datalen = filesize && !do_compress ? filesize : 0;
} /* end preparation of plaintext packet */
/* push in the actual encryption filter */
efx.pk_list = pk_list;
iobuf_push_filter( out, encrypt_filter, &efx );
/* register the compress filter (so that it is done before encryption) */
if( do_compress ) {
int compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR );
if( !compr_algo )
; /* don't use compression */
else {
if( compr_algo == 1 )
zfx.algo = 1; /* default is 2 */
iobuf_push_filter( out, compress_filter, &zfx );
if( opt.pgp2 ) {
log_info(_("unable to use the IDEA cipher for all of the keys "
"you are encrypting to.\n"));
log_info(_("this message may not be usable by PGP 2.x\n"));
opt.pgp2=0;
}
}
}
else {
if(!opt.expert &&
select_algo_from_prefs(pk_list,PREFTYPE_SYM,
opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
log_info(_("forcing symmetric cipher %s (%d) "
"violates recipient preferences\n"),
cipher_algo_to_string(opt.def_cipher_algo),
opt.def_cipher_algo);
cfx.dek->algo = opt.def_cipher_algo;
}
cfx.dek->use_mdc = select_mdc_from_pklist (pk_list);
make_session_key( cfx.dek );
if( DBG_CIPHER )
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
if( rc )
goto leave;
if (!opt.no_literal) {
/* setup the inner packet */
if( filename || opt.set_filename ) {
char *s = make_basename( opt.set_filename ? opt.set_filename : filename );
pt = m_alloc( sizeof *pt + strlen(s) - 1 );
pt->namelen = strlen(s);
memcpy(pt->name, s, pt->namelen );
m_free(s);
}
else { /* no filename */
pt = m_alloc( sizeof *pt - 1 );
pt->namelen = 0;
}
}
if( filename && !opt.textmode ) {
if( !(filesize = iobuf_get_filelength(inp)) )
log_info(_("%s: WARNING: empty file\n"), filename );
/* we can't yet encode the length of very large files,
* so we switch to partial length encoding in this case */
if ( filesize >= IOBUF_FILELENGTH_LIMIT )
filesize = 0;
}
else
filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
if (!opt.no_literal) {
pt->timestamp = make_timestamp();
pt->mode = opt.textmode ? 't' : 'b';
pt->len = filesize;
pt->new_ctb = !pt->len && !opt.rfc1991;
pt->buf = inp;
pkt.pkttype = PKT_PLAINTEXT;
pkt.pkt.plaintext = pt;
cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
}
else
cfx.datalen = filesize && !do_compress ? filesize : 0;
/* register the cipher filter */
iobuf_push_filter( out, cipher_filter, &cfx );
/* register the compress filter */
if( do_compress ) {
int compr_algo = opt.def_compress_algo;
if(compr_algo==-1)
{
if((compr_algo=
select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
compr_algo=DEFAULT_COMPRESS_ALGO;
}
else if(!opt.expert &&
select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
compr_algo,NULL)!=compr_algo)
log_info(_("forcing compression algorithm %s (%d) "
"violates recipient preferences\n"),
compress_algo_to_string(compr_algo),compr_algo);
/* algo 0 means no compression */
if( compr_algo )
{
zfx.algo = compr_algo;
iobuf_push_filter( out, compress_filter, &zfx );
}
}
/* do the work */
if (!opt.no_literal) {
if( (rc = build_packet( out, &pkt )) )
log_error("build_packet failed: %s\n", gpg_errstr(rc) );
log_error("build_packet failed: %s\n", g10_errstr(rc) );
}
else {
/* user requested not to create a literal packet,
* so we copy the plain data */
/* user requested not to create a literal packet, so we copy the plain data */
byte copy_buffer[4096];
int bytes_copied;
while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
rc = GPGERR_WRITE_FILE;
log_error("copying input to output failed: %s\n", gpg_errstr(rc) );
rc = G10ERR_WRITE_FILE;
log_error("copying input to output failed: %s\n", g10_errstr(rc) );
break;
}
memset(copy_buffer, 0, DIM(copy_buffer)); /* burn buffer */
memset(copy_buffer, 0, 4096); /* burn buffer */
}
/* finish the stuff */
@ -415,13 +517,14 @@ encode_crypt( const char *filename, STRLIST remusr )
iobuf_close(inp);
if( rc )
iobuf_cancel(out);
else
else {
iobuf_close(out); /* fixme: check returncode */
write_status( STATUS_END_ENCRYPTION );
}
if( pt )
pt->buf = NULL;
free_packet(&pkt);
gcry_free(efx.cfx.dek); /* Hmmm, why does the encrypt filter does not
* take care about this? */
m_free(cfx.dek);
release_pk_list( pk_list );
return rc;
}
@ -430,7 +533,7 @@ encode_crypt( const char *filename, STRLIST remusr )
/****************
* Filter to handle the entire public key encryption.
* Filter to do a complete public key encryption.
*/
int
encrypt_filter( void *opaque, int control,
@ -445,16 +548,32 @@ encrypt_filter( void *opaque, int control,
}
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
if( !efx->header_okay ) {
efx->cfx.dek = gcry_xmalloc_secure( sizeof *efx->cfx.dek );
efx->cfx.dek = m_alloc_secure_clear( sizeof *efx->cfx.dek );
if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
efx->cfx.dek->algo =
select_algo_from_prefs( efx->pk_list, PREFTYPE_SYM );
if( efx->cfx.dek->algo == -1 )
select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL);
if( efx->cfx.dek->algo == -1 ) {
/* because 3DES is implicitly in the prefs, this can only
* happen if we do not have any public keys in the list */
efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
}
}
else
efx->cfx.dek->algo = opt.def_cipher_algo;
else {
if(!opt.expert &&
select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,
opt.def_cipher_algo,
NULL)!=opt.def_cipher_algo)
log_info(_("forcing symmetric cipher %s (%d) "
"violates recipient preferences\n"),
cipher_algo_to_string(opt.def_cipher_algo),
opt.def_cipher_algo);
efx->cfx.dek->algo = opt.def_cipher_algo;
}
efx->cfx.dek->use_mdc = select_mdc_from_pklist (efx->pk_list);
make_session_key( efx->cfx.dek );
if( DBG_CIPHER )
log_hexdump("DEK is: ",
@ -497,7 +616,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
pk = pk_list->pk;
print_pubkey_algo_note( pk->pubkey_algo );
enc = gcry_xcalloc( 1, sizeof *enc );
enc = m_alloc_clear( sizeof *enc );
enc->pubkey_algo = pk->pubkey_algo;
keyid_from_pk( pk, enc->keyid );
enc->throw_keyid = opt.throw_keyid;
@ -517,17 +636,17 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
*/
frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo,
pk->pkey ) );
rc = pk_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
mpi_release( frame );
rc = pubkey_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
mpi_free( frame );
if( rc )
log_error("pubkey_encrypt failed: %s\n", gpg_errstr(rc) );
log_error("pubkey_encrypt failed: %s\n", g10_errstr(rc) );
else {
if( opt.verbose ) {
char *ustr = get_user_id_string_native( enc->keyid );
log_info(_("%s/%s encrypted for: %s\n"),
gcry_pk_algo_name(enc->pubkey_algo),
gcry_cipher_algo_name(dek->algo), ustr );
gcry_free(ustr);
pubkey_algo_to_string(enc->pubkey_algo),
cipher_algo_to_string(dek->algo), ustr );
m_free(ustr);
}
/* and write it */
init_packet(&pkt);
@ -535,7 +654,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
pkt.pkt.pubkey_enc = enc;
rc = build_packet( out, &pkt );
if( rc )
log_error("build_packet(pubkey_enc) failed: %s\n", gpg_errstr(rc));
log_error("build_packet(pubkey_enc) failed: %s\n", g10_errstr(rc));
}
free_pubkey_enc(enc);
if( rc )
@ -544,3 +663,47 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
return 0;
}
void
encode_crypt_files(int nfiles, char **files, STRLIST remusr)
{
int rc = 0;
if (opt.outfile)
{
log_error(_("--output doesn't work for this command\n"));
return;
}
if (!nfiles)
{
char line[2048];
unsigned int lno = 0;
while ( fgets(line, DIM(line), stdin) )
{
lno++;
if (!*line || line[strlen(line)-1] != '\n')
{
log_error("input line %u too long or missing LF\n", lno);
return;
}
line[strlen(line)-1] = '\0';
print_file_status(STATUS_FILE_START, line, 2);
if ( (rc = encode_crypt(line, remusr)) )
log_error("%s: encryption failed: %s\n",
print_fname_stdin(line), g10_errstr(rc) );
write_status( STATUS_FILE_DONE );
}
}
else
{
while (nfiles--)
{
print_file_status(STATUS_FILE_START, *files, 2);
if ( (rc = encode_crypt(*files, remusr)) )
log_error("%s: encryption failed: %s\n",
print_fname_stdin(*files), g10_errstr(rc) );
write_status( STATUS_FILE_DONE );
files++;
}
}
}