1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-03-28 22:49:59 +01:00

See ChangeLog: Mon Jan 24 22:24:38 CET 2000 Werner Koch

This commit is contained in:
Werner Koch 2000-01-24 21:14:42 +00:00
parent 54b141f63e
commit db43afc923
12 changed files with 454 additions and 32 deletions

View File

@ -1,3 +1,14 @@
Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
* pubkey.c (gcry_pk_decrypt): Implemented.
(gcry_pk_encrypt): Implemented.
(gcry_pk_testkey): New.
(gcry_pk_genkey): New.
(pubkey_decrypt): Made static.
(pubkey_encrypt): Ditto.
(pubkey_check_secret_key): Ditto.
(pubkey_generate): Ditto.
Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
* pubkey.c (pubkey_nbits): Removed and replaced by ...

View File

@ -95,6 +95,7 @@ static struct {
{ NULL }};
static int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
static int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey );
static int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
int (*cmp)(void *, MPI), void *opaque );
@ -432,7 +433,7 @@ pubkey_get_nenc( int algo )
}
int
static int
pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
{
int i;
@ -447,7 +448,7 @@ pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
}
int
static int
pubkey_check_secret_key( int algo, MPI *skey )
{
int i;
@ -467,7 +468,7 @@ pubkey_check_secret_key( int algo, MPI *skey )
* should be an array of MPIs of size PUBKEY_MAX_NENC (or less if the
* algorithm allows this - check with pubkey_get_nenc() )
*/
int
static int
pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
{
int i, rc;
@ -504,12 +505,12 @@ pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
* result is a pointer to a mpi variable which will receive a
* newly allocated mpi or NULL in case of an error.
*/
int
static int
pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
{
int i, rc;
*result = NULL; /* so the caller can always do an mpi_free */
*result = NULL; /* so the caller can always do a mpi_free */
if( DBG_CIPHER ) {
log_debug("pubkey_decrypt: algo=%d\n", algo );
for(i=0; i < pubkey_get_nskey(algo); i++ )
@ -751,20 +752,196 @@ sexp_to_sig( GCRY_SEXP sexp, MPI **retarray, int *retalgo)
}
int
gcry_pk_encrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey )
/****************
* Take sexp and return an array of MPI as used for our internal decrypt
* function.
*/
static int
sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo)
{
/* ... */
GCRY_SEXP list, l2;
const char *name;
const char *s;
size_t n;
int i, idx;
int algo;
const char *elems;
GCRY_MPI *array;
/* check that the first element is valid */
list = gcry_sexp_find_token( sexp, "enc-val" , 0 );
if( !list )
return GCRYERR_INV_OBJ; /* Does not contain a encrypted value object */
list = gcry_sexp_cdr( list );
if( !list )
return GCRYERR_NO_OBJ; /* no cdr for the data object */
name = gcry_sexp_car_data( list, &n );
if( !name )
return GCRYERR_INV_OBJ; /* invalid structure of object */
for(i=0; (s=enc_info_table[i].name); i++ ) {
if( strlen(s) == n && !memcmp( s, name, n ) )
break;
}
if( !s )
return GCRYERR_INV_PK_ALGO; /* unknown algorithm */
algo = enc_info_table[i].algo;
elems = enc_info_table[i].elements;
array = g10_calloc( (strlen(elems)+1) , sizeof *array );
if( !array )
return GCRYERR_NO_MEM;
idx = 0;
for(s=elems; *s; s++, idx++ ) {
l2 = gcry_sexp_find_token( list, s, 1 );
if( !l2 ) {
g10_free( array );
return GCRYERR_NO_OBJ; /* required parameter not found */
}
array[idx] = gcry_sexp_cdr_mpi( l2, GCRYMPI_FMT_USG );
if( !array[idx] ) {
g10_free( array );
return GCRYERR_INV_OBJ; /* required parameter is invalid */
}
}
*retarray = array;
*retalgo = algo;
return 0;
}
/****************
* Do a PK encrypt operation
*
* Caller has to provide a public key as the SEXP pkey and data as a SEXP
* with just one MPI in it. The function returns a a sexp which may
* be passed tp to pk_decrypt.
* Later versions of this functions may take more complex input data.
*
* Returns: 0 or an errorcode.
*
* s_data = (<mpi>)
* s_pkey = <key-as-defined-in-sexp_to_key>
* r_ciph = (enc-val
* (<algo>
* (<param_name1> <mpi>)
* ...
* (<param_namen> <mpi>)
* ))
*/
int
gcry_pk_decrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey )
gcry_pk_encrypt( GCRY_SEXP *r_ciph, GCRY_SEXP s_data, GCRY_SEXP s_pkey )
{
/* ... */
MPI *pkey, data, *ciph;
const char *algo_name, *algo_elems;
GCRY_SEXP *s_elems;
int i, rc, algo;
/* get the key */
rc = sexp_to_key( s_pkey, 0, &pkey, &algo );
if( rc ) {
return rc;
}
/* get the name and the required size of the return value */
for(i=0; (algo_name = enc_info_table[i].name); i++ ) {
if( enc_info_table[i].algo == algo )
break;
}
if( !algo_name ) {
release_mpi_array( pkey );
return GCRYERR_INV_PK_ALGO;
}
algo_elems = enc_info_table[i].elements;
/* get the stuff we want to encrypt */
data = gcry_sexp_car_mpi( s_data, 0 );
if( !data ) {
release_mpi_array( pkey );
return GCRYERR_INV_OBJ;
}
/* Now we can encrypt data to ciph */
ciph = g10_xcalloc( (strlen(algo_elems)+1) , sizeof *ciph );
rc = pubkey_encrypt( algo, ciph, data, pkey );
release_mpi_array( pkey );
mpi_free( data );
if( rc ) {
g10_free( ciph );
return rc;
}
/* We did it. Now build the return list */
s_elems = g10_xcalloc( (strlen(algo_elems)+2), sizeof *s_elems );
s_elems[0] = SEXP_NEW( algo_name, 0 );
for(i=0; algo_elems[i]; i++ ) {
char tmp[2];
tmp[0] = algo_elems[i];
tmp[1] = 0;
s_elems[i+1] = gcry_sexp_new_name_mpi( tmp, ciph[i] );
}
release_mpi_array( ciph );
g10_free( ciph );
*r_ciph = SEXP_CONS( SEXP_NEW( "enc-val", 0 ),
gcry_sexp_alist( s_elems ) );
g10_free( s_elems );
return 0;
}
/****************
* Do a PK decrypt operation
*
* Caller has to provide a secret key as the SEXP skey and data in a format
* as created by gcry_pk_encrypt. Currently the function returns
* simply a MPI. Later versions of this functions may return a more
* complex data structure.
*
* Returns: 0 or an errorcode.
*
* s_data = (enc-val
* (<algo>
* (<param_name1> <mpi>)
* ...
* (<param_namen> <mpi>)
* ))
* s_skey = <key-as-defined-in-sexp_to_key>
* r_plain= (<mpi>) FIXME: Return a more structered value
*/
int
gcry_pk_decrypt( GCRY_SEXP *r_plain, GCRY_SEXP s_data, GCRY_SEXP s_skey )
{
MPI *skey, *data, plain;
int rc, algo, dataalgo;
rc = sexp_to_key( s_skey, 1, &skey, &algo );
if( rc ) {
return rc;
}
rc = sexp_to_enc( s_data, &data, &dataalgo );
if( rc ) {
release_mpi_array( skey );
return rc;
}
if( algo != dataalgo ) {
release_mpi_array( skey );
release_mpi_array( data );
return -1; /* fixme: add real errornumber - algo does not match */
}
rc = pubkey_decrypt( algo, &plain, data, skey );
if( rc ) {
release_mpi_array( skey );
release_mpi_array( data );
return -1; /* fixme: add real errornumber - decryption failed */
}
*r_plain = gcry_sexp_new_mpi( plain );
mpi_free( plain );
release_mpi_array( data );
release_mpi_array( skey );
return 0;
}
@ -800,7 +977,7 @@ gcry_pk_sign( GCRY_SEXP *r_sig, GCRY_SEXP s_hash, GCRY_SEXP s_skey )
MPI *result;
int i, algo, rc;
const char *algo_name, *algo_elems;
GCRY_SEXP s;
GCRY_SEXP *s_elems;
rc = sexp_to_key( s_skey, 1, &skey, &algo );
if( rc )
@ -832,16 +1009,21 @@ gcry_pk_sign( GCRY_SEXP *r_sig, GCRY_SEXP s_hash, GCRY_SEXP s_skey )
return rc;
}
s = SEXP_NEW( algo_name, 0 );
s_elems = g10_xcalloc( (strlen(algo_elems)+2), sizeof *s_elems );
s_elems[0] = SEXP_NEW( algo_name, 0 );
for(i=0; algo_elems[i]; i++ ) {
char tmp[2];
tmp[0] = algo_elems[i];
tmp[1] = 0;
s = gcry_sexp_append( s, gcry_sexp_new_name_mpi( tmp, result[i] ) );
s_elems[i+1] = gcry_sexp_new_name_mpi( tmp, result[i] );
}
release_mpi_array( result );
g10_free( result );
*r_sig = SEXP_CONS( SEXP_NEW( "sig-val", 0 ), s );
gcry_sexp_dump( *r_sig );
*r_sig = SEXP_CONS( SEXP_NEW( "sig-val", 0 ),
gcry_sexp_alist( s_elems ) );
g10_free( s_elems );
return 0;
}
@ -889,6 +1071,52 @@ gcry_pk_verify( GCRY_SEXP s_sig, GCRY_SEXP s_hash, GCRY_SEXP s_pkey )
}
/****************
* Test a key. This may be used either for a public or a secret key
* to see whether internal structre is valid.
*
* Returns: 0 or an errorcode.
*
* s_key = <key-as-defined-in-sexp_to_key>
*/
int
gcry_pk_testkey( GCRY_SEXP s_key )
{
MPI *key;
int rc, algo;
/* Note we currently support only secret key checking */
rc = sexp_to_key( s_key, 1, &key, &algo );
if( rc ) {
return rc;
}
rc = pubkey_check_secret_key( algo, key );
release_mpi_array( key );
return rc;
}
/****************
* Create a public key pair and return it in r_key.
* How the key is created depends on s_parms:
* (GNU
* (genkey
* (algo
* (parameter_name_1 ....)
* ....
* (parameter_name_n ....)
* )))
* The key is returned in a format depending on the
* algorithm. Both, private and secret key are returned
* and optionally some additional informatin.
*/
int
gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms )
{
return GCRYERR_NOT_IMPL;
}
/****************
* Get the number of nbits from the public key
* Hmmm: Should we have really this function or is it

View File

@ -1,3 +1,16 @@
Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
* misc.c (mpi_read_opaque): Fixed double counting.
* seckey-cert.c (do_check): Removed buffer and the unmotivated free
on it.
* pubkey-enc.c (pk_decrypt): New wrapper for the gcry_ function.
* seckey-cert.c (pk_check_secret_key): Likewise.
* encode.c (pk_encrypt): Likewise.
* parse-packet.c (parse_key): Fixed case of unencrypted secret keys.
Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
* misc.c (mpi_print): Use gcry_mpi_aprint.

View File

@ -41,6 +41,52 @@
static int encode_simple( const char *filename, int mode );
static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out );
/****************
* Emulate our old PK interface here - sometime in the future we might
* change the internal design to directly fit to libgcrypt.
*/
static int
pk_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
{
GCRY_SEXP s_ciph, s_data, s_pkey;
int rc;
/* make a sexp from pkey */
if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
s_pkey = SEXP_CONS( SEXP_NEW( "public-key", 0 ),
gcry_sexp_vlist( SEXP_NEW( "elg", 3 ),
gcry_sexp_new_name_mpi( "p", pkey[0] ),
gcry_sexp_new_name_mpi( "g", pkey[1] ),
gcry_sexp_new_name_mpi( "y", pkey[2] ),
NULL ));
}
else
return G10ERR_PUBKEY_ALGO;
/* put the data into a simple list */
s_data = gcry_sexp_new_mpi( data );
/* pass it to libgcrypt */
rc = gcry_pk_encrypt( &s_ciph, s_data, s_pkey );
gcry_sexp_release( s_data );
gcry_sexp_release( s_pkey );
if( rc )
;
else { /* add better error handling or make gnupg use S-Exp directly */
GCRY_SEXP list = gcry_sexp_find_token( s_ciph, "a" , 0 );
assert( list );
resarr[0] = gcry_sexp_cdr_mpi( list, 0 );
assert( resarr[0] );
list = gcry_sexp_find_token( s_ciph, "b" , 0 );
assert( list );
resarr[1] = gcry_sexp_cdr_mpi( list, 0 );
assert( resarr[1] );
}
gcry_sexp_release( s_ciph );
return rc;
}
/****************
@ -464,7 +510,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
* number of bits we have to use. We then encode the session
* key in some way and we get it back in the big intger value
* FRAME. Then we use FRAME, the public key PK->PKEY and the
* algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt
* algorithm number PK->PUBKEY_ALGO and pass it to pk_encrypt
* which returns the encrypted value in the array ENC->DATA.
* This array has a size which depends on the used algorithm
* (e.g. 2 for ElGamal). We don't need frame anymore because we
@ -473,7 +519,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
*/
frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo,
pk->pkey ) );
rc = pubkey_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
rc = pk_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
mpi_release( frame );
if( rc )
log_error("pubkey_encrypt failed: %s\n", g10_errstr(rc) );

View File

@ -488,7 +488,7 @@ make_username( const char *string )
static void
register_extension( const char *mainpgm, const char *fname )
{
#warning fixme add resgitser cipher extension
#warning fixme add register cipher extension
#if 0
if( *fname != '/' ) { /* do tilde expansion etc */
char *tmp;

View File

@ -204,9 +204,10 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
MPI *factors;
assert( is_ELGAMAL(algo) );
rc = pubkey_generate( algo, nbits, skey, &factors );
/*rc = pubkey_generate( algo, nbits, skey, &factors );*/
rc = gcry_pk_genkey( NULL, NULL );
if( rc ) {
log_error("pubkey_generate failed: %s\n", g10_errstr(rc) );
log_error("pk_genkey failed: %s\n", g10_errstr(rc) );
return rc;
}
@ -281,7 +282,8 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
if( nbits > 1024 )
nbits = 1024;
rc = pubkey_generate( GCRY_PK_DSA, nbits, skey, &factors );
/*rc = pubkey_generate( GCRY_PK_DSA, nbits, skey, &factors );*/
rc = gcry_pk_genkey( NULL, NULL );
if( rc ) {
log_error("pubkey_generate failed: %s\n", g10_errstr(rc) );
return rc;

View File

@ -178,7 +178,7 @@ mpi_read(IOBUF inp, unsigned int *ret_nread, int secure)
/****************
* Same as mpi_read but the value is stored as an opaque MPI.
* This function is used to read encrpted MPI of v3 packets.
* This function is used to read encrypted MPI of v3 packets.
*/
GCRY_MPI
mpi_read_opaque(IOBUF inp, unsigned *ret_nread )
@ -205,7 +205,6 @@ mpi_read_opaque(IOBUF inp, unsigned *ret_nread )
p = buf;
for( i=0 ; i < nbytes; i++ ) {
p[i] = iobuf_get(inp) & 0xff;
nread++;
}
nread += nbytes;
a = gcry_mpi_set_opaque(NULL, buf, nbits );

View File

@ -1420,10 +1420,11 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
printf("\tencrypted stuff follows\n");
}
}
else { /* v3 method: the mpi length is not encrypted */
else { /* unencrypted v4 or v3 method (where length is not encrypted) */
for(i=npkey; i < nskey; i++ ) {
n = pktlen;
sk->skey[i] = mpi_read_opaque(inp, &n );
sk->skey[i] = sk->is_protected ? mpi_read_opaque(inp, &n )
: mpi_read( inp, &n, 1 );
pktlen -=n;
if( list_mode ) {
printf( "\tskey[%d]: ", i);

View File

@ -37,6 +37,74 @@
static int get_it( PKT_pubkey_enc *k,
DEK *dek, PKT_secret_key *sk, u32 *keyid );
/****************
* Emulate our old PK interface here - sometime in the future we might
* change the internal design to directly fit to libgcrypt.
*/
static int
pk_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
{
GCRY_SEXP s_skey, s_data, s_plain;
int rc;
*result = NULL;
/* make a sexp from skey */
if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
s_skey = SEXP_CONS( SEXP_NEW( "private-key", 0 ),
gcry_sexp_vlist( SEXP_NEW( "elg", 0 ),
gcry_sexp_new_name_mpi( "p", skey[0] ),
gcry_sexp_new_name_mpi( "g", skey[1] ),
gcry_sexp_new_name_mpi( "y", skey[2] ),
gcry_sexp_new_name_mpi( "x", skey[3] ),
NULL ));
}
else if( algo == GCRY_PK_RSA ) {
s_skey = SEXP_CONS( SEXP_NEW( "private-key", 0 ),
gcry_sexp_vlist( SEXP_NEW( "rsa", 0 ),
gcry_sexp_new_name_mpi( "n", skey[0] ),
gcry_sexp_new_name_mpi( "e", skey[1] ),
gcry_sexp_new_name_mpi( "d", skey[2] ),
gcry_sexp_new_name_mpi( "p", skey[3] ),
gcry_sexp_new_name_mpi( "q", skey[4] ),
gcry_sexp_new_name_mpi( "u", skey[5] ),
NULL ));
}
else
return G10ERR_PUBKEY_ALGO;
/* put data into a S-Exp s_data */
if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
s_data = SEXP_CONS( SEXP_NEW( "enc-val", 0 ),
gcry_sexp_vlist( SEXP_NEW( "elg", 0 ),
gcry_sexp_new_name_mpi( "a", data[0] ),
gcry_sexp_new_name_mpi( "b", data[1] ),
NULL ));
}
else if( algo == GCRY_PK_RSA ) {
s_data = SEXP_CONS( SEXP_NEW( "enc-val", 0 ),
gcry_sexp_vlist( SEXP_NEW( "rsa", 0 ),
gcry_sexp_new_name_mpi( "a", data[0] ),
NULL ));
}
else
BUG();
rc = gcry_pk_decrypt( &s_plain, s_data, s_skey );
gcry_sexp_release( s_skey );
gcry_sexp_release( s_data);
if( rc )
return rc;
*result = gcry_sexp_car_mpi( s_plain, 0 );
if( !*result )
return -1; /* oops */
return 0;
}
/****************
* Get the session key from a pubkey enc paket and return
* it in DEK, which should have been allocated in secure memory.
@ -106,7 +174,7 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
size_t nframe;
u16 csum, csum2;
rc = pubkey_decrypt(sk->pubkey_algo, &plain_dek, k->data, sk->skey );
rc = pk_decrypt(sk->pubkey_algo, &plain_dek, k->data, sk->skey );
if( rc )
goto leave;
if( gcry_mpi_aprint( GCRYMPI_FMT_USG, &frame, &nframe, plain_dek ) )

View File

@ -33,11 +33,58 @@
#include "i18n.h"
#include "status.h"
/****************
* Emulate our old PK interface here - sometime in the future we might
* change the internal design to directly fit to libgcrypt.
*/
static int
pk_check_secret_key( int algo, MPI *skey )
{
GCRY_SEXP s_skey;
int rc;
/* make a sexp from skey */
if( algo == GCRY_PK_DSA ) {
s_skey = SEXP_CONS( SEXP_NEW( "private-key", 0 ),
gcry_sexp_vlist( SEXP_NEW( "dsa", 0 ),
gcry_sexp_new_name_mpi( "p", skey[0] ),
gcry_sexp_new_name_mpi( "q", skey[1] ),
gcry_sexp_new_name_mpi( "g", skey[2] ),
gcry_sexp_new_name_mpi( "y", skey[3] ),
gcry_sexp_new_name_mpi( "x", skey[4] ),
NULL ));
}
else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
s_skey = SEXP_CONS( SEXP_NEW( "private-key", 0 ),
gcry_sexp_vlist( SEXP_NEW( "elg", 0 ),
gcry_sexp_new_name_mpi( "p", skey[0] ),
gcry_sexp_new_name_mpi( "g", skey[1] ),
gcry_sexp_new_name_mpi( "y", skey[2] ),
gcry_sexp_new_name_mpi( "x", skey[3] ),
NULL ));
}
else if( algo == GCRY_PK_RSA ) {
s_skey = SEXP_CONS( SEXP_NEW( "private-key", 0 ),
gcry_sexp_vlist( SEXP_NEW( "rsa", 0 ),
gcry_sexp_new_name_mpi( "n", skey[0] ),
gcry_sexp_new_name_mpi( "e", skey[1] ),
gcry_sexp_new_name_mpi( "d", skey[2] ),
gcry_sexp_new_name_mpi( "p", skey[3] ),
gcry_sexp_new_name_mpi( "q", skey[4] ),
gcry_sexp_new_name_mpi( "u", skey[5] ),
NULL ));
}
else
return G10ERR_PUBKEY_ALGO;
rc = gcry_pk_testkey( s_skey );
gcry_sexp_release( s_skey );
return rc;
}
static int
do_check( PKT_secret_key *sk )
{
byte *buffer;
u16 csum=0;
int i, res;
unsigned nbytes;
@ -141,7 +188,7 @@ do_check( PKT_secret_key *sk )
log_bug("gcry_mpi_scan failed in do_check: rc=%d\n", res);
csum += checksum_mpi( sk->skey[i] );
gcry_free( buffer );
gcry_free( data );
}
}
gcry_cipher_close( cipher_hd );
@ -152,7 +199,7 @@ do_check( PKT_secret_key *sk )
return G10ERR_BAD_PASS;
}
/* the checksum may fail, so we also check the key itself */
res = pubkey_check_secret_key( sk->pubkey_algo, sk->skey );
res = pk_check_secret_key( sk->pubkey_algo, sk->skey );
if( res ) {
copy_secret_key( sk, save_sk );
free_secret_key( save_sk );
@ -165,6 +212,7 @@ do_check( PKT_secret_key *sk )
csum = 0;
for(i=pubkey_get_npkey(sk->pubkey_algo);
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
assert( !gcry_mpi_get_flag( sk->skey[i], GCRYMPI_FLAG_OPAQUE ) );
csum += checksum_mpi( sk->skey[i] );
}
if( csum != sk->csum )

View File

@ -1,3 +1,7 @@
Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
* mpicoder.c (gcry_mpi_aprint): Now really returns the length.
Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
* mpiutil.c: Removed all memory debugging code.

View File

@ -608,6 +608,8 @@ gcry_mpi_aprint( enum gcry_mpi_format format, void **buffer, size_t *nbytes,
g10_free(*buffer);
*buffer = NULL;
}
else if( nbytes )
*nbytes = n;
return rc;
}