mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
added more stuff
This commit is contained in:
parent
4d2636eafe
commit
b7bdef0834
84
README
84
README
@ -51,7 +51,6 @@
|
||||
|
||||
Key Generation
|
||||
--------------
|
||||
Create a key pair with this command:
|
||||
|
||||
g10 --gen-key
|
||||
|
||||
@ -59,7 +58,7 @@
|
||||
good random numbers for prime number generation, it uses a /dev/random
|
||||
which will emit only bytes if the kernel can gather enough entropy.
|
||||
If you see no progress, you should start some other activities such
|
||||
as a mouse moves or a "find /". Because we have no hardware device
|
||||
as mouse moves or a "find /". Because we have no hardware device
|
||||
to generate random we have to use this method.
|
||||
|
||||
Key generation shows progress by printing different characters to
|
||||
@ -89,9 +88,25 @@
|
||||
9) Find a generator for that prime.
|
||||
|
||||
|
||||
Signatures
|
||||
----------
|
||||
To create a signature, use this:
|
||||
You can sign a key with this command:
|
||||
|
||||
g10 --sign-key Donald
|
||||
|
||||
To sign the key of of "Donald" with your default userid
|
||||
|
||||
g10 --sign-key -u Karl -u Joe Donald
|
||||
|
||||
To sign the key of of "Donald" with the userids of "Karl" and "Joe".
|
||||
All existing signatures are checked, if some are invalid, a menu is
|
||||
offered to delete some of them, and the you are asked for every user
|
||||
wether you want to sign this key.
|
||||
|
||||
You may remove a signature at any time by usiing the option "--edit-sig",
|
||||
which also asks for the sigs to remove.
|
||||
|
||||
|
||||
Sign
|
||||
----
|
||||
|
||||
g10 -s file
|
||||
|
||||
@ -106,9 +121,9 @@
|
||||
|
||||
Creates a signature of file, but writes the output to the file "out".
|
||||
|
||||
Encryption
|
||||
----------
|
||||
To encrypt data use this:
|
||||
|
||||
Encrypt
|
||||
-------
|
||||
|
||||
g10 -e -r heine file
|
||||
|
||||
@ -120,6 +135,51 @@
|
||||
Ditto, but encrypts "hallo\n" and mails it as ascii armored message.
|
||||
|
||||
|
||||
Sign and Encrypt
|
||||
----------------
|
||||
|
||||
g10 -se -r heine file
|
||||
|
||||
This encrypts files with the public key of "heine" and writes it
|
||||
to "file.g10" after signing it with the default user id.
|
||||
|
||||
|
||||
g10 -se -r heine -u Suttner file
|
||||
|
||||
Ditto, but sign the file with the user id "Suttner"
|
||||
|
||||
|
||||
|
||||
Examine a data or key file
|
||||
--------------------------
|
||||
|
||||
g10 --list-packets datafile
|
||||
|
||||
Use this to list the contents of a data file. If the file is encrypted
|
||||
you are asked for the passphrase, so that G10 is able to look at the
|
||||
inner structure of a encrypted packet.
|
||||
|
||||
|
||||
Batch mode
|
||||
----------
|
||||
If you use the option "--batch", G10 runs in non-interactive mode and
|
||||
never prompts for input data. This even does not allow to enter
|
||||
passphrase; until we have a better solution (something like ssh-agent),
|
||||
you can use the option "--passhrase-fd n", which works like PGPs
|
||||
PGPPASSFD.
|
||||
|
||||
Batch mode also causes PGP to terminate as soon as a BAD signature is
|
||||
detected.
|
||||
|
||||
|
||||
Exit status
|
||||
-----------
|
||||
G10 returns with an exit status of 1 if in batch mode and a bad signature
|
||||
has been detected or 2 or higher for all other errors. You should parse
|
||||
stderr to get detailed informations about the errors.
|
||||
|
||||
|
||||
|
||||
Debug Flags
|
||||
-----------
|
||||
Use the option "--debug n" to output debug informations. This option
|
||||
@ -146,18 +206,10 @@
|
||||
I will run "indent" over the source when making a real distribution,
|
||||
but for now I stick to my own formatting rules.
|
||||
|
||||
Compression does not work always; this is the reason that "-z 0"
|
||||
is the default.
|
||||
|
||||
This will be cleaned up of course.
|
||||
|
||||
The primary FTP site is "ftp://ftp.guug.de/pub/gcrypt/"
|
||||
The primary WWW page is "http://www.d.shuttle.de/isil/g10.html"
|
||||
|
||||
Please direct bug reports to <g10-bugs@isil.d.shuttle.de> or better
|
||||
post them to the mailing list <g10@net.lut.ac.uk>.
|
||||
|
||||
Have fun
|
||||
|
||||
Werner
|
||||
|
||||
|
3
TODO
3
TODO
@ -22,7 +22,6 @@
|
||||
before we can check wether we have the pubkey or not. The one-pass
|
||||
signature packets should be implemented to avoid this.
|
||||
|
||||
* compress does not work always!
|
||||
* complete cipher/cast.c
|
||||
* complete cipher/dsa.c
|
||||
|
||||
@ -34,3 +33,5 @@
|
||||
of the userid.
|
||||
[can be handles in get_pubkey_by_name()]
|
||||
|
||||
* armor has now some problems.
|
||||
|
||||
|
@ -21,9 +21,12 @@
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
@ -98,6 +101,7 @@ fill_buffer( byte *buffer, size_t length, int level )
|
||||
static int fd_random = -1;
|
||||
int fd;
|
||||
int n;
|
||||
int warn=0;
|
||||
|
||||
if( level == 2 ) {
|
||||
if( fd_random == -1 )
|
||||
@ -112,11 +116,34 @@ fill_buffer( byte *buffer, size_t length, int level )
|
||||
|
||||
|
||||
do {
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
int rc;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
tv.tv_sec = 3;
|
||||
tv.tv_usec = 0;
|
||||
if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
|
||||
if( !warn )
|
||||
tty_printf(
|
||||
"\nNot enough random bytes available. Please do some other work to give
|
||||
the OS a chance to collect more entropy! (Need %d more bytes)\n", length );
|
||||
warn = 1;
|
||||
continue;
|
||||
}
|
||||
else if( rc == -1 ) {
|
||||
tty_printf("select() error: %s\n", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
assert( length < 200 );
|
||||
do {
|
||||
n = read(fd, buffer, length );
|
||||
} while( n == -1 && errno == EINTR );
|
||||
if( n == -1 )
|
||||
log_fatal("read error on random device: %s\n", strerror(errno) );
|
||||
assert( n <= length );
|
||||
buffer += n;
|
||||
length -= n;
|
||||
} while( length );
|
||||
|
@ -30,6 +30,7 @@ g10_SOURCES = g10.c \
|
||||
options.h \
|
||||
openfile.c \
|
||||
keyid.c \
|
||||
trustdb.c \
|
||||
packet.h \
|
||||
parse-packet.c \
|
||||
passphrase.c \
|
||||
|
@ -68,6 +68,7 @@ g10_SOURCES = g10.c \
|
||||
options.h \
|
||||
openfile.c \
|
||||
keyid.c \
|
||||
trustdb.c \
|
||||
packet.h \
|
||||
parse-packet.c \
|
||||
passphrase.c \
|
||||
@ -100,8 +101,8 @@ LINK = $(CC) $(LDFLAGS) -o $@
|
||||
g10_OBJECTS = g10.o build-packet.o compress.o encode.o encr-data.o \
|
||||
free-packet.o getkey.o pkclist.o skclist.o ringedit.o kbnode.o keygen.o \
|
||||
mainproc.o armor.o mdfilter.o textfilter.o cipher.o elg.o rsa.o \
|
||||
openfile.o keyid.o parse-packet.o passphrase.o plaintext.o pubkey-enc.o \
|
||||
seckey-cert.o seskey.o sign.o comment.o sig-check.o
|
||||
openfile.o keyid.o trustdb.o parse-packet.o passphrase.o plaintext.o \
|
||||
pubkey-enc.o seckey-cert.o seskey.o sign.o comment.o sig-check.o
|
||||
EXTRA_g10_SOURCES =
|
||||
g10_LDADD = $(LDADD)
|
||||
DIST_COMMON = Makefile.am Makefile.in
|
||||
@ -130,7 +131,8 @@ $(srcdir)/.deps/plaintext.P $(srcdir)/.deps/pubkey-enc.P \
|
||||
$(srcdir)/.deps/ringedit.P $(srcdir)/.deps/rsa.P \
|
||||
$(srcdir)/.deps/seckey-cert.P $(srcdir)/.deps/seskey.P \
|
||||
$(srcdir)/.deps/sig-check.P $(srcdir)/.deps/sign.P \
|
||||
$(srcdir)/.deps/skclist.P $(srcdir)/.deps/textfilter.P
|
||||
$(srcdir)/.deps/skclist.P $(srcdir)/.deps/textfilter.P \
|
||||
$(srcdir)/.deps/trustdb.P
|
||||
SOURCES = $(g10_SOURCES)
|
||||
OBJECTS = $(g10_OBJECTS)
|
||||
|
||||
|
88
g10/encode.c
88
g10/encode.c
@ -37,6 +37,7 @@
|
||||
|
||||
|
||||
static int encode_simple( const char *filename, int mode );
|
||||
static int write_pubkey_enc_from_list( PKC_LIST pkc_list, DEK *dek, IOBUF out );
|
||||
|
||||
|
||||
|
||||
@ -164,7 +165,7 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
cipher_filter_context_t cfx;
|
||||
armor_filter_context_t afx;
|
||||
compress_filter_context_t zfx;
|
||||
PKC_LIST pkc_list, pkc_rover;
|
||||
PKC_LIST pkc_list;
|
||||
|
||||
memset( &cfx, 0, sizeof cfx);
|
||||
memset( &afx, 0, sizeof afx);
|
||||
@ -203,31 +204,9 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
||||
|
||||
/* loop over all public key certificates */
|
||||
for( pkc_rover=pkc_list; pkc_rover; pkc_rover = pkc_rover->next ) {
|
||||
PKT_public_cert *pkc;
|
||||
PKT_pubkey_enc *enc;
|
||||
|
||||
pkc = pkc_rover->pkc;
|
||||
enc = m_alloc_clear( sizeof *enc );
|
||||
enc->pubkey_algo = pkc->pubkey_algo;
|
||||
if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||
g10_elg_encrypt( pkc, enc, cfx.dek );
|
||||
else if( enc->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
g10_rsa_encrypt( pkc, enc, cfx.dek );
|
||||
else
|
||||
log_bug(NULL);
|
||||
/* and write it */
|
||||
init_packet(&pkt);
|
||||
pkt.pkttype = PKT_PUBKEY_ENC;
|
||||
pkt.pkt.pubkey_enc = enc;
|
||||
rc = build_packet( out, &pkt );
|
||||
free_pubkey_enc(enc);
|
||||
if( rc ) {
|
||||
log_error("build pubkey_enc packet failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
rc = write_pubkey_enc_from_list( pkc_list, cfx.dek, out );
|
||||
if( rc )
|
||||
goto leave;
|
||||
|
||||
/* setup the inner packet */
|
||||
if( filename ) {
|
||||
@ -276,7 +255,6 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
/****************
|
||||
* Filter to do a complete public key encryption.
|
||||
*/
|
||||
#if 0
|
||||
int
|
||||
encrypt_filter( void *opaque, int control,
|
||||
IOBUF a, byte *buf, size_t *ret_len)
|
||||
@ -289,6 +267,24 @@ encrypt_filter( void *opaque, int control,
|
||||
log_bug(NULL); /* not used */
|
||||
}
|
||||
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
|
||||
if( !efx->header_okay ) {
|
||||
efx->cfx.dek = m_alloc_secure( sizeof *efx->cfx.dek );
|
||||
efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
|
||||
make_session_key( efx->cfx.dek );
|
||||
if( DBG_CIPHER )
|
||||
log_hexdump("DEK is: ",
|
||||
efx->cfx.dek->key, efx->cfx.dek->keylen );
|
||||
|
||||
rc = write_pubkey_enc_from_list( efx->pkc_list, efx->cfx.dek, a );
|
||||
if( rc )
|
||||
return rc;
|
||||
|
||||
iobuf_push_filter( a, cipher_filter, &efx->cfx );
|
||||
|
||||
efx->header_okay = 1;
|
||||
}
|
||||
rc = iobuf_write( a, buf, size );
|
||||
|
||||
}
|
||||
else if( control == IOBUFCTRL_FREE ) {
|
||||
}
|
||||
@ -297,5 +293,41 @@ encrypt_filter( void *opaque, int control,
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/****************
|
||||
* Write pubkey-enc packets from the list of PKCs to OUT.
|
||||
*/
|
||||
static int
|
||||
write_pubkey_enc_from_list( PKC_LIST pkc_list, DEK *dek, IOBUF out )
|
||||
{
|
||||
PACKET pkt;
|
||||
PKT_public_cert *pkc;
|
||||
PKT_pubkey_enc *enc;
|
||||
int rc;
|
||||
|
||||
for( ; pkc_list; pkc_list = pkc_list->next ) {
|
||||
|
||||
pkc = pkc_list->pkc;
|
||||
enc = m_alloc_clear( sizeof *enc );
|
||||
enc->pubkey_algo = pkc->pubkey_algo;
|
||||
if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||
g10_elg_encrypt( pkc, enc, dek );
|
||||
else if( enc->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
g10_rsa_encrypt( pkc, enc, dek );
|
||||
else
|
||||
log_bug(NULL);
|
||||
/* and write it */
|
||||
init_packet(&pkt);
|
||||
pkt.pkttype = PKT_PUBKEY_ENC;
|
||||
pkt.pkt.pubkey_enc = enc;
|
||||
rc = build_packet( out, &pkt );
|
||||
free_pubkey_enc(enc);
|
||||
if( rc ) {
|
||||
log_error("build pubkey_enc packet failed: %s\n", g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@ typedef struct {
|
||||
} cipher_filter_context_t;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
size_t linesize;
|
||||
byte *line;
|
||||
@ -73,6 +74,9 @@ typedef struct {
|
||||
int eof;
|
||||
} text_filter_context_t;
|
||||
|
||||
|
||||
/* encrypt_filter_context_t defined in main.h */
|
||||
|
||||
/*-- mdfilter.c --*/
|
||||
int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len);
|
||||
void free_md_filter_context( md_filter_context_t *mfx );
|
||||
|
69
g10/g10.c
69
g10/g10.c
@ -121,7 +121,7 @@ main( int argc, char **argv )
|
||||
{ 'e', "encrypt", 0, "encrypt data" },
|
||||
{ 'd', "decrypt", 0, "decrypt data (default)" },
|
||||
/*{ 'c', "check", 0, "check a signature (default)" }, */
|
||||
{ 'l', "local-user",2, "use this user-id to sign or decrypt" },
|
||||
{ 'u', "local-user",2, "use this user-id to sign or decrypt" },
|
||||
{ 'r', "remote-user", 2, "use this user-id for encryption" },
|
||||
{ 510, "debug" ,4|16, "set debugging flags" },
|
||||
{ 511, "debug-all" ,0, "enable full debugging"},
|
||||
@ -135,13 +135,17 @@ main( int argc, char **argv )
|
||||
{ 518, "options" , 2, "read options from file" },
|
||||
{ 519, "no-armor", 0, "\r"},
|
||||
{ 520, "no-default-keyring", 0, "\r" },
|
||||
{ 521, "list-packets",0,"list only the sequence of packets"},
|
||||
{ 522, "no-greeting", 0, "\r" },
|
||||
{ 523, "passphrase-fd",1, "\r" },
|
||||
{ 524, "edit-sig" ,0, "edit a key signature" },
|
||||
|
||||
{0} };
|
||||
ARGPARSE_ARGS pargs;
|
||||
IOBUF a;
|
||||
int rc;
|
||||
enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
|
||||
aTest, aPrintMDs, aSignKey, aClearsig
|
||||
aTest, aPrintMDs, aSignKey, aClearsig, aListPackets, aEditSig,
|
||||
} action = aNull;
|
||||
int orig_argc;
|
||||
char **orig_argv;
|
||||
@ -158,9 +162,10 @@ main( int argc, char **argv )
|
||||
int default_config =1;
|
||||
int errors=0;
|
||||
int default_keyring = 1;
|
||||
int greeting = 1;
|
||||
|
||||
|
||||
opt.compress = 0; /* defaults to no compression level */
|
||||
opt.compress = -1; /* defaults to standard compress level */
|
||||
|
||||
/* check wether we have a config file on the commandline */
|
||||
orig_argc = argc;
|
||||
@ -221,7 +226,7 @@ main( int argc, char **argv )
|
||||
/* fall trough */
|
||||
case 's': action = action == aEncr? aSignEncr : aSign; break;
|
||||
case 't': action = aClearsig; break;
|
||||
case 'l': /* store the local users */
|
||||
case 'u': /* store the local users */
|
||||
sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
|
||||
strcpy(sl->d, pargs.r.ret_str);
|
||||
sl->next = locusr;
|
||||
@ -233,7 +238,7 @@ main( int argc, char **argv )
|
||||
sl->next = remusr;
|
||||
remusr = sl;
|
||||
break;
|
||||
case 500: opt.batch = 1; break;
|
||||
case 500: opt.batch = 1; greeting = 0; break;
|
||||
case 501: opt.answer_yes = 1; break;
|
||||
case 502: opt.answer_no = 1; break;
|
||||
case 503: action = aKeygen; break;
|
||||
@ -259,6 +264,10 @@ main( int argc, char **argv )
|
||||
break;
|
||||
case 519: opt.no_armor=1; opt.armor=0; break;
|
||||
case 520: default_keyring = 0; break;
|
||||
case 521: action = aListPackets; break;
|
||||
case 522: greeting = 0; break;
|
||||
case 523: set_passphrase_fd( pargs.r.ret_int ); break;
|
||||
case 524: action = aEditSig; break;
|
||||
default : errors++; pargs.err = configfp? 1:2; break;
|
||||
}
|
||||
}
|
||||
@ -275,11 +284,11 @@ main( int argc, char **argv )
|
||||
set_debug();
|
||||
if( opt.verbose > 1 )
|
||||
set_packet_list_mode(1);
|
||||
if( opt.verbose && isatty(fileno(stdin)) ) {
|
||||
if( greeting ) {
|
||||
if( *(s=strusage(10)) )
|
||||
fputs(s, stderr);
|
||||
tty_printf("%s", s);
|
||||
if( *(s=strusage(30)) )
|
||||
fputs(s, stderr);
|
||||
tty_printf("%s", s);
|
||||
}
|
||||
|
||||
if( !sec_nrings || default_keyring ) { /* add default secret rings */
|
||||
@ -347,6 +356,14 @@ main( int argc, char **argv )
|
||||
log_error("sign_key('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aEditSig: /* Edit a key signature */
|
||||
if( argc != 1 )
|
||||
usage(1);
|
||||
/* note: fname is the user id! */
|
||||
if( (rc = edit_keysigs(fname)) )
|
||||
log_error("edit_keysig('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
|
||||
case aPrimegen:
|
||||
if( argc == 1 ) {
|
||||
@ -388,6 +405,8 @@ main( int argc, char **argv )
|
||||
|
||||
case aTest: do_test( argc? atoi(*argv): 0 ); break;
|
||||
|
||||
case aListPackets:
|
||||
opt.list_packets=1;
|
||||
default:
|
||||
if( argc > 1 )
|
||||
usage(1);
|
||||
@ -398,6 +417,10 @@ main( int argc, char **argv )
|
||||
memset( &afx, 0, sizeof afx);
|
||||
iobuf_push_filter( a, armor_filter, &afx );
|
||||
}
|
||||
if( action == aListPackets ) {
|
||||
set_packet_list_mode(1);
|
||||
opt.list_packets=1;
|
||||
}
|
||||
proc_packets( a );
|
||||
iobuf_close(a);
|
||||
break;
|
||||
@ -406,7 +429,7 @@ main( int argc, char **argv )
|
||||
/* cleanup */
|
||||
FREE_STRLIST(remusr);
|
||||
FREE_STRLIST(locusr);
|
||||
return 0;
|
||||
return log_get_errorcount(0)? 2:0;
|
||||
}
|
||||
|
||||
|
||||
@ -509,33 +532,5 @@ do_test(int times)
|
||||
|
||||
m_check(NULL);
|
||||
#endif
|
||||
#if 0
|
||||
char *array;
|
||||
int i, j;
|
||||
int n = 6;
|
||||
int m = times;
|
||||
|
||||
if( m > n )
|
||||
abort();
|
||||
array = m_alloc_clear( n );
|
||||
memset( array, 1, m );
|
||||
|
||||
for(i=0;; i++) {
|
||||
printf("i=%3d: ", i );
|
||||
for(j=0; j < n ; j++ )
|
||||
if( array[j] )
|
||||
putchar( 'X' );
|
||||
else
|
||||
putchar( '-' );
|
||||
putchar('\n');
|
||||
m_out_of_n( array, m, n );
|
||||
for(j=0; j < n; j++ )
|
||||
if( !array[j] )
|
||||
break;
|
||||
if( j == m )
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
55
g10/kbnode.c
55
g10/kbnode.c
@ -38,6 +38,7 @@ new_kbnode( PACKET *pkt )
|
||||
n->pkt = pkt;
|
||||
n->child = NULL;
|
||||
n->flag = 0;
|
||||
n->private_flag=0; /* kludge to delete a node */
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -57,6 +58,16 @@ release_kbnode( KBNODE n )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Delete NODE from ROOT, ROOT must exist!
|
||||
* Note does only work with walk_kbtree!!
|
||||
*/
|
||||
void
|
||||
delete_kbnode( KBNODE root, KBNODE node )
|
||||
{
|
||||
node->private_flag |= 1;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Append NODE to ROOT, ROOT must exist!
|
||||
*/
|
||||
@ -115,27 +126,36 @@ find_kbparent( KBNODE root, KBNODE node )
|
||||
*/
|
||||
KBNODE
|
||||
walk_kbtree( KBNODE root, KBNODE *context )
|
||||
{
|
||||
return walk_kbtree2( root, context, 0 );
|
||||
}
|
||||
|
||||
KBNODE
|
||||
walk_kbtree2( KBNODE root, KBNODE *context, int all )
|
||||
{
|
||||
KBNODE n;
|
||||
|
||||
if( !*context ) {
|
||||
*context = root;
|
||||
return root;
|
||||
}
|
||||
do {
|
||||
if( !*context ) {
|
||||
*context = root;
|
||||
return root;
|
||||
}
|
||||
|
||||
n = *context;
|
||||
if( n->child ) {
|
||||
n = n->child;
|
||||
*context = n;
|
||||
}
|
||||
else if( n->next ) {
|
||||
n = n->next;
|
||||
*context = n;
|
||||
}
|
||||
else if( (n = find_kbparent( root, n )) ) {
|
||||
n = n->next;
|
||||
*context = n;
|
||||
}
|
||||
} while( !all && n && (n->private_flag & 1) );
|
||||
|
||||
n = *context;
|
||||
if( n->child ) {
|
||||
n = n->child;
|
||||
*context = n;
|
||||
}
|
||||
else if( n->next ) {
|
||||
n = n->next;
|
||||
*context = n;
|
||||
}
|
||||
else if( (n = find_kbparent( root, n )) ) {
|
||||
n = n->next;
|
||||
*context = n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -147,3 +167,4 @@ clear_kbnode_flags( KBNODE n )
|
||||
n->flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ struct kbnode_struct {
|
||||
KBNODE next; /* used to form a link list */
|
||||
KBNODE child;
|
||||
int flag;
|
||||
int private_flag;
|
||||
};
|
||||
|
||||
/****************
|
||||
@ -81,6 +82,8 @@ void release_skc_list( SKC_LIST skc_list );
|
||||
int build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock );
|
||||
|
||||
/*-- passphrase.h --*/
|
||||
void set_passphrase_fd( int fd );
|
||||
int get_passphrase_fd(void);
|
||||
DEK *get_passphrase_hash( u32 *keyid, char *text );
|
||||
int make_dek_from_passphrase( DEK *dek, int mode );
|
||||
|
||||
@ -112,10 +115,12 @@ byte *fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len );
|
||||
/*-- kbnode.c --*/
|
||||
KBNODE new_kbnode( PACKET *pkt );
|
||||
void release_kbnode( KBNODE n );
|
||||
void delete_kbnode( KBNODE root, KBNODE node );
|
||||
void add_kbnode( KBNODE root, KBNODE node );
|
||||
void add_kbnode_as_child( KBNODE root, KBNODE node );
|
||||
KBNODE find_kbparent( KBNODE root, KBNODE node );
|
||||
KBNODE walk_kbtree( KBNODE root, KBNODE *context );
|
||||
KBNODE walk_kbtree2( KBNODE root, KBNODE *context, int all );
|
||||
void clear_kbnode_flags( KBNODE n );
|
||||
|
||||
/*-- ringedit.c --*/
|
||||
|
@ -155,7 +155,7 @@ datestr_from_pkc( PKT_public_cert *pkc )
|
||||
time_t atime = pkc->timestamp;
|
||||
|
||||
tp = gmtime( &atime );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ datestr_from_skc( PKT_secret_cert *skc )
|
||||
time_t atime = skc->timestamp;
|
||||
|
||||
tp = gmtime( &atime );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ datestr_from_sig( PKT_signature *sig )
|
||||
time_t atime = sig->timestamp;
|
||||
|
||||
tp = gmtime( &atime );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
|
||||
sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
12
g10/main.h
12
g10/main.h
@ -28,15 +28,27 @@
|
||||
#define DEFAULT_PUBKEY_ALGO PUBKEY_ALGO_ELGAMAL
|
||||
#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_RMD160
|
||||
|
||||
|
||||
typedef struct {
|
||||
int header_okay;
|
||||
PKC_LIST pkc_list;
|
||||
cipher_filter_context_t cfx;
|
||||
} encrypt_filter_context_t;
|
||||
|
||||
|
||||
/*-- encode.c --*/
|
||||
int encode_symmetric( const char *filename );
|
||||
int encode_store( const char *filename );
|
||||
int encode_crypt( const char *filename, STRLIST remusr );
|
||||
int encrypt_filter( void *opaque, int control,
|
||||
IOBUF a, byte *buf, size_t *ret_len);
|
||||
|
||||
|
||||
/*-- sign.c --*/
|
||||
int sign_file( const char *filename, int detached, STRLIST locusr,
|
||||
int encrypt, STRLIST remusr );
|
||||
int sign_key( const char *username, STRLIST locusr );
|
||||
int edit_keysigs( const char *username );
|
||||
|
||||
/*-- sig-check.c --*/
|
||||
int check_key_signature( KBNODE root, KBNODE node );
|
||||
|
@ -46,7 +46,6 @@ typedef struct {
|
||||
md_filter_context_t mfx;
|
||||
DEK *dek;
|
||||
int last_was_pubkey_enc;
|
||||
int opt_list;
|
||||
KBNODE cert; /* the current certificate */
|
||||
int have_data;
|
||||
IOBUF iobuf; /* used to get the filename etc. */
|
||||
@ -198,7 +197,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
|
||||
|
||||
c->last_was_pubkey_enc = 1;
|
||||
enc = pkt->pkt.pubkey_enc;
|
||||
printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );
|
||||
/*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
|
||||
if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
|
||||
|| enc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
m_free(c->dek ); /* paranoid: delete a pending DEK */
|
||||
@ -213,11 +212,12 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
|
||||
|
||||
if( result == -1 )
|
||||
;
|
||||
else if( !result )
|
||||
fputs( " DEK is good", stdout );
|
||||
else if( !result ) {
|
||||
if( opt.verbose > 1 )
|
||||
log_info( "pubkey_enc packet: Good DEK\n" );
|
||||
}
|
||||
else
|
||||
printf( " %s", g10_errstr(result));
|
||||
putchar('\n');
|
||||
log_error( "pubkey_enc packet: %s\n", g10_errstr(result));
|
||||
free_packet(pkt);
|
||||
}
|
||||
|
||||
@ -228,7 +228,7 @@ proc_encrypted( CTX c, PACKET *pkt )
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
printf("dat: %sencrypted data\n", c->dek?"":"conventional ");
|
||||
/*printf("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
|
||||
if( !c->dek && !c->last_was_pubkey_enc ) {
|
||||
/* assume this is conventional encrypted data */
|
||||
c->dek = m_alloc_secure( sizeof *c->dek );
|
||||
@ -242,11 +242,13 @@ proc_encrypted( CTX c, PACKET *pkt )
|
||||
m_free(c->dek); c->dek = NULL;
|
||||
if( result == -1 )
|
||||
;
|
||||
else if( !result )
|
||||
fputs( " encryption okay",stdout);
|
||||
else
|
||||
printf( " %s", g10_errstr(result));
|
||||
putchar('\n');
|
||||
else if( !result ) {
|
||||
if( opt.verbose > 1 )
|
||||
log_info("encryption okay\n");
|
||||
}
|
||||
else {
|
||||
log_error("encryption failed: %s\n", g10_errstr(result));
|
||||
}
|
||||
free_packet(pkt);
|
||||
c->last_was_pubkey_enc = 0;
|
||||
}
|
||||
@ -256,9 +258,10 @@ static void
|
||||
proc_plaintext( CTX c, PACKET *pkt )
|
||||
{
|
||||
PKT_plaintext *pt = pkt->pkt.plaintext;
|
||||
int result;
|
||||
int rc;
|
||||
|
||||
printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name);
|
||||
if( opt.verbose )
|
||||
log_info("original file name='%.*s'\n", pt->namelen, pt->name);
|
||||
free_md_filter_context( &c->mfx );
|
||||
/* fixme: take the digest algo(s) to use from the
|
||||
* onepass_sig packet (if we have these)
|
||||
@ -266,12 +269,9 @@ proc_plaintext( CTX c, PACKET *pkt )
|
||||
* textmode filter (sigclass 0x01)
|
||||
*/
|
||||
c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
|
||||
result = handle_plaintext( pt, &c->mfx );
|
||||
if( !result )
|
||||
fputs( " okay", stdout);
|
||||
else
|
||||
printf( " %s", g10_errstr(result));
|
||||
putchar('\n');
|
||||
rc = handle_plaintext( pt, &c->mfx );
|
||||
if( rc )
|
||||
log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
|
||||
free_packet(pkt);
|
||||
c->last_was_pubkey_enc = 0;
|
||||
}
|
||||
@ -281,15 +281,12 @@ static void
|
||||
proc_compressed( CTX c, PACKET *pkt )
|
||||
{
|
||||
PKT_compressed *zd = pkt->pkt.compressed;
|
||||
int result;
|
||||
int rc;
|
||||
|
||||
printf("zip: compressed data packet\n");
|
||||
result = handle_compressed( zd );
|
||||
if( !result )
|
||||
fputs( " okay", stdout);
|
||||
else
|
||||
printf( " %s", g10_errstr(result));
|
||||
putchar('\n');
|
||||
/*printf("zip: compressed data packet\n");*/
|
||||
rc = handle_compressed( zd );
|
||||
if( rc )
|
||||
log_error("uncompressing failed: %s\n", g10_errstr(rc));
|
||||
free_packet(pkt);
|
||||
c->last_was_pubkey_enc = 0;
|
||||
}
|
||||
@ -505,7 +502,6 @@ proc_packets( IOBUF a )
|
||||
u32 keyid[2];
|
||||
int newpkt;
|
||||
|
||||
c->opt_list = 1;
|
||||
c->iobuf = a;
|
||||
init_packet(pkt);
|
||||
while( (rc=parse_packet(a, pkt)) != -1 ) {
|
||||
@ -522,17 +518,27 @@ proc_packets( IOBUF a )
|
||||
continue;
|
||||
}
|
||||
newpkt = -1;
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBLIC_CERT: newpkt = add_public_cert( c, pkt ); break;
|
||||
case PKT_SECRET_CERT: newpkt = add_secret_cert( c, pkt ); break;
|
||||
case PKT_USER_ID: newpkt = add_user_id( c, pkt ); break;
|
||||
case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
|
||||
case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
|
||||
case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
|
||||
case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
|
||||
case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
|
||||
case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
|
||||
default: newpkt = 0; break;
|
||||
if( opt.list_packets ) {
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
|
||||
case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
|
||||
case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
|
||||
default: newpkt = 0; break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBLIC_CERT: newpkt = add_public_cert( c, pkt ); break;
|
||||
case PKT_SECRET_CERT: newpkt = add_secret_cert( c, pkt ); break;
|
||||
case PKT_USER_ID: newpkt = add_user_id( c, pkt ); break;
|
||||
case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
|
||||
case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
|
||||
case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
|
||||
case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
|
||||
case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
|
||||
case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
|
||||
default: newpkt = 0; break;
|
||||
}
|
||||
}
|
||||
if( pkt->pkttype != PKT_SIGNATURE )
|
||||
c->have_data = pkt->pkttype == PKT_PLAINTEXT;
|
||||
@ -575,13 +581,16 @@ proc_tree( CTX c, KBNODE node )
|
||||
KBNODE n1;
|
||||
int rc;
|
||||
|
||||
if( opt.list_packets )
|
||||
return;
|
||||
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_CERT )
|
||||
list_node( c, node );
|
||||
else if( node->pkt->pkttype == PKT_SECRET_CERT )
|
||||
list_node( c, node );
|
||||
else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
|
||||
if( !node->child )
|
||||
log_error("proc_tree: onepass_sig without followin data\n");
|
||||
log_error("proc_tree: onepass_sig without data\n");
|
||||
else if( node->child->pkt->pkttype != PKT_SIGNATURE )
|
||||
log_error("proc_tree: onepass_sig not followed by signature\n");
|
||||
else { /* check all signatures */
|
||||
@ -611,6 +620,8 @@ proc_tree( CTX c, KBNODE node )
|
||||
log_error("BAD signature from ");
|
||||
print_keyid( stderr, sig->keyid );
|
||||
putc('\n', stderr);
|
||||
if( opt.batch )
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
log_error("Can't check signature made by %08lX: %s\n",
|
||||
|
@ -35,7 +35,7 @@ struct {
|
||||
int fingerprint; /* list fingerprints */
|
||||
int list_sigs; /* list signatures */
|
||||
int no_armor;
|
||||
int reserved5;
|
||||
int list_packets; /* list-packets mode */
|
||||
int reserved6;
|
||||
int reserved7;
|
||||
int reserved8;
|
||||
|
@ -210,6 +210,7 @@ struct packet_struct {
|
||||
|
||||
/*-- mainproc.c --*/
|
||||
int proc_packets( IOBUF a );
|
||||
int list_packets( IOBUF a );
|
||||
|
||||
/*-- parse-packet.c --*/
|
||||
int set_packet_list_mode( int mode );
|
||||
|
@ -25,13 +25,27 @@
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "options.h"
|
||||
#include "ttyio.h"
|
||||
#include "cipher.h"
|
||||
#include "keydb.h"
|
||||
|
||||
static int pwfd = -1;
|
||||
|
||||
static int hash_passphrase( DEK *dek, char *pw );
|
||||
|
||||
void
|
||||
set_passphrase_fd( int fd )
|
||||
{
|
||||
pwfd = fd;
|
||||
}
|
||||
|
||||
int
|
||||
get_passphrase_fd()
|
||||
{
|
||||
return pwfd;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Get a passphrase for the secret key with KEYID, display TEXT
|
||||
@ -41,35 +55,51 @@ static int hash_passphrase( DEK *dek, char *pw );
|
||||
DEK *
|
||||
get_passphrase_hash( u32 *keyid, char *text )
|
||||
{
|
||||
char *p=NULL, *pw;
|
||||
char *pw;
|
||||
DEK *dek;
|
||||
|
||||
if( keyid ) {
|
||||
if( keyid && !opt.batch ) {
|
||||
char *ustr;
|
||||
tty_printf("\nNeed a pass phrase to unlock the secret key!\n");
|
||||
tty_printf("KeyID: " );
|
||||
tty_printf("Need a pass phrase to unlock the secret key for:\n");
|
||||
tty_printf(" \"" );
|
||||
ustr = get_user_id_string( keyid );
|
||||
tty_print_string( ustr, strlen(ustr) );
|
||||
m_free(ustr);
|
||||
tty_printf("\n\n");
|
||||
tty_printf("\"\n\n");
|
||||
|
||||
}
|
||||
if( keyid && (p=getenv("G10PASSPHRASE")) ) {
|
||||
pw = m_alloc_secure(strlen(p)+1);
|
||||
strcpy(pw,p);
|
||||
tty_printf("Taking it from $G10PASSPHRASE !\n", keyid[1] );
|
||||
if( pwfd != -1 ) { /* read the passphrase from the given descriptor */
|
||||
int i, len;
|
||||
|
||||
if( !opt.batch )
|
||||
tty_printf("Reading from file descriptor %d ...", pwfd );
|
||||
for( pw = NULL, i = len = 100; ; i++ ) {
|
||||
if( i >= len-1 ) {
|
||||
char *pw2 = pw;
|
||||
len += 100;
|
||||
pw = m_alloc_secure( len );
|
||||
if( pw2 )
|
||||
memcpy(pw, pw2, i );
|
||||
i=0;
|
||||
}
|
||||
if( read( pwfd, pw+i, 1) != 1 || pw[i] == '\n' )
|
||||
break;
|
||||
}
|
||||
pw[i] = 0;
|
||||
if( !opt.batch )
|
||||
tty_printf("\b\b\b \n" );
|
||||
}
|
||||
else
|
||||
else if( opt.batch )
|
||||
log_fatal("Can't query password in batchmode\n");
|
||||
else {
|
||||
pw = tty_get_hidden("Enter pass phrase: " );
|
||||
tty_kill_prompt();
|
||||
}
|
||||
dek = m_alloc_secure( sizeof *dek );
|
||||
dek->algo = CIPHER_ALGO_BLOWFISH;
|
||||
if( hash_passphrase( dek, pw ) )
|
||||
log_bug("get_passphrase_hash\n");
|
||||
m_free(pw); /* is allocated in secure memory, so it will be burned */
|
||||
if( !p ) {
|
||||
tty_kill_prompt();
|
||||
tty_printf("\n");
|
||||
}
|
||||
return dek;
|
||||
}
|
||||
|
||||
@ -89,6 +119,7 @@ make_dek_from_passphrase( DEK *dek, int mode )
|
||||
tty_kill_prompt();
|
||||
if( mode == 2 ) {
|
||||
pw2 = tty_get_hidden("Repeat pass phrase: " );
|
||||
tty_kill_prompt();
|
||||
if( strcmp(pw, pw2) ) {
|
||||
m_free(pw2);
|
||||
m_free(pw);
|
||||
|
@ -65,6 +65,7 @@ check_elg( PKT_secret_cert *cert )
|
||||
unsigned nbytes;
|
||||
u32 keyid[2];
|
||||
ELG_secret_key skey;
|
||||
char save_iv[8];
|
||||
|
||||
if( cert->d.elg.is_protected ) { /* remove the protection */
|
||||
DEK *dek = NULL;
|
||||
@ -80,6 +81,7 @@ check_elg( PKT_secret_cert *cert )
|
||||
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
|
||||
m_free(dek); /* pw is in secure memory, so m_free() burns it */
|
||||
blowfish_setiv( blowfish_ctx, NULL );
|
||||
memcpy(save_iv, cert->d.elg.protect.blowfish.iv, 8 );
|
||||
blowfish_decode_cfb( blowfish_ctx,
|
||||
cert->d.elg.protect.blowfish.iv,
|
||||
cert->d.elg.protect.blowfish.iv, 8 );
|
||||
@ -94,6 +96,7 @@ check_elg( PKT_secret_cert *cert )
|
||||
/* now let's see wether we have used the right passphrase */
|
||||
if( csum != cert->d.elg.csum ) {
|
||||
mpi_free(test_x);
|
||||
memcpy( cert->d.elg.protect.blowfish.iv, save_iv, 8 );
|
||||
return G10ERR_BAD_PASS;
|
||||
}
|
||||
|
||||
@ -105,6 +108,7 @@ check_elg( PKT_secret_cert *cert )
|
||||
memset( &skey, 0, sizeof skey );
|
||||
if( !res ) {
|
||||
mpi_free(test_x);
|
||||
memcpy( cert->d.elg.protect.blowfish.iv, save_iv, 8 );
|
||||
return G10ERR_BAD_PASS;
|
||||
}
|
||||
mpi_set(cert->d.elg.x, test_x);
|
||||
@ -274,6 +278,8 @@ check_secret_key( PKT_secret_cert *cert )
|
||||
#endif
|
||||
else
|
||||
rc = G10ERR_PUBKEY_ALGO;
|
||||
if( get_passphrase_fd() != -1 )
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
173
g10/sign.c
173
g10/sign.c
@ -79,6 +79,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
|
||||
compress_filter_context_t zfx;
|
||||
md_filter_context_t mfx;
|
||||
text_filter_context_t tfx;
|
||||
encrypt_filter_context_t efx;
|
||||
IOBUF inp = NULL, out = NULL;
|
||||
PACKET pkt;
|
||||
PKT_plaintext *pt = NULL;
|
||||
@ -92,6 +93,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
|
||||
memset( &zfx, 0, sizeof zfx);
|
||||
memset( &mfx, 0, sizeof mfx);
|
||||
memset( &tfx, 0, sizeof tfx);
|
||||
memset( &efx, 0, sizeof efx);
|
||||
init_packet( &pkt );
|
||||
|
||||
if( (rc=build_skc_list( locusr, &skc_list, 1 )) )
|
||||
@ -127,8 +129,9 @@ sign_file( const char *filename, int detached, STRLIST locusr,
|
||||
iobuf_push_filter( out, compress_filter, &zfx );
|
||||
|
||||
if( encrypt ) {
|
||||
/* prepare for encryption */
|
||||
/* FIXME!!!!!!! */
|
||||
efx.pkc_list = pkc_list;
|
||||
/* fixme: set efx.cfx.datalen if known */
|
||||
iobuf_push_filter( out, encrypt_filter, &efx );
|
||||
}
|
||||
|
||||
/* loop over the secret certificates and build headers */
|
||||
@ -348,7 +351,15 @@ sign_it_p( PKT_public_cert *pkc, PKT_user_id *uid )
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
/****************
|
||||
* Check the keysigs and set the flags to indicate errors.
|
||||
* Usage of nodes flag bits:
|
||||
* Bit 0 = bad signature
|
||||
* 1 = no public key
|
||||
* 2 = other error
|
||||
* Returns true if error found.
|
||||
*/
|
||||
static int
|
||||
check_all_keysigs( KBNODE keyblock )
|
||||
{
|
||||
KBNODE kbctx;
|
||||
@ -384,6 +395,7 @@ check_all_keysigs( KBNODE keyblock )
|
||||
m_free(p);
|
||||
}
|
||||
tty_printf("\n");
|
||||
/* FIXME: update the trustdb */
|
||||
}
|
||||
}
|
||||
if( inv_sigs )
|
||||
@ -392,6 +404,76 @@ check_all_keysigs( KBNODE keyblock )
|
||||
tty_printf("No public key for %d signatures\n", no_key );
|
||||
if( oth_err )
|
||||
tty_printf("%d signatures not checked due to errors\n", oth_err );
|
||||
return inv_sigs || no_key || oth_err;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Ask and remove invalid signatures are to be removed.
|
||||
*/
|
||||
static int
|
||||
remove_keysigs( KBNODE keyblock, int all )
|
||||
{
|
||||
KBNODE kbctx;
|
||||
KBNODE node;
|
||||
char *answer;
|
||||
int yes;
|
||||
int count;
|
||||
|
||||
count = 0;
|
||||
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
|
||||
if( ((node->flag & 7) || all )
|
||||
&& node->pkt->pkttype == PKT_SIGNATURE
|
||||
&& (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
|
||||
PKT_signature *sig = node->pkt->pkt.signature;
|
||||
int sigrc;
|
||||
|
||||
if( all ) {
|
||||
/* fixme: skip self-sig */
|
||||
}
|
||||
|
||||
tty_printf("\n \"%08lX %s ",
|
||||
sig->keyid[1], datestr_from_sig(sig));
|
||||
if( node->flag & 6 )
|
||||
tty_printf("[User name not available] ");
|
||||
else {
|
||||
size_t n;
|
||||
char *p = get_user_id( sig->keyid, &n );
|
||||
tty_print_string( p, n );
|
||||
m_free(p);
|
||||
}
|
||||
tty_printf("\"\n");
|
||||
if( node->flag & 1 )
|
||||
tty_printf("This is a BAD signature!\n");
|
||||
else if( node->flag & 2 )
|
||||
tty_printf("Public key not available.\n");
|
||||
else if( node->flag & 4 )
|
||||
tty_printf("The signature could not be checked!\n");
|
||||
answer = tty_get("\nRemove this signature? ");
|
||||
tty_kill_prompt();
|
||||
if( answer_is_yes(answer) ) {
|
||||
node->flag |= 128; /* use bit 7 to mark this node */
|
||||
count++;
|
||||
}
|
||||
m_free(answer);
|
||||
}
|
||||
}
|
||||
|
||||
if( !count )
|
||||
return 0; /* nothing to remove */
|
||||
answer = tty_get("Do you really want to remove the selected signatures? ");
|
||||
tty_kill_prompt();
|
||||
yes = answer_is_yes(answer);
|
||||
m_free(answer);
|
||||
if( !yes )
|
||||
return 0;
|
||||
|
||||
for( kbctx=NULL; (node=walk_kbtree2( keyblock, &kbctx, 1)) ; ) {
|
||||
if( node->flag & 128)
|
||||
delete_kbnode( keyblock, node );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -414,6 +496,7 @@ sign_key( const char *username, STRLIST locusr )
|
||||
PKT_public_cert *pkc;
|
||||
int any;
|
||||
u32 pkc_keyid[2];
|
||||
char *answer;
|
||||
|
||||
memset( &mfx, 0, sizeof mfx);
|
||||
|
||||
@ -464,9 +547,16 @@ sign_key( const char *username, STRLIST locusr )
|
||||
}
|
||||
|
||||
clear_kbnode_flags( keyblock );
|
||||
check_all_keysigs( keyblock );
|
||||
/* look wether we should ask to remove invalid keys */
|
||||
/*+ FIXME: */
|
||||
if( check_all_keysigs( keyblock ) ) {
|
||||
if( !opt.batch ) {
|
||||
/* ask wether we really should do anything */
|
||||
answer = tty_get("To you want to remove some of the invalid sigs? ");
|
||||
tty_kill_prompt();
|
||||
if( answer_is_yes(answer) )
|
||||
remove_keysigs( keyblock, 0 );
|
||||
m_free(answer);
|
||||
}
|
||||
}
|
||||
|
||||
/* check wether we have already signed it */
|
||||
for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) {
|
||||
@ -524,7 +614,7 @@ sign_key( const char *username, STRLIST locusr )
|
||||
|
||||
rc = update_keyblock( &kbpos, keyblock );
|
||||
if( rc ) {
|
||||
log_error("insert_keyblock failed: %s\n", g10_errstr(rc) );
|
||||
log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -537,6 +627,75 @@ sign_key( const char *username, STRLIST locusr )
|
||||
|
||||
|
||||
|
||||
int
|
||||
edit_keysigs( const char *username )
|
||||
{
|
||||
int rc = 0;
|
||||
KBNODE keyblock = NULL;
|
||||
KBNODE kbctx, node;
|
||||
KBPOS kbpos;
|
||||
PKT_public_cert *pkc;
|
||||
int any;
|
||||
u32 pkc_keyid[2];
|
||||
char *answer;
|
||||
|
||||
/* search the userid */
|
||||
rc = search_keyblock_byname( &kbpos, username );
|
||||
if( rc ) {
|
||||
log_error("user '%s' not found\n", username );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* read the keyblock */
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
log_error("error reading the certificate: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* get the keyid from the keyblock */
|
||||
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_CERT )
|
||||
break;
|
||||
}
|
||||
if( !node ) {
|
||||
log_error("Oops; public key not found anymore!\n");
|
||||
rc = G10ERR_GENERAL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
pkc = node->pkt->pkt.public_cert;
|
||||
keyid_from_pkc( pkc, pkc_keyid );
|
||||
log_info("Checking signatures of this public key certificate:\n");
|
||||
tty_printf("pub %4u%c/%08lX %s ",
|
||||
nbits_from_pkc( pkc ),
|
||||
pubkey_letter( pkc->pubkey_algo ),
|
||||
pkc_keyid[1], datestr_from_pkc(pkc) );
|
||||
{
|
||||
size_t n;
|
||||
char *p = get_user_id( pkc_keyid, &n );
|
||||
tty_print_string( p, n > 40? 40 : n );
|
||||
m_free(p);
|
||||
tty_printf("\n");
|
||||
}
|
||||
|
||||
clear_kbnode_flags( keyblock );
|
||||
check_all_keysigs( keyblock );
|
||||
if( remove_keysigs( keyblock, 1 ) ) {
|
||||
rc = update_keyblock( &kbpos, keyblock );
|
||||
if( rc ) {
|
||||
log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
release_kbnode( keyblock );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Create a signature packet for the given public key certificate
|
||||
* and the user id and return it in ret_sig. User signature class SIGCLASS
|
||||
|
35
g10/trustdb.c
Normal file
35
g10/trustdb.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* trustdb.c
|
||||
* Copyright (c) 1997 by Werner Koch (dd9jn)
|
||||
*
|
||||
* This file is part of G10.
|
||||
*
|
||||
* G10 is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* G10 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
|
@ -56,7 +56,8 @@ typedef struct {
|
||||
} ARGPARSE_OPTS;
|
||||
|
||||
/*-- logger.c --*/
|
||||
void set_log_pid( int pid );
|
||||
void log_set_pid( int pid );
|
||||
int log_get_errorcount( int clear );
|
||||
void printstr( int level, const char *fmt, ... );
|
||||
void log_bug( const char *fmt, ... );
|
||||
void log_fatal( const char *fmt, ... );
|
||||
|
@ -450,6 +450,7 @@ iobuf_push_filter( IOBUF a,
|
||||
/* remove the filter stuff from the new stream */
|
||||
a->filter = NULL;
|
||||
a->filter_ov = NULL;
|
||||
a->filter_eof = 0;
|
||||
if( a->usage == 2 ) { /* allocate a fresh buffer for the original stream */
|
||||
b->d.buf = m_alloc( a->d.size );
|
||||
b->d.len = 0;
|
||||
@ -539,7 +540,7 @@ iobuf_pop_filter( IOBUF a, int (*f)(void *opaque, int control,
|
||||
m_free(b);
|
||||
}
|
||||
else if( !b->chain ) { /* remove the last iobuf from the chain */
|
||||
log_bug("Ohh jeee, trying to a head filter\n");
|
||||
log_bug("Ohh jeee, trying to remove a head filter\n");
|
||||
}
|
||||
else { /* remove an intermediate iobuf from the chain */
|
||||
log_bug("Ohh jeee, trying to remove an intermediate filter\n");
|
||||
@ -833,13 +834,13 @@ iobuf_set_block_mode( IOBUF a, size_t n )
|
||||
|
||||
|
||||
/****************
|
||||
* checks wether the stream is in block mode
|
||||
* Checks wether the stream is in block mode
|
||||
* Note: This does not work if other filters are pushed on the stream.
|
||||
*/
|
||||
int
|
||||
iobuf_in_block_mode( IOBUF a )
|
||||
{
|
||||
for(; a; a = a->chain )
|
||||
if( a->filter == block_filter )
|
||||
if( a && a->filter == block_filter )
|
||||
return 1; /* yes */
|
||||
return 0; /* no */
|
||||
}
|
||||
|
@ -26,10 +26,10 @@
|
||||
#include "util.h"
|
||||
|
||||
static char pidstring[15];
|
||||
|
||||
static int errorcount;
|
||||
|
||||
void
|
||||
set_log_pid( int pid )
|
||||
log_set_pid( int pid )
|
||||
{
|
||||
if( pid )
|
||||
sprintf(pidstring,"[%u]", (unsigned)pid );
|
||||
@ -37,6 +37,15 @@ set_log_pid( int pid )
|
||||
*pidstring = 0;
|
||||
}
|
||||
|
||||
int
|
||||
log_get_errorcount( int clear)
|
||||
{
|
||||
int n = errorcount;
|
||||
if( clear )
|
||||
errorcount = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* General interface for printing a line
|
||||
@ -90,6 +99,7 @@ log_error( const char *fmt, ... )
|
||||
va_start( arg_ptr, fmt ) ;
|
||||
vfprintf(stderr,fmt,arg_ptr) ;
|
||||
va_end(arg_ptr);
|
||||
errorcount++;
|
||||
}
|
||||
|
||||
void
|
||||
|
106
util/ttyio.c
106
util/ttyio.c
@ -30,41 +30,19 @@
|
||||
#include "memory.h"
|
||||
#include "ttyio.h"
|
||||
|
||||
static FILE *ttyfp = NULL;
|
||||
static int last_prompt_len;
|
||||
|
||||
static FILE *
|
||||
open_tty(struct termios *termsave )
|
||||
{
|
||||
struct termios term;
|
||||
|
||||
FILE *tty = fopen("/dev/tty", "r");
|
||||
if( !tty )
|
||||
log_fatal("cannot open /dev/tty: %s\n", strerror(errno) );
|
||||
|
||||
if( termsave ) { /* hide input */
|
||||
if( tcgetattr(fileno(tty), termsave) )
|
||||
log_fatal("tcgetattr() failed: %s\n", strerror(errno) );
|
||||
term = *termsave;
|
||||
term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
if( tcsetattr( fileno(tty), TCSAFLUSH, &term ) )
|
||||
log_fatal("tcsetattr() failed: %s\n", strerror(errno) );
|
||||
}
|
||||
|
||||
|
||||
return tty;
|
||||
}
|
||||
|
||||
static void
|
||||
close_tty( FILE *tty, struct termios *termsave )
|
||||
init_ttyfp()
|
||||
{
|
||||
if( termsave ) {
|
||||
if( tcsetattr(fileno(tty), TCSAFLUSH, termsave) )
|
||||
log_error("tcsetattr() failed: %s\n", strerror(errno) );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
fclose(tty);
|
||||
}
|
||||
if( ttyfp )
|
||||
return;
|
||||
|
||||
ttyfp = fopen("/dev/tty", "r+");
|
||||
if( !ttyfp )
|
||||
log_fatal("cannot open /dev/tty: %s\n", strerror(errno) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
@ -72,10 +50,13 @@ tty_printf( const char *fmt, ... )
|
||||
{
|
||||
va_list arg_ptr;
|
||||
|
||||
if( !ttyfp )
|
||||
init_ttyfp();
|
||||
|
||||
va_start( arg_ptr, fmt ) ;
|
||||
last_prompt_len += vfprintf(stderr,fmt,arg_ptr) ;
|
||||
last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ;
|
||||
va_end(arg_ptr);
|
||||
fflush(stderr);
|
||||
fflush(ttyfp);
|
||||
}
|
||||
|
||||
|
||||
@ -85,18 +66,21 @@ tty_printf( const char *fmt, ... )
|
||||
void
|
||||
tty_print_string( byte *p, size_t n )
|
||||
{
|
||||
if( !ttyfp )
|
||||
init_ttyfp();
|
||||
|
||||
for( ; n; n--, p++ )
|
||||
if( iscntrl( *p ) ) {
|
||||
putc('\\', stderr);
|
||||
putc('\\', ttyfp);
|
||||
if( *p == '\n' )
|
||||
putc('n', stderr);
|
||||
putc('n', ttyfp);
|
||||
else if( !*p )
|
||||
putc('0', stderr);
|
||||
putc('0', ttyfp);
|
||||
else
|
||||
fprintf(stderr, "x%02x", *p );
|
||||
fprintf(ttyfp, "x%02x", *p );
|
||||
}
|
||||
else
|
||||
putc(*p, stderr);
|
||||
putc(*p, ttyfp);
|
||||
}
|
||||
|
||||
|
||||
@ -107,17 +91,36 @@ static char *
|
||||
do_get( const char *prompt, int hidden )
|
||||
{
|
||||
char *buf;
|
||||
byte cbuf[1];
|
||||
int c, n, i;
|
||||
FILE *fp;
|
||||
struct termios termsave;
|
||||
|
||||
if( !ttyfp )
|
||||
init_ttyfp();
|
||||
|
||||
last_prompt_len = 0;
|
||||
tty_printf( prompt );
|
||||
buf = m_alloc(n=50);
|
||||
i = 0;
|
||||
fp = open_tty(hidden? &termsave: NULL);
|
||||
while( (c=getc(fp)) != EOF && c != '\n' ) {
|
||||
last_prompt_len++;
|
||||
|
||||
if( hidden ) {
|
||||
struct termios term;
|
||||
|
||||
if( tcgetattr(fileno(ttyfp), &termsave) )
|
||||
log_fatal("tcgetattr() failed: %s\n", strerror(errno) );
|
||||
term = termsave;
|
||||
term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
if( tcsetattr( fileno(ttyfp), TCSAFLUSH, &term ) )
|
||||
log_fatal("tcsetattr() failed: %s\n", strerror(errno) );
|
||||
}
|
||||
|
||||
/* fixme: How can we avoid that the \n is echoed w/o disabling
|
||||
* canonical mode - w/o this kill_prompt can't work */
|
||||
while( read(fileno(ttyfp), cbuf, 1) == 1 && *cbuf != '\n' ) {
|
||||
if( !hidden )
|
||||
last_prompt_len++;
|
||||
c = *cbuf;
|
||||
if( c == '\t' )
|
||||
c = ' ';
|
||||
else if( iscntrl(c) )
|
||||
@ -128,7 +131,11 @@ do_get( const char *prompt, int hidden )
|
||||
}
|
||||
buf[i++] = c;
|
||||
}
|
||||
close_tty(fp, hidden? &termsave: NULL);
|
||||
|
||||
if( hidden ) {
|
||||
if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) )
|
||||
log_error("tcsetattr() failed: %s\n", strerror(errno) );
|
||||
}
|
||||
buf[i] = 0;
|
||||
return buf;
|
||||
}
|
||||
@ -151,15 +158,16 @@ void
|
||||
tty_kill_prompt()
|
||||
{
|
||||
int i;
|
||||
#if 0
|
||||
|
||||
if( !ttyfp )
|
||||
init_ttyfp();
|
||||
if( !last_prompt_len )
|
||||
return;
|
||||
fputc('\r', ttyfp);
|
||||
for(i=0; i < last_prompt_len; i ++ )
|
||||
fputc('\b', stderr);
|
||||
for(i=0; i < last_prompt_len; i ++ )
|
||||
fputc(' ', stderr);
|
||||
for(i=0; i < last_prompt_len; i ++ )
|
||||
fputc('\b', stderr);
|
||||
#endif
|
||||
fputc(' ', ttyfp);
|
||||
fputc('\r', ttyfp);
|
||||
last_prompt_len = 0;
|
||||
fflush(stderr);
|
||||
fflush(ttyfp);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user