See ChangeLog: Wed Oct 4 13:16:18 CEST 2000 Werner Koch

This commit is contained in:
Werner Koch 2000-10-04 11:16:19 +00:00
parent 986d928ce2
commit 9c20f65cbe
29 changed files with 629 additions and 335 deletions

2
NEWS
View File

@ -3,6 +3,8 @@ Noteworthy changes in the current CVS HEAD
THIS IS A DEVELOPMENT VERSION; see README-alpha
* Add Rijndael (AES) support.
* Fixed problems with piping to/from other MS-Windows software
* Expiration time of the primary key can be changed again.

7
TODO
View File

@ -7,11 +7,6 @@
* Use --output for keylistings too.
* Add to the (EGD) docs that ~/.gnupg/entropy should be a symlink to the
real socket.
* Add a way to generate keys in batch mode with arbitrary parameters.
* Never allocate packet memory with a m-alloc, but use a specific function.
* Should we change names like mpi_write in g10/ so that we don't
@ -28,8 +23,6 @@
* Speed up calculation of key validation.
* print a warning when a revoked/expired _secret_ key is used.
* --disable-asm should still assemble _udiv_qrnnd when needed
* Skip RO keyrings when importing a key.

View File

@ -1,3 +1,7 @@
Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
* run-gpg: redirect fgrep output to stderr
Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
* genkey1024.test: Does not use --quick-random anymore.

View File

@ -1,6 +1,6 @@
#!/bin/sh
[ -n "$show_cmds" ] && echo "../g10/gpg --homedir . $*"
[ -n "$show_cmds" ] && echo "../g10/gpg --homedir . $*" >&2
if ../g10/gpg --homedir . $* 2>err.tmp.$$ ; then
:
@ -10,6 +10,6 @@ else
rm err.tmp.$$
exit 1
fi
fgrep -v -f $srcdir/run-gpg.patterns err.tmp.$$
fgrep -v -f $srcdir/run-gpg.patterns err.tmp.$$ >&2
rm err.tmp.$$

View File

@ -9,3 +9,6 @@ gpg: NOTE: secret key 439F02CA is NOT protected.
gpg: WARNING: using insecure random number generator
gpg: NOTE: signature key expired
NOTE: this is a development version!
secret key without public key - skipped
gpg: using secondary key CB879DE9 instead of primary key 439F02CA

View File

@ -1,3 +1,17 @@
Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
* sha1.c (transform): Use rol() macro. Actually this is not needed
for a newer gcc but there are still aoter compilers.
* rsa.c (test_keys): Use new random function.
* md.c (gcry_md_setkey): New function to overcome problems with
const conflics.
(gcry_md_ctl): Pass set key to the new functions.
* rijndael.c: New.
* cipher.c: Add Rijndael support.
Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
* rndlinux.c (open_device): Loose random device checking.

View File

@ -36,6 +36,7 @@ libcipher_la_SOURCES = cipher.c \
bithelp.h \
des.c \
des.h \
rijndael.c \
twofish.c \
blowfish.c \
blowfish.h \

View File

@ -33,7 +33,7 @@
#include "dynload.h"
#define MAX_BLOCKSIZE 16
#define TABLE_SIZE 10
#define TABLE_SIZE 12
#define CTX_MAGIC_NORMAL 0x24091964
#define CTX_MAGIC_SECURE 0x46919042
@ -82,11 +82,43 @@ dummy_decrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); }
static void
setup_cipher_table(void)
{
int i;
i = 0;
cipher_table[i].algo = CIPHER_ALGO_TWOFISH;
cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL;
cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
&cipher_table[i].keylen,
&cipher_table[i].blocksize,
&cipher_table[i].contextsize,
&cipher_table[i].setkey,
&cipher_table[i].encrypt,
&cipher_table[i].decrypt );
if( !cipher_table[i].name )
BUG();
i++;
cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL192;
cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
&cipher_table[i].keylen,
&cipher_table[i].blocksize,
&cipher_table[i].contextsize,
&cipher_table[i].setkey,
&cipher_table[i].encrypt,
&cipher_table[i].decrypt );
if( !cipher_table[i].name )
BUG();
i++;
cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL256;
cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
&cipher_table[i].keylen,
&cipher_table[i].blocksize,
&cipher_table[i].contextsize,
&cipher_table[i].setkey,
&cipher_table[i].encrypt,
&cipher_table[i].decrypt );
if( !cipher_table[i].name )
BUG();
i++;
cipher_table[i].algo = GCRY_CIPHER_TWOFISH;
cipher_table[i].name = twofish_get_info( cipher_table[i].algo,
&cipher_table[i].keylen,
&cipher_table[i].blocksize,
@ -97,7 +129,7 @@ setup_cipher_table(void)
if( !cipher_table[i].name )
BUG();
i++;
cipher_table[i].algo = CIPHER_ALGO_BLOWFISH;
cipher_table[i].algo = GCRY_CIPHER_BLOWFISH;
cipher_table[i].name = blowfish_get_info( cipher_table[i].algo,
&cipher_table[i].keylen,
&cipher_table[i].blocksize,
@ -108,7 +140,7 @@ setup_cipher_table(void)
if( !cipher_table[i].name )
BUG();
i++;
cipher_table[i].algo = CIPHER_ALGO_CAST5;
cipher_table[i].algo = GCRY_CIPHER_CAST5;
cipher_table[i].name = cast5_get_info( cipher_table[i].algo,
&cipher_table[i].keylen,
&cipher_table[i].blocksize,
@ -119,7 +151,7 @@ setup_cipher_table(void)
if( !cipher_table[i].name )
BUG();
i++;
cipher_table[i].algo = CIPHER_ALGO_3DES;
cipher_table[i].algo = GCRY_CIPHER_3DES;
cipher_table[i].name = des_get_info( cipher_table[i].algo,
&cipher_table[i].keylen,
&cipher_table[i].blocksize,
@ -455,7 +487,7 @@ do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo
unsigned n;
for(n=0; n < nblocks; n++ ) {
(*c->encrypt)( &c->context.c, outbuf, inbuf );
(*c->encrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
inbuf += c->blocksize;
outbuf += c->blocksize;
}
@ -467,7 +499,7 @@ do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo
unsigned n;
for(n=0; n < nblocks; n++ ) {
(*c->decrypt)( &c->context.c, outbuf, inbuf );
(*c->decrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
inbuf += c->blocksize;
outbuf += c->blocksize;
}
@ -507,7 +539,7 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo
* to save the original ciphertext block. We use lastiv
* for this here because it is not used otherwise */
memcpy(c->lastiv, inbuf, blocksize );
(*c->decrypt)( &c->context.c, outbuf, inbuf );
(*c->decrypt)( &c->context.c, outbuf, (char*)/*argggg*/inbuf );
for(ivp=c->iv,i=0; i < blocksize; i++ )
outbuf[i] ^= *ivp++;
memcpy(c->iv, c->lastiv, blocksize );

View File

@ -557,10 +557,7 @@ gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen)
if( cmd == GCRYCTL_FINALIZE )
md_final( hd );
else if( cmd == GCRYCTL_SET_KEY ) {
if( !(hd->ctx->macpads ) )
rc = GCRYERR_CONFLICT;
else if ( !(rc = prepare_macpads( hd, buffer, buflen )) )
gcry_md_reset( hd );
rc = gcry_md_setkey ( hd, buffer, buflen );
}
else if( cmd == GCRYCTL_START_DUMP ) {
md_start_debug( hd, buffer );
@ -574,6 +571,20 @@ gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen)
}
int
gcry_md_setkey( GCRY_MD_HD hd, const char *key, size_t keylen )
{
int rc = 0;
if( !(hd->ctx->macpads ) )
rc = GCRYERR_CONFLICT;
else if ( !(rc = prepare_macpads( hd, key, keylen )) )
gcry_md_reset( hd );
return rc;
}
/****************
* if ALGO is null get the digest for the used algo (which should be only one)
*/

View File

@ -27,6 +27,8 @@ void random_dump_stats(void);
void secure_random_alloc(void);
int quick_random_gen( int onoff );
int random_is_faked(void);
void secure_random_alloc(void);
void random_dump_stats(void);
byte *get_random_bits( size_t nbits, int level, int secure );
void fast_random_poll( void );

View File

@ -67,10 +67,7 @@ test_keys( RSA_secret_key *sk, unsigned nbits )
pk.n = sk->n;
pk.e = sk->e;
{ char *p = get_random_bits( nbits, 0, 0 );
mpi_set_buffer( test, p, (nbits+7)/8, 0 );
g10_free(p);
}
gcry_mpi_randomize( test, nbits, GCRY_WEAK_RANDOM );
public( out1, test, &pk );
secret( out2, out1, sk );

View File

@ -108,7 +108,7 @@ transform( SHA1_CONTEXT *hd, byte *data )
#define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] \
^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \
, (x[i&0x0f] = (tm << 1) | (tm >> 31)) )
, (x[i&0x0f] = rol(tm, 1)) )
#define R(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) \
+ f( b, c, d ) \

View File

@ -68,7 +68,8 @@
specified. It is possible to use these functions as MAC functons; therefore
the flag <literal/GCRY_MD_FLAG_HMAC/ must be given along with the
hash functions. Other MAC algorithms than HMAC are currently not
supported. The key for the MAC must be set using the gcry_md_setkey macro.
supported. The key for the MAC must be set using
the <function>gcry_md_setkey</> function.
<function>gcry_md_close</function> releases all resources associated
with the context.
<function>gcry_md_enable</function> may be used to enable hash
@ -194,6 +195,7 @@
hash functions into MAC functions. The key may be any string
of the speicified length. The type of the MAC is determined
by special flags set with the open function.
NEW: There is now a function to do this
</para>
</refentry>
@ -479,3 +481,6 @@
</para>
</refentry>
<!-- FIXME: doc gcry_md_setkey */

View File

@ -18,28 +18,238 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-->
<!--
const char *gcry_check_version( const char *req_version );
<refentry>
<refnamediv>
<refname>gcry_check_version</refname>
<refpurpose>get or check the version of libgcrypt</refpurpose>
</refnamediv>
int gcry_errno(void);
const char *gcry_strerror( int ec );
int gcry_control( enum gcry_ctl_cmds, ... );
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>
#include &lt;gcrypt.h&gt;
</funcsynopsisinfo>
<funcprototype>
<funcdef>const char *<function>gcry_check_version</function></funcdef>
<paramdef>const char *<parameter>req_version</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<indexterm><primary>gcry_check_version</primary>
</indexterm>
<function>gcry_check_version</function> checks
that the version of the library is at minimum the requested one
and return the version string; NULL is returned if the condition is
not met. You may pass NULL as reqy_version to simply get the version
string back without any checking.
</para>
</refentry>
<refentry>
<refnamediv>
<refname>gcry_errno</refname>
<refname>gcry_strerror</refname>
<refpurpose>Get the last error</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>
#include &lt;gcrypt.h&gt;
</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>gcry_errno</function></funcdef>
</funcprototype>
<funcprototype>
<funcdef>const char *<function>gcry_strerror</function></funcdef>
<paramdef>int<parameter>no</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<indexterm><primary>gcry_errno</primary></indexterm>
<indexterm><primary>gcry_strerror</primary></indexterm>
Both function are to be used like there Standard-C
counterparts. However <function>gcry_errno</function> is a function
and not just a global variable. If -1 is passed to
<function>gcry_strerror</>, <function>gcry_errno</> is implictly used.
</para>
</refentry>
<refentry>
<refnamediv>
<refname>gcry_control</refname>
<refpurpose>Multi purpose control function</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>
#include &lt;gcrypt.h&gt;
</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>gcry_control</function></funcdef>
<paramdef>enum gcry_ctl_cmds<parameter>cmd</parameter></paramdef>
<paramdef><parameter>...</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<indexterm><primary>gcry_control</primary></indexterm>
This function is used to control various aspects of &libgcrypt;
FIXME: Explain all commands here.
</para>
</refentry>
<refentry>
<refnamediv>
<refname>gcry_set_allocation_handler</refname>
<refname>gcry_set_outofcore_handler</refname>
<refpurpose>Use application defined malloc functions</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>
#include &lt;gcrypt.h&gt;
</funcsynopsisinfo>
<funcprototype>
<funcdef>void <function>gcry_set_allocation_handler</></funcdef>
<paramdef>void *(*<parameter>alloc_func</>)(size_t n)</paramdef>
<paramdef>void *(*<parameter>alloc_secure_func</>)(size_t n)</paramdef>
<paramdef>int (*<parameter>is_secure_func</>)(const void *p)</paramdef>
<paramdef>void *(*<parameter>realloc_func</>)(void *p, size_t n)</paramdef>
<paramdef>void (*<parameter>free_func</>)(void *p)</paramdef>
</funcprototype>
<funcprototype>
<funcdef>void <function>gcry_set_outofcore_handler</></funcdef>
<paramdef>int (*<parameter>h</>)( void*, size_t, unsigned int ),
void *opaque )</paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<indexterm><primary>gcry_set_allocation_handler</primary></indexterm>
<indexterm><primary>gcry_set_outofcore_handler</primary></indexterm>
FIXME
</para>
</refentry>
<refentry>
<refnamediv>
<refname>gcry_set_fatalerror_handler</refname>
<refpurpose>change the default fatal error handler</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>
#include &lt;gcrypt.h&gt;
</funcsynopsisinfo>
<funcprototype>
<funcdef>void <function>gcry_set_fatalerror_handler</></funcdef>
<paramdef>void (*<parameter>func</>)(
void *, int, const char*)</paramdef>
<paramdef>void *<parameter>opaque</></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<indexterm><primary>gcry_set_fatalerror_handler</primary></indexterm>
At certain places the &libgcrypt; may need to call a fatal error fucntion
which does terminate the process. To allow an application to do
some emergency cleanup, it may register a fatal error handler with
the library. This handler is assumed to terminate the application;
however if it returns &libgcrypt; will abort anyway.
</para>
<para>
The handler is called with the opaque value registered here, an
errorcode from &libgcrypt; and some descriptive text string.
</para>
</refentry>
<refentry>
<refnamediv>
<refname>gcry_set_gettext_handler</refname>
<refpurpose>Change the default gettext function</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>
#include &lt;gcrypt.h&gt;
</funcsynopsisinfo>
<funcprototype>
<funcdef>void <function>gcry_set_gettext_handler</></funcdef>
<paramdef>const char *(*<parameter>func</>)(const char*)</paramdef>
<paramdef>void *<parameter>opaque</></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<indexterm><primary>gcry_set_log_handler</primary></indexterm>
FIXME!!
</para>
</refentry>
void gcry_set_allocation_handler( void *(*new_alloc_func)(size_t n),
void *(*new_alloc_secure_func)(size_t n),
int (*new_is_secure_func)(const void*),
void *(*new_realloc_func)(void *p, size_t n),
void (*new_free_func)(void*) );
void gcry_set_outofcore_handler( int (*h)( void*, size_t, unsigned int ),
void *opaque );
void gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*),
void *opaque );
void gcry_set_gettext_handler( const char *(*f)(const char*) );
void gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ),
void *opaque );
<refentry>
<refnamediv>
<refname>gcry_set_log_handler</refname>
<refpurpose>Change the default logging function</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>
#include &lt;gcrypt.h&gt;
</funcsynopsisinfo>
<funcprototype>
<funcdef>void <function>gcry_set_log_handler</></funcdef>
<paramdef>void (*<parameter>func</>)
(void*, int, const char*, va_list)</paramdef>
<paramdef>void *<parameter>opaque</></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<indexterm><primary>gcry_set_log_handler</primary></indexterm>
&libgcrypt; has it;s own logging functions. Applications which
need to use their own, should provide a log function to &libgcrypt;
so that it will use this function instead.
Fixme: Describe how this is intended to work.
</para>
</refentry>
void *gcry_malloc( size_t n );
void *gcry_calloc( size_t n, size_t m );
@ -55,6 +265,53 @@ char *gcry_xstrdup( const char * a);
void gcry_free( void *a );
int gcry_is_secure( const void *a );
<refentry>
<refnamediv>
<refname>gcry_malloc</refname>
<refname>gcry_calloc</refname>
<refname>gcry_malloc_secure</refname>
<refname>gcry_calloc_secure</refname>
<refname>gcry_realloc</refname>
<refname>gcry_xmalloc</refname>
<refname>gcry_xcalloc</refname>
<refname>gcry_xmalloc_secure</refname>
<refname>gcry_xcalloc_secure</refname>
<refname>gcry_xrealloc</refname>
<refname>gcry_xstrdup</refname>
WORk WORK
<refname>gcry_malloc</refname>
<refname>gcry_malloc</refname>
<refpurpose>Change the default logging function</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>
#include &lt;gcrypt.h&gt;
</funcsynopsisinfo>
<funcprototype>
<funcdef>void <function>gcry_set_log_handler</></funcdef>
<paramdef>void (*<parameter>func</>)
(void*, int, const char*, va_list)</paramdef>
<paramdef>void *<parameter>opaque</></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<indexterm><primary>gcry_set_log_handler</primary></indexterm>
&libgcrypt; has it;s own logging functions. Applications which
need to use their own, should provide a log function to &libgcrypt;
so that it will use this function instead.
Fixme: Describe how this is intended to work.
</para>
</refentry>
void gcry_randomize( byte *buffer, size_t length,
enum gcry_random_level level );
@ -65,3 +322,5 @@ void *gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level );
-->

View File

@ -1,3 +1,18 @@
Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
* getkey.c (merge_selfsigs_main): Fixed for v3 keys.
* sign.c (hash_for): New arg to take packet version in account. Changed
all callers.
(write_one_sig): New. Moved the shared code from sign_file and
clearsign_file to here.
* skclist.c (build_sk_list): Fixed usage check.
* pkclist.c (build_pk_list): Ditto.
* encode.c (encode_crypt): Removed duplicated stuff by using
encrypt_filter as sign.c already did. Removed already disabled
comment-packet code.
Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
* parse-packet.c (dump_sig_subpkt): Dump key flags.

View File

@ -293,18 +293,17 @@ encode_crypt( const char *filename, STRLIST remusr )
PKT_plaintext *pt = NULL;
int rc = 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;
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)) )
@ -320,83 +319,67 @@ encode_crypt( const char *filename, STRLIST remusr )
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 = gcry_xmalloc_secure( 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 );
if( cfx.dek->algo == -1 )
cfx.dek->algo = DEFAULT_CIPHER_ALGO;
}
else
cfx.dek->algo = opt.def_cipher_algo;
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;
/* 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 );
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 = 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;
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 */
/* 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 )
@ -414,7 +397,8 @@ encode_crypt( const char *filename, STRLIST remusr )
log_error("build_packet failed: %s\n", gpg_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)
@ -423,7 +407,7 @@ encode_crypt( const char *filename, STRLIST remusr )
log_error("copying input to output failed: %s\n", gpg_errstr(rc) );
break;
}
memset(copy_buffer, 0, 4096); /* burn buffer */
memset(copy_buffer, 0, DIM(copy_buffer)); /* burn buffer */
}
/* finish the stuff */
@ -436,7 +420,8 @@ encode_crypt( const char *filename, STRLIST remusr )
if( pt )
pt->buf = NULL;
free_packet(&pkt);
gcry_free(cfx.dek);
gcry_free(efx.cfx.dek); /* Hmmm, why does the encrypt filter does not
* take care about this? */
release_pk_list( pk_list );
return rc;
}
@ -445,7 +430,7 @@ encode_crypt( const char *filename, STRLIST remusr )
/****************
* Filter to do a complete public key encryption.
* Filter to handle the entire public key encryption.
*/
int
encrypt_filter( void *opaque, int control,

View File

@ -162,7 +162,7 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
log_error(_("certificate read problem: %s\n"), gpg_errstr(rc));
goto leave;
}
/* do not export keys which are incompatible with rfc2440 */
if( onlyrfc && (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) {

View File

@ -795,12 +795,19 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
ctx->nitems = n;
for(n=0, r=namelist; r; r = r->next, n++ ) {
ctx->items[n].mode = classify_user_id( r->d,
ctx->items[n].keyid,
ctx->items[n].fprint,
&ctx->items[n].name,
NULL );
if( !ctx->items[n].mode ) {
int mode = classify_user_id( r->d,
ctx->items[n].keyid,
ctx->items[n].fprint,
&ctx->items[n].name,
NULL );
/* if we don't use one of the exact key specifications, we assume that
* the primary key is requested */
if ( mode != 10 && mode != 11 && mode != 16 && mode == 20 )
ctx->primary = 1;
ctx->items[n].mode = mode;
if( !ctx->items[n].mode ) {
gcry_free( ctx );
return GPGERR_INV_USER_ID;
}
@ -810,8 +817,7 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
}
}
/* and call the lookup function */
ctx->primary = 1; /* we want to look for the primary key only */
if ( !ret_kb )
ret_kb = &help_kb;
@ -1337,8 +1343,13 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
pk->main_keyid[0] = kid[0];
pk->main_keyid[1] = kid[1];
if ( pk->version < 4 )
return; /* nothing to do for old keys FIXME: This is wrong!!!!*/
if ( pk->version < 4 ) {
/* before v4 the key packet itself contains the expiration date
* and there was noway to change it. So we also use only the
* one from the key packet */
key_expire = pk->expiredate;
key_expire_seen = 1;
}
/* first pass: find the latest direct key self-signature.
* We assume that the newest one overrides all others
@ -1394,12 +1405,14 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
key_usage |= GCRY_PK_USAGE_ENCR;
}
p = parse_sig_subpkt ( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL);
if ( p ) {
key_expire = sig->timestamp + buffer_to_u32(p);
key_expire_seen = 1;
if ( pk->version > 3 ) {
p = parse_sig_subpkt ( sig->hashed_data,
SIGSUBPKT_KEY_EXPIRE, NULL);
if ( p ) {
key_expire = sig->timestamp + buffer_to_u32(p);
key_expire_seen = 1;
}
}
/* and set the created field */
pk->created = sigdate;
/* and mark that key as valid: one direct key signature should
@ -1518,8 +1531,8 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
}
}
}
if ( key_expire >= curtime )
pk->has_expired = key_expire;
pk->has_expired = key_expire >= curtime? 0 : key_expire;
/* FIXME: we should see how to get rid of the expiretime fields */
@ -1651,7 +1664,7 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
key_expire = sig->timestamp + buffer_to_u32(p);
else
key_expire = 0;
subpk->has_expired = key_expire >= curtime? key_expire : 0;
subpk->has_expired = key_expire >= curtime? 0 : key_expire;
}
@ -1711,7 +1724,7 @@ merge_selfsigs( KBNODE keyblock )
* keys at all and have a way to store just the real secret parts
* from the key.
*/
static void
void
merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
{
KBNODE pub;
@ -1942,8 +1955,8 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk )
}
if (DBG_CACHE)
log_debug( "\tconsidering key created %lu\n",
(ulong)pk->created);
log_debug( "\tconsidering key %08lX\n",
(ulong)keyid_from_pk( pk, NULL));
if ( pk->created > latest_date ) {
latest_date = pk->created;
latest_key = k;
@ -1989,7 +2002,8 @@ finish_lookup( GETKEY_CTX ctx, KBNODE foundk )
}
if (DBG_CACHE)
log_debug( "\tusing key created %lu\n", (ulong)latest_date );
log_debug( "\tusing key %08lX\n",
(ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL) );
ctx->found_key = latest_key;

View File

@ -509,6 +509,10 @@ static void
register_extension( const char *mainpgm, const char *fname )
{
#warning fixme add register cipher extension
/* Before we do so, we should design a beter API for this.
* I am currently thinking about using S-Exp to pass everything we
* need from the module to gcrypt. I hope we are not going to
* implement my-own-lisp-library-no-17000 */
#if 0
if( *fname != '/' ) { /* do tilde expansion etc */
char *tmp;

View File

@ -166,6 +166,7 @@ int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock );
void get_seckey_end( GETKEY_CTX ctx );
int enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys );
void merge_keys_and_selfsig( KBNODE keyblock );
void merge_public_with_secret ( KBNODE pubblock, KBNODE secblock );
char*get_user_id_string( u32 *keyid );
char*get_user_id_string_native( u32 *keyid );
char*get_long_user_id_string( u32 *keyid );

View File

@ -294,7 +294,6 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
{
int rc;
int i;
PACKET *pkt;
PKT_secret_key *sk;
PKT_public_key *pk;
@ -407,7 +406,6 @@ gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
{
int rc;
int i;
PACKET *pkt;
PKT_secret_key *sk;
PKT_public_key *pk;
@ -948,7 +946,6 @@ ask_user_id( int mode )
/* append a warning if we do not have dev/random
* or it is switched into quick testmode */
#warning quick_random_gen() not available
#if 0
if( quick_random_gen(-1) )
strcpy(p, " (INSECURE!)" );

View File

@ -454,7 +454,7 @@ fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
int rc;
size_t nbytes;
#warning Why is the hash sequence for secret keys different
/* FIXME: Why is the hash sequence for secret keys different */
rc = gcry_mpi_print( GCRYMPI_FMT_USG, NULL, &nbytes, sk->skey[1] );
assert( !rc );
/* fixme: allocate it on the stack */

View File

@ -330,6 +330,7 @@ print_cipher_algo_note( int algo )
else if( algo == GCRY_CIPHER_3DES
|| algo == GCRY_CIPHER_CAST5
|| algo == GCRY_CIPHER_BLOWFISH
|| algo == GCRY_CIPHER_RIJNDAEL
|| algo == GCRY_CIPHER_TWOFISH
)
;

View File

@ -819,7 +819,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
free_public_key( pk ); pk = NULL;
log_error(_("%s: skipped: %s\n"), rov->d, gpg_errstr(rc) );
}
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) {
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
pk->pubkey_usage)) ) {
/* Skip the actual key if the key is already present
* in the list */
if (key_present_in_pk_list(pk_list, pk) == 0) {
@ -874,7 +875,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
rc = get_pubkey_byname( NULL, pk, answer, NULL );
if( rc )
tty_printf(_("No such user ID.\n"));
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use)) ) {
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
pk->pubkey_usage)) ) {
if( have_def_rec ) {
if (key_present_in_pk_list(pk_list, pk) == 0) {
free_public_key(pk); pk = NULL;
@ -940,7 +942,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
rc = get_pubkey_byname( NULL, pk, def_rec, NULL );
if( rc )
log_error(_("unknown default recipient `%s'\n"), def_rec );
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use)) ) {
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
pk->pubkey_usage)) ) {
PK_LIST r = gcry_xmalloc( sizeof *r );
r->pk = pk; pk = NULL;
r->next = pk_list;
@ -966,7 +969,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
free_public_key( pk ); pk = NULL;
log_error(_("%s: skipped: %s\n"), remusr->d, gpg_errstr(rc) );
}
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) {
else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
pk->pubkey_usage)) ) {
int trustlevel;
rc = check_trust( pk, &trustlevel, pk->namehash, NULL, NULL );

View File

@ -75,7 +75,6 @@ pk_check_secret_key( int algo, MPI *skey )
static int
do_check( PKT_secret_key *sk )
{
byte *buffer;
u16 csum=0;
int i, res;
unsigned nbytes;
@ -324,7 +323,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
GCRY_STRONG_RANDOM);
gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
#warning FIXME: replace set/get buffer
/* FIXME: replace set/get buffer */
if( sk->version >= 4 ) {
byte *bufarr[GNUPG_MAX_NSKEY];
unsigned narr[GNUPG_MAX_NSKEY];
@ -336,7 +335,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ ) {
assert( !gcry_mpi_get_flag( sk->skey[i], GCRYMPI_FLAG_OPAQUE ) );
if( gcry_mpi_aprint( GCRYMPI_FMT_USG, (char*)bufarr+j,
if( gcry_mpi_aprint( GCRYMPI_FMT_USG, (void**)bufarr+j,
narr+j, sk->skey[i]))
BUG();
@ -374,7 +373,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
else {
/* NOTE: we always recalculate the checksum because there
* are some test releases which calculated it wrong */
#warning FIXME: Replace this code
/* FIXME: Replace this code -- Hmmm: why */
csum = 0;
for(i=pubkey_get_npkey(sk->pubkey_algo);
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {

View File

@ -40,6 +40,8 @@
#include "i18n.h"
#define ENABLE_BETTER_PGP2_COMPAT 1
#ifdef HAVE_DOSISH_SYSTEM
#define LF "\r\n"
#else
@ -217,13 +219,13 @@ complete_sig( PKT_signature *sig, PKT_secret_key *sk, GCRY_MD_HD md )
}
static int
hash_for(int pubkey_algo )
hash_for(int pubkey_algo, int packet_version )
{
if( opt.def_digest_algo )
return opt.def_digest_algo;
if( pubkey_algo == GCRY_PK_DSA )
return GCRY_MD_SHA1;
if( pubkey_algo == GCRY_PK_RSA )
if( pubkey_algo == GCRY_PK_RSA && packet_version < 4 )
return GCRY_MD_MD5;
return DEFAULT_DIGEST_ALGO;
}
@ -265,6 +267,94 @@ print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what )
write_status_text( STATUS_SIG_CREATED, buf );
}
static int
write_one_signature( IOBUF out, PKT_secret_key *sk, int old_style,
const char *outfile,
GCRY_MD_HD datamd,
int sig_class,
int status_char )
{
PKT_signature *sig;
GCRY_MD_HD md;
int rc;
/* build the signature packet */
/* fixme: this code is partly duplicated in make_keysig_packet */
sig = gcry_xcalloc( 1, sizeof *sig );
sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
keyid_from_sk( sk, sig->keyid );
sig->digest_algo = hash_for(sk->pubkey_algo, sk->version);
sig->pubkey_algo = sk->pubkey_algo;
sig->timestamp = make_timestamp();
sig->sig_class = sig_class;
md = gcry_md_copy( datamd );
if( !md )
BUG();
if( sig->version >= 4 ) {
build_sig_subpkt_from_sig( sig );
gcry_md_putc( md, sig->version );
}
mk_notation_and_policy( sig );
gcry_md_putc( md, sig->sig_class );
if( sig->version < 4 ) {
u32 a = sig->timestamp;
gcry_md_putc( md, (a >> 24) & 0xff );
gcry_md_putc( md, (a >> 16) & 0xff );
gcry_md_putc( md, (a >> 8) & 0xff );
gcry_md_putc( md, a & 0xff );
}
else {
byte buf[6];
size_t n;
gcry_md_putc( md, sig->pubkey_algo );
gcry_md_putc( md, sig->digest_algo );
if( sig->hashed_data ) {
n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
gcry_md_write( md, sig->hashed_data, n+2 );
n += 6;
}
else {
gcry_md_putc( md, 0 );/* always hash the length of the subpacket*/
gcry_md_putc( md, 0 );
n = 6;
}
/* add some magic */
buf[0] = sig->version;
buf[1] = 0xff;
buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
buf[3] = n >> 16;
buf[4] = n >> 8;
buf[5] = n;
gcry_md_write( md, buf, 6 );
}
gcry_md_final( md );
rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo, sk->version) );
gcry_md_close( md );
/* Hmmm: Do we release sig in case of rc != 0? */
if( !rc ) { /* and write it */
PACKET pkt;
init_packet(&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet( out, &pkt );
if( !rc && is_status_enabled() ) {
print_status_sig_created ( sk, sig, status_char );
}
free_packet( &pkt );
if( rc )
log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
}
return rc;
}
/****************
* Sign the files whose names are in FILENAME.
@ -360,7 +450,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
gcry_md_enable(mfx.md, hash_for(sk->pubkey_algo));
gcry_md_enable(mfx.md, hash_for(sk->pubkey_algo, sk->version ));
}
if( !multifile )
@ -385,6 +475,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
iobuf_push_filter( out, encrypt_filter, &efx );
}
/* Select a compress algorithm */
if( opt.compress && !outfile && ( !detached || opt.compress_sigs) ) {
if( !compr_algo )
; /* don't use compression */
@ -397,6 +488,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
}
}
/* Build one-pass signature packets when needed */
if( !detached && !old_style ) {
int skcount=0;
/* loop over the secret certificates and build headers
@ -417,7 +509,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
sk = sk_rover->sk;
ops = gcry_xcalloc( 1, sizeof *ops );
ops->sig_class = opt.textmode && !outfile ? 0x01 : 0x00;
ops->digest_algo = hash_for(sk->pubkey_algo);
ops->digest_algo = hash_for(sk->pubkey_algo, sk->version);
ops->pubkey_algo = sk->pubkey_algo;
keyid_from_sk( sk, ops->keyid );
ops->last = skcount == 1;
@ -437,6 +529,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
/* setup the inner packet */
if( detached ) {
/* this is pretty much the same for old and new PGP. So no
* need to cope with different packet ordering */
if( multifile ) {
STRLIST sl;
@ -468,9 +562,11 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
}
}
else {
/* get the filename to be stored into the literal datapacket */
if (!opt.no_literal) {
if( fname || opt.set_filename ) {
char *s = make_basename( opt.set_filename ? opt.set_filename : fname );
char *s = make_basename( opt.set_filename ?
opt.set_filename : fname );
pt = gcry_xmalloc( sizeof *pt + strlen(s) - 1 );
pt->namelen = strlen(s);
memcpy(pt->name, s, pt->namelen );
@ -490,7 +586,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
if ( filesize >= IOBUF_FILELENGTH_LIMIT )
filesize = 0;
/* because the text_filter modifies the length of the
/* Because the text_filter modifies the length of the
* data, it is not possible to know the used length
* without a double read of the file - to avoid that
* we simple use partial length packets.
@ -511,7 +607,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
pkt.pkt.plaintext = pt;
/*cfx.datalen = filesize? calc_packet_length( &pkt ) : 0;*/
if( (rc = build_packet( out, &pkt )) )
log_error("build_packet(PLAINTEXT) failed: %s\n", gpg_errstr(rc) );
log_error("build_packet(PLAINTEXT) failed: %s\n",
gpg_errstr(rc) );
pt->buf = NULL;
}
else {
@ -520,100 +617,24 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
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));
log_error("copying input to output failed: %s\n",
gpg_errstr(rc));
break;
}
memset(copy_buffer, 0, 4096); /* burn buffer */
}
}
/* catch errors from above blocks */
/* catch errors from above */
if (rc)
goto leave;
/* loop over the secret certificates */
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk;
PKT_signature *sig;
GCRY_MD_HD md;
sk = sk_rover->sk;
/* build the signature packet */
/* fixme: this code is partly duplicated in make_keysig_packet */
sig = gcry_xcalloc( 1, sizeof *sig );
sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
keyid_from_sk( sk, sig->keyid );
sig->digest_algo = hash_for(sk->pubkey_algo);
sig->pubkey_algo = sk->pubkey_algo;
sig->timestamp = make_timestamp();
sig->sig_class = opt.textmode && !outfile? 0x01 : 0x00;
md = gcry_md_copy( mfx.md );
if( !md )
BUG();
if( sig->version >= 4 ) {
build_sig_subpkt_from_sig( sig );
gcry_md_putc( md, sig->version );
}
mk_notation_and_policy( sig );
gcry_md_putc( md, sig->sig_class );
if( sig->version < 4 ) {
u32 a = sig->timestamp;
gcry_md_putc( md, (a >> 24) & 0xff );
gcry_md_putc( md, (a >> 16) & 0xff );
gcry_md_putc( md, (a >> 8) & 0xff );
gcry_md_putc( md, a & 0xff );
}
else {
byte buf[6];
size_t n;
gcry_md_putc( md, sig->pubkey_algo );
gcry_md_putc( md, sig->digest_algo );
if( sig->hashed_data ) {
n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
gcry_md_write( md, sig->hashed_data, n+2 );
n += 6;
}
else {
gcry_md_putc( md, 0 ); /* always hash the length of the subpacket*/
gcry_md_putc( md, 0 );
n = 6;
}
/* add some magic */
buf[0] = sig->version;
buf[1] = 0xff;
buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
buf[3] = n >> 16;
buf[4] = n >> 8;
buf[5] = n;
gcry_md_write( md, buf, 6 );
}
gcry_md_final( md );
rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo) );
gcry_md_close( md );
if( !rc ) { /* and write it */
init_packet(&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet( out, &pkt );
if( !rc && is_status_enabled() ) {
print_status_sig_created ( sk, sig, detached ? 'D':'S');
}
free_packet( &pkt );
if( rc )
log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
}
if( rc )
goto leave;
/* write all the signature packets */
for( sk_rover = sk_list; sk_rover && !rc ; sk_rover = sk_rover->next ) {
rc = write_one_signature( out, sk_rover->sk,
old_style, outfile, mfx.md,
opt.textmode && !outfile? 0x01 : 0x00,
detached ? 'D':'S' );
}
@ -626,6 +647,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
gcry_md_close( mfx.md );
release_sk_list( sk_list );
release_pk_list( pk_list );
/* FIXME: Did we release the efx.cfx.dek ? */
return rc;
}
@ -679,7 +701,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
if( hash_for(sk->pubkey_algo) == GCRY_MD_MD5 )
if( hash_for(sk->pubkey_algo, sk->version) == GCRY_MD_MD5 )
only_md5 = 1;
else {
only_md5 = 0;
@ -697,7 +719,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
iobuf_writestr(out, "Hash: " );
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
int i = hash_for(sk->pubkey_algo);
int i = hash_for(sk->pubkey_algo, sk->version);
if( !hashs_seen[ i & 0xff ] ) {
if( !openpgp_md_test_algo( i ) ) {
@ -723,7 +745,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
BUG();
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
gcry_md_enable(textmd, hash_for(sk->pubkey_algo));
gcry_md_enable(textmd, hash_for(sk->pubkey_algo, sk->version));
}
if ( DBG_HASHING )
gcry_md_start_debug( textmd, "clearsign" );
@ -735,90 +757,14 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
afx.what = 2;
iobuf_push_filter( out, armor_filter, &afx );
/* loop over the secret certificates */
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk;
PKT_signature *sig;
GCRY_MD_HD md;
sk = sk_rover->sk;
/* build the signature packet */
/* fixme: this code is duplicated above */
sig = gcry_xcalloc( 1, sizeof *sig );
sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
keyid_from_sk( sk, sig->keyid );
sig->digest_algo = hash_for(sk->pubkey_algo);
sig->pubkey_algo = sk->pubkey_algo;
sig->timestamp = make_timestamp();
sig->sig_class = 0x01;
md = gcry_md_copy( textmd );
if( !md )
BUG();
if( sig->version >= 4 ) {
build_sig_subpkt_from_sig( sig );
gcry_md_putc( md, sig->version );
}
mk_notation_and_policy( sig );
gcry_md_putc( md, sig->sig_class );
if( sig->version < 4 ) {
u32 a = sig->timestamp;
gcry_md_putc( md, (a >> 24) & 0xff );
gcry_md_putc( md, (a >> 16) & 0xff );
gcry_md_putc( md, (a >> 8) & 0xff );
gcry_md_putc( md, a & 0xff );
}
else {
byte buf[6];
size_t n;
gcry_md_putc( md, sig->pubkey_algo );
gcry_md_putc( md, sig->digest_algo );
if( sig->hashed_data ) {
n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
gcry_md_write( md, sig->hashed_data, n+2 );
n += 6;
}
else {
gcry_md_putc( md, 0 ); /* always hash the length of the subpacket*/
gcry_md_putc( md, 0 );
n = 6;
}
/* add some magic */
buf[0] = sig->version;
buf[1] = 0xff;
buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
buf[3] = n >> 16;
buf[4] = n >> 8;
buf[5] = n;
gcry_md_write( md, buf, 6 );
}
gcry_md_final( md );
rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo) );
gcry_md_close( md );
if( !rc ) { /* and write it */
init_packet(&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet( out, &pkt );
if( !rc && is_status_enabled() ) {
print_status_sig_created ( sk, sig, 'C');
}
free_packet( &pkt );
if( rc )
log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
}
if( rc )
goto leave;
/* write all the signature packets */
for( sk_rover = sk_list; sk_rover && !rc ; sk_rover = sk_rover->next ) {
rc = write_one_signature( out, sk_rover->sk,
old_style, outfile, textmd,
0x01,
'C' );
}
leave:
if( rc )
iobuf_cancel(out);

View File

@ -50,7 +50,7 @@ release_sk_list( SK_LIST sk_list )
int
build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
unsigned use )
unsigned int use )
{
SK_LIST sk_list = NULL;
int rc;
@ -64,9 +64,11 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
free_secret_key( sk ); sk = NULL;
log_error("no default secret key: %s\n", gpg_errstr(rc) );
}
else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo, use)) ) {
else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo,
sk->pubkey_usage)) ) {
SK_LIST r;
if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN )
if( sk->version == 4 && (sk->pubkey_usage & GCRY_PK_USAGE_SIGN )
&& sk->pubkey_algo == GCRY_PK_ELG_E ) {
log_info("this is a PGP generated "
"ElGamal key which is NOT secure for signatures!\n");
@ -95,9 +97,10 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
free_secret_key( sk ); sk = NULL;
log_error(_("skipped `%s': %s\n"), locusr->d, gpg_errstr(rc) );
}
else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo, use)) ) {
else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo,
sk->pubkey_usage)) ) {
SK_LIST r;
if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN)
if( sk->version == 4 && (sk->pubkey_usage & GCRY_PK_USAGE_SIGN)
&& sk->pubkey_algo == GCRY_PK_ELG_E ) {
log_info(_("skipped `%s': this is a PGP generated "
"ElGamal key which is not secure for signatures!\n"),

View File

@ -74,8 +74,9 @@ set_status_fd ( int newfd )
{
fd = newfd;
if ( fd != -1 ) {
#if 0
#warning fixme - progress functions
/* Has to be fixed in libgcrypt */
#if 0
register_primegen_progress ( progress_cb, "primegen" );
register_pk_dsa_progress ( progress_cb, "pk_dsa" );
register_pk_elg_progress ( progress_cb, "pk_elg" );

View File

@ -24,6 +24,7 @@ int tty_batchmode( int onoff );
void tty_printf( const char *fmt, ... );
void tty_print_string( byte *p, size_t n );
void tty_print_utf8_string( byte *p, size_t n );
void tty_print_utf8_string2( byte *p, size_t n, size_t max_n );
char *tty_get( const char *prompt );
char *tty_get_hidden( const char *prompt );
void tty_kill_prompt(void);