summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2000-10-04 13:16:19 +0200
committerWerner Koch <wk@gnupg.org>2000-10-04 13:16:19 +0200
commit9c20f65cbe9d3d806b02f0f90a2051a20f3857db (patch)
tree6c784f870b191b2a1b3f16f86cff3a5af59ff2f6
parentSee ChangeLog: Mon Sep 18 16:35:45 CEST 2000 Werner Koch (diff)
downloadgnupg2-9c20f65cbe9d3d806b02f0f90a2051a20f3857db.tar.xz
gnupg2-9c20f65cbe9d3d806b02f0f90a2051a20f3857db.zip
See ChangeLog: Wed Oct 4 13:16:18 CEST 2000 Werner Koch
-rw-r--r--NEWS2
-rw-r--r--TODO7
-rw-r--r--checks/ChangeLog4
-rwxr-xr-xchecks/run-gpg4
-rw-r--r--checks/run-gpg.patterns3
-rw-r--r--cipher/ChangeLog14
-rw-r--r--cipher/Makefile.am1
-rw-r--r--cipher/cipher.c50
-rw-r--r--cipher/md.c19
-rw-r--r--cipher/random.h2
-rw-r--r--cipher/rsa.c5
-rw-r--r--cipher/sha1.c2
-rw-r--r--doc/gcryptref-digest.sgml7
-rw-r--r--doc/gcryptref-misc.sgml289
-rw-r--r--g10/ChangeLog15
-rw-r--r--g10/encode.c135
-rw-r--r--g10/export.c2
-rw-r--r--g10/getkey.c58
-rw-r--r--g10/gpg.c4
-rw-r--r--g10/keydb.h1
-rw-r--r--g10/keygen.c3
-rw-r--r--g10/keyid.c2
-rw-r--r--g10/misc.c1
-rw-r--r--g10/pkclist.c12
-rw-r--r--g10/seckey-cert.c7
-rw-r--r--g10/sign.c300
-rw-r--r--g10/skclist.c13
-rw-r--r--g10/status.c3
-rw-r--r--include/ttyio.h1
29 files changed, 630 insertions, 336 deletions
diff --git a/NEWS b/NEWS
index d5367ae1c..66d650a2a 100644
--- a/NEWS
+++ b/NEWS
@@ -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.
diff --git a/TODO b/TODO
index 45d066797..da49089d7 100644
--- a/TODO
+++ b/TODO
@@ -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.
diff --git a/checks/ChangeLog b/checks/ChangeLog
index 9be8600e9..b5c810bfd 100644
--- a/checks/ChangeLog
+++ b/checks/ChangeLog
@@ -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.
diff --git a/checks/run-gpg b/checks/run-gpg
index a9e0e31cc..28d575e95 100755
--- a/checks/run-gpg
+++ b/checks/run-gpg
@@ -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.$$
diff --git a/checks/run-gpg.patterns b/checks/run-gpg.patterns
index 9eb355e5b..fde7bbbe7 100644
--- a/checks/run-gpg.patterns
+++ b/checks/run-gpg.patterns
@@ -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
+
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index 2e4ebe53e..1d793ec34 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -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.
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 26de92520..6feea1563 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -36,6 +36,7 @@ libcipher_la_SOURCES = cipher.c \
bithelp.h \
des.c \
des.h \
+ rijndael.c \
twofish.c \
blowfish.c \
blowfish.h \
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 7808d8769..d36db6652 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -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 );
diff --git a/cipher/md.c b/cipher/md.c
index e8ac8ac24..29d6afed8 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -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)
*/
diff --git a/cipher/random.h b/cipher/random.h
index 9a7dd8f68..d96cea7f3 100644
--- a/cipher/random.h
+++ b/cipher/random.h
@@ -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 );
diff --git a/cipher/rsa.c b/cipher/rsa.c
index 2bb451002..f342e3c35 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -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 );
diff --git a/cipher/sha1.c b/cipher/sha1.c
index aa3ac092f..a0438dbd6 100644
--- a/cipher/sha1.c
+++ b/cipher/sha1.c
@@ -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 ) \
diff --git a/doc/gcryptref-digest.sgml b/doc/gcryptref-digest.sgml
index a123c9b25..3b4dcd7e8 100644
--- a/doc/gcryptref-digest.sgml
+++ b/doc/gcryptref-digest.sgml
@@ -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 */
+
diff --git a/doc/gcryptref-misc.sgml b/doc/gcryptref-misc.sgml
index 31032d64d..8b93ee798 100644
--- a/doc/gcryptref-misc.sgml
+++ b/doc/gcryptref-misc.sgml
@@ -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 );
-->
+
+
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 7cb0f17b7..fb25e7fdc 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -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.
diff --git a/g10/encode.c b/g10/encode.c
index a817f9094..f033c76ae 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -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;
-
- 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 */
+ /* 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 )
@@ -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,
diff --git a/g10/export.c b/g10/export.c
index 2de9f91bf..ddcc971d9 100644
--- a/g10/export.c
+++ b/g10/export.c
@@ -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 )) ) {
diff --git a/g10/getkey.c b/g10/getkey.c
index 17dc6fafb..aa32dff74 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -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;
diff --git a/g10/gpg.c b/g10/gpg.c
index be4ec98a7..6faeb0721 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -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;
diff --git a/g10/keydb.h b/g10/keydb.h
index 830a7db3c..43c36e719 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -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 );
diff --git a/g10/keygen.c b/g10/keygen.c
index fc3b2cf8c..ef0064fc7 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -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!)" );
diff --git a/g10/keyid.c b/g10/keyid.c
index fb652e7b2..a4acb16d5 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -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 */
diff --git a/g10/misc.c b/g10/misc.c
index a62a04766..2348e46f0 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -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
)
;
diff --git a/g10/pkclist.c b/g10/pkclist.c
index d827ce653..d585880ea 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -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 );
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 0be514eb3..2adb9ef4c 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -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++ ) {
diff --git a/g10/sign.c b/g10/sign.c
index b53444b7c..bdc5b8afe 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -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);
diff --git a/g10/skclist.c b/g10/skclist.c
index 5c6d6fbd7..dceba71f8 100644
--- a/g10/skclist.c
+++ b/g10/skclist.c
@@ -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"),
diff --git a/g10/status.c b/g10/status.c
index 2eb6724f3..d336ae3b0 100644
--- a/g10/status.c
+++ b/g10/status.c
@@ -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" );
diff --git a/include/ttyio.h b/include/ttyio.h
index 0b447066f..e81c659c4 100644
--- a/include/ttyio.h
+++ b/include/ttyio.h
@@ -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);