mirror of
git://git.gnupg.org/gnupg.git
synced 2024-11-10 21:38:50 +01:00
added more stuff
This commit is contained in:
parent
4d2636eafe
commit
b7bdef0834
84
README
84
README
@ -51,7 +51,6 @@
|
|||||||
|
|
||||||
Key Generation
|
Key Generation
|
||||||
--------------
|
--------------
|
||||||
Create a key pair with this command:
|
|
||||||
|
|
||||||
g10 --gen-key
|
g10 --gen-key
|
||||||
|
|
||||||
@ -59,7 +58,7 @@
|
|||||||
good random numbers for prime number generation, it uses a /dev/random
|
good random numbers for prime number generation, it uses a /dev/random
|
||||||
which will emit only bytes if the kernel can gather enough entropy.
|
which will emit only bytes if the kernel can gather enough entropy.
|
||||||
If you see no progress, you should start some other activities such
|
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.
|
to generate random we have to use this method.
|
||||||
|
|
||||||
Key generation shows progress by printing different characters to
|
Key generation shows progress by printing different characters to
|
||||||
@ -89,9 +88,25 @@
|
|||||||
9) Find a generator for that prime.
|
9) Find a generator for that prime.
|
||||||
|
|
||||||
|
|
||||||
Signatures
|
You can sign a key with this command:
|
||||||
----------
|
|
||||||
To create a signature, use this:
|
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
|
g10 -s file
|
||||||
|
|
||||||
@ -106,9 +121,9 @@
|
|||||||
|
|
||||||
Creates a signature of file, but writes the output to the file "out".
|
Creates a signature of file, but writes the output to the file "out".
|
||||||
|
|
||||||
Encryption
|
|
||||||
----------
|
Encrypt
|
||||||
To encrypt data use this:
|
-------
|
||||||
|
|
||||||
g10 -e -r heine file
|
g10 -e -r heine file
|
||||||
|
|
||||||
@ -120,6 +135,51 @@
|
|||||||
Ditto, but encrypts "hallo\n" and mails it as ascii armored message.
|
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
|
Debug Flags
|
||||||
-----------
|
-----------
|
||||||
Use the option "--debug n" to output debug informations. This option
|
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,
|
I will run "indent" over the source when making a real distribution,
|
||||||
but for now I stick to my own formatting rules.
|
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 FTP site is "ftp://ftp.guug.de/pub/gcrypt/"
|
||||||
The primary WWW page is "http://www.d.shuttle.de/isil/g10.html"
|
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
|
Please direct bug reports to <g10-bugs@isil.d.shuttle.de> or better
|
||||||
post them to the mailing list <g10@net.lut.ac.uk>.
|
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
|
before we can check wether we have the pubkey or not. The one-pass
|
||||||
signature packets should be implemented to avoid this.
|
signature packets should be implemented to avoid this.
|
||||||
|
|
||||||
* compress does not work always!
|
|
||||||
* complete cipher/cast.c
|
* complete cipher/cast.c
|
||||||
* complete cipher/dsa.c
|
* complete cipher/dsa.c
|
||||||
|
|
||||||
@ -34,3 +33,5 @@
|
|||||||
of the userid.
|
of the userid.
|
||||||
[can be handles in get_pubkey_by_name()]
|
[can be handles in get_pubkey_by_name()]
|
||||||
|
|
||||||
|
* armor has now some problems.
|
||||||
|
|
||||||
|
@ -21,9 +21,12 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
@ -98,6 +101,7 @@ fill_buffer( byte *buffer, size_t length, int level )
|
|||||||
static int fd_random = -1;
|
static int fd_random = -1;
|
||||||
int fd;
|
int fd;
|
||||||
int n;
|
int n;
|
||||||
|
int warn=0;
|
||||||
|
|
||||||
if( level == 2 ) {
|
if( level == 2 ) {
|
||||||
if( fd_random == -1 )
|
if( fd_random == -1 )
|
||||||
@ -112,11 +116,34 @@ fill_buffer( byte *buffer, size_t length, int level )
|
|||||||
|
|
||||||
|
|
||||||
do {
|
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 {
|
do {
|
||||||
n = read(fd, buffer, length );
|
n = read(fd, buffer, length );
|
||||||
} while( n == -1 && errno == EINTR );
|
} while( n == -1 && errno == EINTR );
|
||||||
if( n == -1 )
|
if( n == -1 )
|
||||||
log_fatal("read error on random device: %s\n", strerror(errno) );
|
log_fatal("read error on random device: %s\n", strerror(errno) );
|
||||||
|
assert( n <= length );
|
||||||
buffer += n;
|
buffer += n;
|
||||||
length -= n;
|
length -= n;
|
||||||
} while( length );
|
} while( length );
|
||||||
|
@ -30,6 +30,7 @@ g10_SOURCES = g10.c \
|
|||||||
options.h \
|
options.h \
|
||||||
openfile.c \
|
openfile.c \
|
||||||
keyid.c \
|
keyid.c \
|
||||||
|
trustdb.c \
|
||||||
packet.h \
|
packet.h \
|
||||||
parse-packet.c \
|
parse-packet.c \
|
||||||
passphrase.c \
|
passphrase.c \
|
||||||
|
@ -68,6 +68,7 @@ g10_SOURCES = g10.c \
|
|||||||
options.h \
|
options.h \
|
||||||
openfile.c \
|
openfile.c \
|
||||||
keyid.c \
|
keyid.c \
|
||||||
|
trustdb.c \
|
||||||
packet.h \
|
packet.h \
|
||||||
parse-packet.c \
|
parse-packet.c \
|
||||||
passphrase.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 \
|
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 \
|
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 \
|
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 \
|
openfile.o keyid.o trustdb.o parse-packet.o passphrase.o plaintext.o \
|
||||||
seckey-cert.o seskey.o sign.o comment.o sig-check.o
|
pubkey-enc.o seckey-cert.o seskey.o sign.o comment.o sig-check.o
|
||||||
EXTRA_g10_SOURCES =
|
EXTRA_g10_SOURCES =
|
||||||
g10_LDADD = $(LDADD)
|
g10_LDADD = $(LDADD)
|
||||||
DIST_COMMON = Makefile.am Makefile.in
|
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/ringedit.P $(srcdir)/.deps/rsa.P \
|
||||||
$(srcdir)/.deps/seckey-cert.P $(srcdir)/.deps/seskey.P \
|
$(srcdir)/.deps/seckey-cert.P $(srcdir)/.deps/seskey.P \
|
||||||
$(srcdir)/.deps/sig-check.P $(srcdir)/.deps/sign.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)
|
SOURCES = $(g10_SOURCES)
|
||||||
OBJECTS = $(g10_OBJECTS)
|
OBJECTS = $(g10_OBJECTS)
|
||||||
|
|
||||||
|
86
g10/encode.c
86
g10/encode.c
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
|
|
||||||
static int encode_simple( const char *filename, int mode );
|
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;
|
cipher_filter_context_t cfx;
|
||||||
armor_filter_context_t afx;
|
armor_filter_context_t afx;
|
||||||
compress_filter_context_t zfx;
|
compress_filter_context_t zfx;
|
||||||
PKC_LIST pkc_list, pkc_rover;
|
PKC_LIST pkc_list;
|
||||||
|
|
||||||
memset( &cfx, 0, sizeof cfx);
|
memset( &cfx, 0, sizeof cfx);
|
||||||
memset( &afx, 0, sizeof afx);
|
memset( &afx, 0, sizeof afx);
|
||||||
@ -203,31 +204,9 @@ encode_crypt( const char *filename, STRLIST remusr )
|
|||||||
if( DBG_CIPHER )
|
if( DBG_CIPHER )
|
||||||
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
|
||||||
|
|
||||||
/* loop over all public key certificates */
|
rc = write_pubkey_enc_from_list( pkc_list, cfx.dek, out );
|
||||||
for( pkc_rover=pkc_list; pkc_rover; pkc_rover = pkc_rover->next ) {
|
if( rc )
|
||||||
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;
|
goto leave;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* setup the inner packet */
|
/* setup the inner packet */
|
||||||
if( filename ) {
|
if( filename ) {
|
||||||
@ -276,7 +255,6 @@ encode_crypt( const char *filename, STRLIST remusr )
|
|||||||
/****************
|
/****************
|
||||||
* Filter to do a complete public key encryption.
|
* Filter to do a complete public key encryption.
|
||||||
*/
|
*/
|
||||||
#if 0
|
|
||||||
int
|
int
|
||||||
encrypt_filter( void *opaque, int control,
|
encrypt_filter( void *opaque, int control,
|
||||||
IOBUF a, byte *buf, size_t *ret_len)
|
IOBUF a, byte *buf, size_t *ret_len)
|
||||||
@ -289,6 +267,24 @@ encrypt_filter( void *opaque, int control,
|
|||||||
log_bug(NULL); /* not used */
|
log_bug(NULL); /* not used */
|
||||||
}
|
}
|
||||||
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
|
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 ) {
|
else if( control == IOBUFCTRL_FREE ) {
|
||||||
}
|
}
|
||||||
@ -297,5 +293,41 @@ encrypt_filter( void *opaque, int control,
|
|||||||
}
|
}
|
||||||
return rc;
|
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;
|
} cipher_filter_context_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t linesize;
|
size_t linesize;
|
||||||
byte *line;
|
byte *line;
|
||||||
@ -73,6 +74,9 @@ typedef struct {
|
|||||||
int eof;
|
int eof;
|
||||||
} text_filter_context_t;
|
} text_filter_context_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* encrypt_filter_context_t defined in main.h */
|
||||||
|
|
||||||
/*-- mdfilter.c --*/
|
/*-- mdfilter.c --*/
|
||||||
int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len);
|
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 );
|
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" },
|
{ 'e', "encrypt", 0, "encrypt data" },
|
||||||
{ 'd', "decrypt", 0, "decrypt data (default)" },
|
{ 'd', "decrypt", 0, "decrypt data (default)" },
|
||||||
/*{ 'c', "check", 0, "check a signature (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" },
|
{ 'r', "remote-user", 2, "use this user-id for encryption" },
|
||||||
{ 510, "debug" ,4|16, "set debugging flags" },
|
{ 510, "debug" ,4|16, "set debugging flags" },
|
||||||
{ 511, "debug-all" ,0, "enable full debugging"},
|
{ 511, "debug-all" ,0, "enable full debugging"},
|
||||||
@ -135,13 +135,17 @@ main( int argc, char **argv )
|
|||||||
{ 518, "options" , 2, "read options from file" },
|
{ 518, "options" , 2, "read options from file" },
|
||||||
{ 519, "no-armor", 0, "\r"},
|
{ 519, "no-armor", 0, "\r"},
|
||||||
{ 520, "no-default-keyring", 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} };
|
{0} };
|
||||||
ARGPARSE_ARGS pargs;
|
ARGPARSE_ARGS pargs;
|
||||||
IOBUF a;
|
IOBUF a;
|
||||||
int rc;
|
int rc;
|
||||||
enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
|
enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
|
||||||
aTest, aPrintMDs, aSignKey, aClearsig
|
aTest, aPrintMDs, aSignKey, aClearsig, aListPackets, aEditSig,
|
||||||
} action = aNull;
|
} action = aNull;
|
||||||
int orig_argc;
|
int orig_argc;
|
||||||
char **orig_argv;
|
char **orig_argv;
|
||||||
@ -158,9 +162,10 @@ main( int argc, char **argv )
|
|||||||
int default_config =1;
|
int default_config =1;
|
||||||
int errors=0;
|
int errors=0;
|
||||||
int default_keyring = 1;
|
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 */
|
/* check wether we have a config file on the commandline */
|
||||||
orig_argc = argc;
|
orig_argc = argc;
|
||||||
@ -221,7 +226,7 @@ main( int argc, char **argv )
|
|||||||
/* fall trough */
|
/* fall trough */
|
||||||
case 's': action = action == aEncr? aSignEncr : aSign; break;
|
case 's': action = action == aEncr? aSignEncr : aSign; break;
|
||||||
case 't': action = aClearsig; 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));
|
sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
|
||||||
strcpy(sl->d, pargs.r.ret_str);
|
strcpy(sl->d, pargs.r.ret_str);
|
||||||
sl->next = locusr;
|
sl->next = locusr;
|
||||||
@ -233,7 +238,7 @@ main( int argc, char **argv )
|
|||||||
sl->next = remusr;
|
sl->next = remusr;
|
||||||
remusr = sl;
|
remusr = sl;
|
||||||
break;
|
break;
|
||||||
case 500: opt.batch = 1; break;
|
case 500: opt.batch = 1; greeting = 0; break;
|
||||||
case 501: opt.answer_yes = 1; break;
|
case 501: opt.answer_yes = 1; break;
|
||||||
case 502: opt.answer_no = 1; break;
|
case 502: opt.answer_no = 1; break;
|
||||||
case 503: action = aKeygen; break;
|
case 503: action = aKeygen; break;
|
||||||
@ -259,6 +264,10 @@ main( int argc, char **argv )
|
|||||||
break;
|
break;
|
||||||
case 519: opt.no_armor=1; opt.armor=0; break;
|
case 519: opt.no_armor=1; opt.armor=0; break;
|
||||||
case 520: default_keyring = 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;
|
default : errors++; pargs.err = configfp? 1:2; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -275,11 +284,11 @@ main( int argc, char **argv )
|
|||||||
set_debug();
|
set_debug();
|
||||||
if( opt.verbose > 1 )
|
if( opt.verbose > 1 )
|
||||||
set_packet_list_mode(1);
|
set_packet_list_mode(1);
|
||||||
if( opt.verbose && isatty(fileno(stdin)) ) {
|
if( greeting ) {
|
||||||
if( *(s=strusage(10)) )
|
if( *(s=strusage(10)) )
|
||||||
fputs(s, stderr);
|
tty_printf("%s", s);
|
||||||
if( *(s=strusage(30)) )
|
if( *(s=strusage(30)) )
|
||||||
fputs(s, stderr);
|
tty_printf("%s", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !sec_nrings || default_keyring ) { /* add default secret rings */
|
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) );
|
log_error("sign_key('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||||
break;
|
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:
|
case aPrimegen:
|
||||||
if( argc == 1 ) {
|
if( argc == 1 ) {
|
||||||
@ -388,6 +405,8 @@ main( int argc, char **argv )
|
|||||||
|
|
||||||
case aTest: do_test( argc? atoi(*argv): 0 ); break;
|
case aTest: do_test( argc? atoi(*argv): 0 ); break;
|
||||||
|
|
||||||
|
case aListPackets:
|
||||||
|
opt.list_packets=1;
|
||||||
default:
|
default:
|
||||||
if( argc > 1 )
|
if( argc > 1 )
|
||||||
usage(1);
|
usage(1);
|
||||||
@ -398,6 +417,10 @@ main( int argc, char **argv )
|
|||||||
memset( &afx, 0, sizeof afx);
|
memset( &afx, 0, sizeof afx);
|
||||||
iobuf_push_filter( a, armor_filter, &afx );
|
iobuf_push_filter( a, armor_filter, &afx );
|
||||||
}
|
}
|
||||||
|
if( action == aListPackets ) {
|
||||||
|
set_packet_list_mode(1);
|
||||||
|
opt.list_packets=1;
|
||||||
|
}
|
||||||
proc_packets( a );
|
proc_packets( a );
|
||||||
iobuf_close(a);
|
iobuf_close(a);
|
||||||
break;
|
break;
|
||||||
@ -406,7 +429,7 @@ main( int argc, char **argv )
|
|||||||
/* cleanup */
|
/* cleanup */
|
||||||
FREE_STRLIST(remusr);
|
FREE_STRLIST(remusr);
|
||||||
FREE_STRLIST(locusr);
|
FREE_STRLIST(locusr);
|
||||||
return 0;
|
return log_get_errorcount(0)? 2:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -509,33 +532,5 @@ do_test(int times)
|
|||||||
|
|
||||||
m_check(NULL);
|
m_check(NULL);
|
||||||
#endif
|
#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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
21
g10/kbnode.c
21
g10/kbnode.c
@ -38,6 +38,7 @@ new_kbnode( PACKET *pkt )
|
|||||||
n->pkt = pkt;
|
n->pkt = pkt;
|
||||||
n->child = NULL;
|
n->child = NULL;
|
||||||
n->flag = 0;
|
n->flag = 0;
|
||||||
|
n->private_flag=0; /* kludge to delete a node */
|
||||||
return n;
|
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!
|
* Append NODE to ROOT, ROOT must exist!
|
||||||
*/
|
*/
|
||||||
@ -115,9 +126,16 @@ find_kbparent( KBNODE root, KBNODE node )
|
|||||||
*/
|
*/
|
||||||
KBNODE
|
KBNODE
|
||||||
walk_kbtree( KBNODE root, KBNODE *context )
|
walk_kbtree( KBNODE root, KBNODE *context )
|
||||||
|
{
|
||||||
|
return walk_kbtree2( root, context, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
KBNODE
|
||||||
|
walk_kbtree2( KBNODE root, KBNODE *context, int all )
|
||||||
{
|
{
|
||||||
KBNODE n;
|
KBNODE n;
|
||||||
|
|
||||||
|
do {
|
||||||
if( !*context ) {
|
if( !*context ) {
|
||||||
*context = root;
|
*context = root;
|
||||||
return root;
|
return root;
|
||||||
@ -136,6 +154,8 @@ walk_kbtree( KBNODE root, KBNODE *context )
|
|||||||
n = n->next;
|
n = n->next;
|
||||||
*context = n;
|
*context = n;
|
||||||
}
|
}
|
||||||
|
} while( !all && n && (n->private_flag & 1) );
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,3 +167,4 @@ clear_kbnode_flags( KBNODE n )
|
|||||||
n->flag = 0;
|
n->flag = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ struct kbnode_struct {
|
|||||||
KBNODE next; /* used to form a link list */
|
KBNODE next; /* used to form a link list */
|
||||||
KBNODE child;
|
KBNODE child;
|
||||||
int flag;
|
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 );
|
int build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock );
|
||||||
|
|
||||||
/*-- passphrase.h --*/
|
/*-- passphrase.h --*/
|
||||||
|
void set_passphrase_fd( int fd );
|
||||||
|
int get_passphrase_fd(void);
|
||||||
DEK *get_passphrase_hash( u32 *keyid, char *text );
|
DEK *get_passphrase_hash( u32 *keyid, char *text );
|
||||||
int make_dek_from_passphrase( DEK *dek, int mode );
|
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.c --*/
|
||||||
KBNODE new_kbnode( PACKET *pkt );
|
KBNODE new_kbnode( PACKET *pkt );
|
||||||
void release_kbnode( KBNODE n );
|
void release_kbnode( KBNODE n );
|
||||||
|
void delete_kbnode( KBNODE root, KBNODE node );
|
||||||
void add_kbnode( KBNODE root, KBNODE node );
|
void add_kbnode( KBNODE root, KBNODE node );
|
||||||
void add_kbnode_as_child( KBNODE root, KBNODE node );
|
void add_kbnode_as_child( KBNODE root, KBNODE node );
|
||||||
KBNODE find_kbparent( KBNODE root, KBNODE node );
|
KBNODE find_kbparent( KBNODE root, KBNODE node );
|
||||||
KBNODE walk_kbtree( KBNODE root, KBNODE *context );
|
KBNODE walk_kbtree( KBNODE root, KBNODE *context );
|
||||||
|
KBNODE walk_kbtree2( KBNODE root, KBNODE *context, int all );
|
||||||
void clear_kbnode_flags( KBNODE n );
|
void clear_kbnode_flags( KBNODE n );
|
||||||
|
|
||||||
/*-- ringedit.c --*/
|
/*-- ringedit.c --*/
|
||||||
|
@ -155,7 +155,7 @@ datestr_from_pkc( PKT_public_cert *pkc )
|
|||||||
time_t atime = pkc->timestamp;
|
time_t atime = pkc->timestamp;
|
||||||
|
|
||||||
tp = gmtime( &atime );
|
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;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ datestr_from_skc( PKT_secret_cert *skc )
|
|||||||
time_t atime = skc->timestamp;
|
time_t atime = skc->timestamp;
|
||||||
|
|
||||||
tp = gmtime( &atime );
|
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;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ datestr_from_sig( PKT_signature *sig )
|
|||||||
time_t atime = sig->timestamp;
|
time_t atime = sig->timestamp;
|
||||||
|
|
||||||
tp = gmtime( &atime );
|
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;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
g10/main.h
12
g10/main.h
@ -28,15 +28,27 @@
|
|||||||
#define DEFAULT_PUBKEY_ALGO PUBKEY_ALGO_ELGAMAL
|
#define DEFAULT_PUBKEY_ALGO PUBKEY_ALGO_ELGAMAL
|
||||||
#define DEFAULT_DIGEST_ALGO DIGEST_ALGO_RMD160
|
#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 --*/
|
/*-- encode.c --*/
|
||||||
int encode_symmetric( const char *filename );
|
int encode_symmetric( const char *filename );
|
||||||
int encode_store( const char *filename );
|
int encode_store( const char *filename );
|
||||||
int encode_crypt( const char *filename, STRLIST remusr );
|
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 --*/
|
/*-- sign.c --*/
|
||||||
int sign_file( const char *filename, int detached, STRLIST locusr,
|
int sign_file( const char *filename, int detached, STRLIST locusr,
|
||||||
int encrypt, STRLIST remusr );
|
int encrypt, STRLIST remusr );
|
||||||
int sign_key( const char *username, STRLIST locusr );
|
int sign_key( const char *username, STRLIST locusr );
|
||||||
|
int edit_keysigs( const char *username );
|
||||||
|
|
||||||
/*-- sig-check.c --*/
|
/*-- sig-check.c --*/
|
||||||
int check_key_signature( KBNODE root, KBNODE node );
|
int check_key_signature( KBNODE root, KBNODE node );
|
||||||
|
@ -46,7 +46,6 @@ typedef struct {
|
|||||||
md_filter_context_t mfx;
|
md_filter_context_t mfx;
|
||||||
DEK *dek;
|
DEK *dek;
|
||||||
int last_was_pubkey_enc;
|
int last_was_pubkey_enc;
|
||||||
int opt_list;
|
|
||||||
KBNODE cert; /* the current certificate */
|
KBNODE cert; /* the current certificate */
|
||||||
int have_data;
|
int have_data;
|
||||||
IOBUF iobuf; /* used to get the filename etc. */
|
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;
|
c->last_was_pubkey_enc = 1;
|
||||||
enc = pkt->pkt.pubkey_enc;
|
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
|
if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
|
||||||
|| enc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
|| enc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||||
m_free(c->dek ); /* paranoid: delete a pending DEK */
|
m_free(c->dek ); /* paranoid: delete a pending DEK */
|
||||||
@ -213,11 +212,12 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
|
|||||||
|
|
||||||
if( result == -1 )
|
if( result == -1 )
|
||||||
;
|
;
|
||||||
else if( !result )
|
else if( !result ) {
|
||||||
fputs( " DEK is good", stdout );
|
if( opt.verbose > 1 )
|
||||||
|
log_info( "pubkey_enc packet: Good DEK\n" );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
printf( " %s", g10_errstr(result));
|
log_error( "pubkey_enc packet: %s\n", g10_errstr(result));
|
||||||
putchar('\n');
|
|
||||||
free_packet(pkt);
|
free_packet(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ proc_encrypted( CTX c, PACKET *pkt )
|
|||||||
{
|
{
|
||||||
int result = 0;
|
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 ) {
|
if( !c->dek && !c->last_was_pubkey_enc ) {
|
||||||
/* assume this is conventional encrypted data */
|
/* assume this is conventional encrypted data */
|
||||||
c->dek = m_alloc_secure( sizeof *c->dek );
|
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;
|
m_free(c->dek); c->dek = NULL;
|
||||||
if( result == -1 )
|
if( result == -1 )
|
||||||
;
|
;
|
||||||
else if( !result )
|
else if( !result ) {
|
||||||
fputs( " encryption okay",stdout);
|
if( opt.verbose > 1 )
|
||||||
else
|
log_info("encryption okay\n");
|
||||||
printf( " %s", g10_errstr(result));
|
}
|
||||||
putchar('\n');
|
else {
|
||||||
|
log_error("encryption failed: %s\n", g10_errstr(result));
|
||||||
|
}
|
||||||
free_packet(pkt);
|
free_packet(pkt);
|
||||||
c->last_was_pubkey_enc = 0;
|
c->last_was_pubkey_enc = 0;
|
||||||
}
|
}
|
||||||
@ -256,9 +258,10 @@ static void
|
|||||||
proc_plaintext( CTX c, PACKET *pkt )
|
proc_plaintext( CTX c, PACKET *pkt )
|
||||||
{
|
{
|
||||||
PKT_plaintext *pt = pkt->pkt.plaintext;
|
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 );
|
free_md_filter_context( &c->mfx );
|
||||||
/* fixme: take the digest algo(s) to use from the
|
/* fixme: take the digest algo(s) to use from the
|
||||||
* onepass_sig packet (if we have these)
|
* onepass_sig packet (if we have these)
|
||||||
@ -266,12 +269,9 @@ proc_plaintext( CTX c, PACKET *pkt )
|
|||||||
* textmode filter (sigclass 0x01)
|
* textmode filter (sigclass 0x01)
|
||||||
*/
|
*/
|
||||||
c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
|
c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
|
||||||
result = handle_plaintext( pt, &c->mfx );
|
rc = handle_plaintext( pt, &c->mfx );
|
||||||
if( !result )
|
if( rc )
|
||||||
fputs( " okay", stdout);
|
log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
|
||||||
else
|
|
||||||
printf( " %s", g10_errstr(result));
|
|
||||||
putchar('\n');
|
|
||||||
free_packet(pkt);
|
free_packet(pkt);
|
||||||
c->last_was_pubkey_enc = 0;
|
c->last_was_pubkey_enc = 0;
|
||||||
}
|
}
|
||||||
@ -281,15 +281,12 @@ static void
|
|||||||
proc_compressed( CTX c, PACKET *pkt )
|
proc_compressed( CTX c, PACKET *pkt )
|
||||||
{
|
{
|
||||||
PKT_compressed *zd = pkt->pkt.compressed;
|
PKT_compressed *zd = pkt->pkt.compressed;
|
||||||
int result;
|
int rc;
|
||||||
|
|
||||||
printf("zip: compressed data packet\n");
|
/*printf("zip: compressed data packet\n");*/
|
||||||
result = handle_compressed( zd );
|
rc = handle_compressed( zd );
|
||||||
if( !result )
|
if( rc )
|
||||||
fputs( " okay", stdout);
|
log_error("uncompressing failed: %s\n", g10_errstr(rc));
|
||||||
else
|
|
||||||
printf( " %s", g10_errstr(result));
|
|
||||||
putchar('\n');
|
|
||||||
free_packet(pkt);
|
free_packet(pkt);
|
||||||
c->last_was_pubkey_enc = 0;
|
c->last_was_pubkey_enc = 0;
|
||||||
}
|
}
|
||||||
@ -505,7 +502,6 @@ proc_packets( IOBUF a )
|
|||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
int newpkt;
|
int newpkt;
|
||||||
|
|
||||||
c->opt_list = 1;
|
|
||||||
c->iobuf = a;
|
c->iobuf = a;
|
||||||
init_packet(pkt);
|
init_packet(pkt);
|
||||||
while( (rc=parse_packet(a, pkt)) != -1 ) {
|
while( (rc=parse_packet(a, pkt)) != -1 ) {
|
||||||
@ -522,6 +518,15 @@ proc_packets( IOBUF a )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
newpkt = -1;
|
newpkt = -1;
|
||||||
|
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 ) {
|
switch( pkt->pkttype ) {
|
||||||
case PKT_PUBLIC_CERT: newpkt = add_public_cert( c, pkt ); break;
|
case PKT_PUBLIC_CERT: newpkt = add_public_cert( c, pkt ); break;
|
||||||
case PKT_SECRET_CERT: newpkt = add_secret_cert( c, pkt ); break;
|
case PKT_SECRET_CERT: newpkt = add_secret_cert( c, pkt ); break;
|
||||||
@ -534,6 +539,7 @@ proc_packets( IOBUF a )
|
|||||||
case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
|
case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
|
||||||
default: newpkt = 0; break;
|
default: newpkt = 0; break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if( pkt->pkttype != PKT_SIGNATURE )
|
if( pkt->pkttype != PKT_SIGNATURE )
|
||||||
c->have_data = pkt->pkttype == PKT_PLAINTEXT;
|
c->have_data = pkt->pkttype == PKT_PLAINTEXT;
|
||||||
|
|
||||||
@ -575,13 +581,16 @@ proc_tree( CTX c, KBNODE node )
|
|||||||
KBNODE n1;
|
KBNODE n1;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if( opt.list_packets )
|
||||||
|
return;
|
||||||
|
|
||||||
if( node->pkt->pkttype == PKT_PUBLIC_CERT )
|
if( node->pkt->pkttype == PKT_PUBLIC_CERT )
|
||||||
list_node( c, node );
|
list_node( c, node );
|
||||||
else if( node->pkt->pkttype == PKT_SECRET_CERT )
|
else if( node->pkt->pkttype == PKT_SECRET_CERT )
|
||||||
list_node( c, node );
|
list_node( c, node );
|
||||||
else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
|
else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
|
||||||
if( !node->child )
|
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 )
|
else if( node->child->pkt->pkttype != PKT_SIGNATURE )
|
||||||
log_error("proc_tree: onepass_sig not followed by signature\n");
|
log_error("proc_tree: onepass_sig not followed by signature\n");
|
||||||
else { /* check all signatures */
|
else { /* check all signatures */
|
||||||
@ -611,6 +620,8 @@ proc_tree( CTX c, KBNODE node )
|
|||||||
log_error("BAD signature from ");
|
log_error("BAD signature from ");
|
||||||
print_keyid( stderr, sig->keyid );
|
print_keyid( stderr, sig->keyid );
|
||||||
putc('\n', stderr);
|
putc('\n', stderr);
|
||||||
|
if( opt.batch )
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log_error("Can't check signature made by %08lX: %s\n",
|
log_error("Can't check signature made by %08lX: %s\n",
|
||||||
|
@ -35,7 +35,7 @@ struct {
|
|||||||
int fingerprint; /* list fingerprints */
|
int fingerprint; /* list fingerprints */
|
||||||
int list_sigs; /* list signatures */
|
int list_sigs; /* list signatures */
|
||||||
int no_armor;
|
int no_armor;
|
||||||
int reserved5;
|
int list_packets; /* list-packets mode */
|
||||||
int reserved6;
|
int reserved6;
|
||||||
int reserved7;
|
int reserved7;
|
||||||
int reserved8;
|
int reserved8;
|
||||||
|
@ -210,6 +210,7 @@ struct packet_struct {
|
|||||||
|
|
||||||
/*-- mainproc.c --*/
|
/*-- mainproc.c --*/
|
||||||
int proc_packets( IOBUF a );
|
int proc_packets( IOBUF a );
|
||||||
|
int list_packets( IOBUF a );
|
||||||
|
|
||||||
/*-- parse-packet.c --*/
|
/*-- parse-packet.c --*/
|
||||||
int set_packet_list_mode( int mode );
|
int set_packet_list_mode( int mode );
|
||||||
|
@ -25,13 +25,27 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "options.h"
|
||||||
#include "ttyio.h"
|
#include "ttyio.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "keydb.h"
|
#include "keydb.h"
|
||||||
|
|
||||||
|
static int pwfd = -1;
|
||||||
|
|
||||||
static int hash_passphrase( DEK *dek, char *pw );
|
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
|
* Get a passphrase for the secret key with KEYID, display TEXT
|
||||||
@ -41,35 +55,51 @@ static int hash_passphrase( DEK *dek, char *pw );
|
|||||||
DEK *
|
DEK *
|
||||||
get_passphrase_hash( u32 *keyid, char *text )
|
get_passphrase_hash( u32 *keyid, char *text )
|
||||||
{
|
{
|
||||||
char *p=NULL, *pw;
|
char *pw;
|
||||||
DEK *dek;
|
DEK *dek;
|
||||||
|
|
||||||
if( keyid ) {
|
if( keyid && !opt.batch ) {
|
||||||
char *ustr;
|
char *ustr;
|
||||||
tty_printf("\nNeed a pass phrase to unlock the secret key!\n");
|
tty_printf("Need a pass phrase to unlock the secret key for:\n");
|
||||||
tty_printf("KeyID: " );
|
tty_printf(" \"" );
|
||||||
ustr = get_user_id_string( keyid );
|
ustr = get_user_id_string( keyid );
|
||||||
tty_print_string( ustr, strlen(ustr) );
|
tty_print_string( ustr, strlen(ustr) );
|
||||||
m_free(ustr);
|
m_free(ustr);
|
||||||
tty_printf("\n\n");
|
tty_printf("\"\n\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
if( keyid && (p=getenv("G10PASSPHRASE")) ) {
|
if( pwfd != -1 ) { /* read the passphrase from the given descriptor */
|
||||||
pw = m_alloc_secure(strlen(p)+1);
|
int i, len;
|
||||||
strcpy(pw,p);
|
|
||||||
tty_printf("Taking it from $G10PASSPHRASE !\n", keyid[1] );
|
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;
|
||||||
}
|
}
|
||||||
else
|
if( read( pwfd, pw+i, 1) != 1 || pw[i] == '\n' )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pw[i] = 0;
|
||||||
|
if( !opt.batch )
|
||||||
|
tty_printf("\b\b\b \n" );
|
||||||
|
}
|
||||||
|
else if( opt.batch )
|
||||||
|
log_fatal("Can't query password in batchmode\n");
|
||||||
|
else {
|
||||||
pw = tty_get_hidden("Enter pass phrase: " );
|
pw = tty_get_hidden("Enter pass phrase: " );
|
||||||
|
tty_kill_prompt();
|
||||||
|
}
|
||||||
dek = m_alloc_secure( sizeof *dek );
|
dek = m_alloc_secure( sizeof *dek );
|
||||||
dek->algo = CIPHER_ALGO_BLOWFISH;
|
dek->algo = CIPHER_ALGO_BLOWFISH;
|
||||||
if( hash_passphrase( dek, pw ) )
|
if( hash_passphrase( dek, pw ) )
|
||||||
log_bug("get_passphrase_hash\n");
|
log_bug("get_passphrase_hash\n");
|
||||||
m_free(pw); /* is allocated in secure memory, so it will be burned */
|
m_free(pw); /* is allocated in secure memory, so it will be burned */
|
||||||
if( !p ) {
|
|
||||||
tty_kill_prompt();
|
|
||||||
tty_printf("\n");
|
|
||||||
}
|
|
||||||
return dek;
|
return dek;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +119,7 @@ make_dek_from_passphrase( DEK *dek, int mode )
|
|||||||
tty_kill_prompt();
|
tty_kill_prompt();
|
||||||
if( mode == 2 ) {
|
if( mode == 2 ) {
|
||||||
pw2 = tty_get_hidden("Repeat pass phrase: " );
|
pw2 = tty_get_hidden("Repeat pass phrase: " );
|
||||||
|
tty_kill_prompt();
|
||||||
if( strcmp(pw, pw2) ) {
|
if( strcmp(pw, pw2) ) {
|
||||||
m_free(pw2);
|
m_free(pw2);
|
||||||
m_free(pw);
|
m_free(pw);
|
||||||
|
@ -65,6 +65,7 @@ check_elg( PKT_secret_cert *cert )
|
|||||||
unsigned nbytes;
|
unsigned nbytes;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
ELG_secret_key skey;
|
ELG_secret_key skey;
|
||||||
|
char save_iv[8];
|
||||||
|
|
||||||
if( cert->d.elg.is_protected ) { /* remove the protection */
|
if( cert->d.elg.is_protected ) { /* remove the protection */
|
||||||
DEK *dek = NULL;
|
DEK *dek = NULL;
|
||||||
@ -80,6 +81,7 @@ check_elg( PKT_secret_cert *cert )
|
|||||||
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
|
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
|
||||||
m_free(dek); /* pw is in secure memory, so m_free() burns it */
|
m_free(dek); /* pw is in secure memory, so m_free() burns it */
|
||||||
blowfish_setiv( blowfish_ctx, NULL );
|
blowfish_setiv( blowfish_ctx, NULL );
|
||||||
|
memcpy(save_iv, cert->d.elg.protect.blowfish.iv, 8 );
|
||||||
blowfish_decode_cfb( blowfish_ctx,
|
blowfish_decode_cfb( blowfish_ctx,
|
||||||
cert->d.elg.protect.blowfish.iv,
|
cert->d.elg.protect.blowfish.iv,
|
||||||
cert->d.elg.protect.blowfish.iv, 8 );
|
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 */
|
/* now let's see wether we have used the right passphrase */
|
||||||
if( csum != cert->d.elg.csum ) {
|
if( csum != cert->d.elg.csum ) {
|
||||||
mpi_free(test_x);
|
mpi_free(test_x);
|
||||||
|
memcpy( cert->d.elg.protect.blowfish.iv, save_iv, 8 );
|
||||||
return G10ERR_BAD_PASS;
|
return G10ERR_BAD_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +108,7 @@ check_elg( PKT_secret_cert *cert )
|
|||||||
memset( &skey, 0, sizeof skey );
|
memset( &skey, 0, sizeof skey );
|
||||||
if( !res ) {
|
if( !res ) {
|
||||||
mpi_free(test_x);
|
mpi_free(test_x);
|
||||||
|
memcpy( cert->d.elg.protect.blowfish.iv, save_iv, 8 );
|
||||||
return G10ERR_BAD_PASS;
|
return G10ERR_BAD_PASS;
|
||||||
}
|
}
|
||||||
mpi_set(cert->d.elg.x, test_x);
|
mpi_set(cert->d.elg.x, test_x);
|
||||||
@ -274,6 +278,8 @@ check_secret_key( PKT_secret_cert *cert )
|
|||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
rc = G10ERR_PUBKEY_ALGO;
|
rc = G10ERR_PUBKEY_ALGO;
|
||||||
|
if( get_passphrase_fd() != -1 )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return rc;
|
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;
|
compress_filter_context_t zfx;
|
||||||
md_filter_context_t mfx;
|
md_filter_context_t mfx;
|
||||||
text_filter_context_t tfx;
|
text_filter_context_t tfx;
|
||||||
|
encrypt_filter_context_t efx;
|
||||||
IOBUF inp = NULL, out = NULL;
|
IOBUF inp = NULL, out = NULL;
|
||||||
PACKET pkt;
|
PACKET pkt;
|
||||||
PKT_plaintext *pt = NULL;
|
PKT_plaintext *pt = NULL;
|
||||||
@ -92,6 +93,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
|
|||||||
memset( &zfx, 0, sizeof zfx);
|
memset( &zfx, 0, sizeof zfx);
|
||||||
memset( &mfx, 0, sizeof mfx);
|
memset( &mfx, 0, sizeof mfx);
|
||||||
memset( &tfx, 0, sizeof tfx);
|
memset( &tfx, 0, sizeof tfx);
|
||||||
|
memset( &efx, 0, sizeof efx);
|
||||||
init_packet( &pkt );
|
init_packet( &pkt );
|
||||||
|
|
||||||
if( (rc=build_skc_list( locusr, &skc_list, 1 )) )
|
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 );
|
iobuf_push_filter( out, compress_filter, &zfx );
|
||||||
|
|
||||||
if( encrypt ) {
|
if( encrypt ) {
|
||||||
/* prepare for encryption */
|
efx.pkc_list = pkc_list;
|
||||||
/* FIXME!!!!!!! */
|
/* fixme: set efx.cfx.datalen if known */
|
||||||
|
iobuf_push_filter( out, encrypt_filter, &efx );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* loop over the secret certificates and build headers */
|
/* 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 )
|
check_all_keysigs( KBNODE keyblock )
|
||||||
{
|
{
|
||||||
KBNODE kbctx;
|
KBNODE kbctx;
|
||||||
@ -384,6 +395,7 @@ check_all_keysigs( KBNODE keyblock )
|
|||||||
m_free(p);
|
m_free(p);
|
||||||
}
|
}
|
||||||
tty_printf("\n");
|
tty_printf("\n");
|
||||||
|
/* FIXME: update the trustdb */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( inv_sigs )
|
if( inv_sigs )
|
||||||
@ -392,6 +404,76 @@ check_all_keysigs( KBNODE keyblock )
|
|||||||
tty_printf("No public key for %d signatures\n", no_key );
|
tty_printf("No public key for %d signatures\n", no_key );
|
||||||
if( oth_err )
|
if( oth_err )
|
||||||
tty_printf("%d signatures not checked due to errors\n", 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;
|
PKT_public_cert *pkc;
|
||||||
int any;
|
int any;
|
||||||
u32 pkc_keyid[2];
|
u32 pkc_keyid[2];
|
||||||
|
char *answer;
|
||||||
|
|
||||||
memset( &mfx, 0, sizeof mfx);
|
memset( &mfx, 0, sizeof mfx);
|
||||||
|
|
||||||
@ -464,9 +547,16 @@ sign_key( const char *username, STRLIST locusr )
|
|||||||
}
|
}
|
||||||
|
|
||||||
clear_kbnode_flags( keyblock );
|
clear_kbnode_flags( keyblock );
|
||||||
check_all_keysigs( keyblock );
|
if( check_all_keysigs( keyblock ) ) {
|
||||||
/* look wether we should ask to remove invalid keys */
|
if( !opt.batch ) {
|
||||||
/*+ FIXME: */
|
/* 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 */
|
/* check wether we have already signed it */
|
||||||
for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) {
|
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 );
|
rc = update_keyblock( &kbpos, keyblock );
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error("insert_keyblock failed: %s\n", g10_errstr(rc) );
|
log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
|
||||||
goto leave;
|
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
|
* Create a signature packet for the given public key certificate
|
||||||
* and the user id and return it in ret_sig. User signature class SIGCLASS
|
* 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;
|
} ARGPARSE_OPTS;
|
||||||
|
|
||||||
/*-- logger.c --*/
|
/*-- 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 printstr( int level, const char *fmt, ... );
|
||||||
void log_bug( const char *fmt, ... );
|
void log_bug( const char *fmt, ... );
|
||||||
void log_fatal( 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 */
|
/* remove the filter stuff from the new stream */
|
||||||
a->filter = NULL;
|
a->filter = NULL;
|
||||||
a->filter_ov = NULL;
|
a->filter_ov = NULL;
|
||||||
|
a->filter_eof = 0;
|
||||||
if( a->usage == 2 ) { /* allocate a fresh buffer for the original stream */
|
if( a->usage == 2 ) { /* allocate a fresh buffer for the original stream */
|
||||||
b->d.buf = m_alloc( a->d.size );
|
b->d.buf = m_alloc( a->d.size );
|
||||||
b->d.len = 0;
|
b->d.len = 0;
|
||||||
@ -539,7 +540,7 @@ iobuf_pop_filter( IOBUF a, int (*f)(void *opaque, int control,
|
|||||||
m_free(b);
|
m_free(b);
|
||||||
}
|
}
|
||||||
else if( !b->chain ) { /* remove the last iobuf from the chain */
|
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 */
|
else { /* remove an intermediate iobuf from the chain */
|
||||||
log_bug("Ohh jeee, trying to remove an intermediate filter\n");
|
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
|
int
|
||||||
iobuf_in_block_mode( IOBUF a )
|
iobuf_in_block_mode( IOBUF a )
|
||||||
{
|
{
|
||||||
for(; a; a = a->chain )
|
if( a && a->filter == block_filter )
|
||||||
if( a->filter == block_filter )
|
|
||||||
return 1; /* yes */
|
return 1; /* yes */
|
||||||
return 0; /* no */
|
return 0; /* no */
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static char pidstring[15];
|
static char pidstring[15];
|
||||||
|
static int errorcount;
|
||||||
|
|
||||||
void
|
void
|
||||||
set_log_pid( int pid )
|
log_set_pid( int pid )
|
||||||
{
|
{
|
||||||
if( pid )
|
if( pid )
|
||||||
sprintf(pidstring,"[%u]", (unsigned)pid );
|
sprintf(pidstring,"[%u]", (unsigned)pid );
|
||||||
@ -37,6 +37,15 @@ set_log_pid( int pid )
|
|||||||
*pidstring = 0;
|
*pidstring = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
log_get_errorcount( int clear)
|
||||||
|
{
|
||||||
|
int n = errorcount;
|
||||||
|
if( clear )
|
||||||
|
errorcount = 0;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* General interface for printing a line
|
* General interface for printing a line
|
||||||
@ -90,6 +99,7 @@ log_error( const char *fmt, ... )
|
|||||||
va_start( arg_ptr, fmt ) ;
|
va_start( arg_ptr, fmt ) ;
|
||||||
vfprintf(stderr,fmt,arg_ptr) ;
|
vfprintf(stderr,fmt,arg_ptr) ;
|
||||||
va_end(arg_ptr);
|
va_end(arg_ptr);
|
||||||
|
errorcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
104
util/ttyio.c
104
util/ttyio.c
@ -30,41 +30,19 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "ttyio.h"
|
#include "ttyio.h"
|
||||||
|
|
||||||
|
static FILE *ttyfp = NULL;
|
||||||
static int last_prompt_len;
|
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
|
static void
|
||||||
close_tty( FILE *tty, struct termios *termsave )
|
init_ttyfp()
|
||||||
{
|
{
|
||||||
if( termsave ) {
|
if( ttyfp )
|
||||||
if( tcsetattr(fileno(tty), TCSAFLUSH, termsave) )
|
return;
|
||||||
log_error("tcsetattr() failed: %s\n", strerror(errno) );
|
|
||||||
putc('\n', stderr);
|
|
||||||
}
|
|
||||||
fclose(tty);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ttyfp = fopen("/dev/tty", "r+");
|
||||||
|
if( !ttyfp )
|
||||||
|
log_fatal("cannot open /dev/tty: %s\n", strerror(errno) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -72,10 +50,13 @@ tty_printf( const char *fmt, ... )
|
|||||||
{
|
{
|
||||||
va_list arg_ptr;
|
va_list arg_ptr;
|
||||||
|
|
||||||
|
if( !ttyfp )
|
||||||
|
init_ttyfp();
|
||||||
|
|
||||||
va_start( arg_ptr, fmt ) ;
|
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);
|
va_end(arg_ptr);
|
||||||
fflush(stderr);
|
fflush(ttyfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -85,18 +66,21 @@ tty_printf( const char *fmt, ... )
|
|||||||
void
|
void
|
||||||
tty_print_string( byte *p, size_t n )
|
tty_print_string( byte *p, size_t n )
|
||||||
{
|
{
|
||||||
|
if( !ttyfp )
|
||||||
|
init_ttyfp();
|
||||||
|
|
||||||
for( ; n; n--, p++ )
|
for( ; n; n--, p++ )
|
||||||
if( iscntrl( *p ) ) {
|
if( iscntrl( *p ) ) {
|
||||||
putc('\\', stderr);
|
putc('\\', ttyfp);
|
||||||
if( *p == '\n' )
|
if( *p == '\n' )
|
||||||
putc('n', stderr);
|
putc('n', ttyfp);
|
||||||
else if( !*p )
|
else if( !*p )
|
||||||
putc('0', stderr);
|
putc('0', ttyfp);
|
||||||
else
|
else
|
||||||
fprintf(stderr, "x%02x", *p );
|
fprintf(ttyfp, "x%02x", *p );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
putc(*p, stderr);
|
putc(*p, ttyfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -107,17 +91,36 @@ static char *
|
|||||||
do_get( const char *prompt, int hidden )
|
do_get( const char *prompt, int hidden )
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
|
byte cbuf[1];
|
||||||
int c, n, i;
|
int c, n, i;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
struct termios termsave;
|
struct termios termsave;
|
||||||
|
|
||||||
|
if( !ttyfp )
|
||||||
|
init_ttyfp();
|
||||||
|
|
||||||
last_prompt_len = 0;
|
last_prompt_len = 0;
|
||||||
tty_printf( prompt );
|
tty_printf( prompt );
|
||||||
buf = m_alloc(n=50);
|
buf = m_alloc(n=50);
|
||||||
i = 0;
|
i = 0;
|
||||||
fp = open_tty(hidden? &termsave: NULL);
|
|
||||||
while( (c=getc(fp)) != EOF && c != '\n' ) {
|
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++;
|
last_prompt_len++;
|
||||||
|
c = *cbuf;
|
||||||
if( c == '\t' )
|
if( c == '\t' )
|
||||||
c = ' ';
|
c = ' ';
|
||||||
else if( iscntrl(c) )
|
else if( iscntrl(c) )
|
||||||
@ -128,7 +131,11 @@ do_get( const char *prompt, int hidden )
|
|||||||
}
|
}
|
||||||
buf[i++] = c;
|
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;
|
buf[i] = 0;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -151,15 +158,16 @@ void
|
|||||||
tty_kill_prompt()
|
tty_kill_prompt()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
#if 0
|
|
||||||
|
if( !ttyfp )
|
||||||
|
init_ttyfp();
|
||||||
|
if( !last_prompt_len )
|
||||||
|
return;
|
||||||
|
fputc('\r', ttyfp);
|
||||||
for(i=0; i < last_prompt_len; i ++ )
|
for(i=0; i < last_prompt_len; i ++ )
|
||||||
fputc('\b', stderr);
|
fputc(' ', ttyfp);
|
||||||
for(i=0; i < last_prompt_len; i ++ )
|
fputc('\r', ttyfp);
|
||||||
fputc(' ', stderr);
|
|
||||||
for(i=0; i < last_prompt_len; i ++ )
|
|
||||||
fputc('\b', stderr);
|
|
||||||
#endif
|
|
||||||
last_prompt_len = 0;
|
last_prompt_len = 0;
|
||||||
fflush(stderr);
|
fflush(ttyfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user