From db43afc923f32d39d06c20c1d4fb698cbad0897c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 24 Jan 2000 21:14:42 +0000 Subject: [PATCH] See ChangeLog: Mon Jan 24 22:24:38 CET 2000 Werner Koch --- cipher/ChangeLog | 11 ++ cipher/pubkey.c | 264 +++++++++++++++++++++++++++++++++++++++++---- g10/ChangeLog | 13 +++ g10/encode.c | 50 ++++++++- g10/g10.c | 2 +- g10/keygen.c | 8 +- g10/misc.c | 3 +- g10/parse-packet.c | 5 +- g10/pubkey-enc.c | 70 +++++++++++- g10/seckey-cert.c | 54 +++++++++- mpi/ChangeLog | 4 + mpi/mpicoder.c | 2 + 12 files changed, 454 insertions(+), 32 deletions(-) diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 33b04e4f2..5925a0419 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,14 @@ +Mon Jan 24 22:24:38 CET 2000 Werner Koch + + * 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 * pubkey.c (pubkey_nbits): Removed and replaced by ... diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 949e3b9ca..4def6f699 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -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 = () + * s_pkey = + * r_ciph = (enc-val + * ( + * ( ) + * ... + * ( ) + * )) + */ 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 + * ( + * ( ) + * ... + * ( ) + * )) + * s_skey = + * r_plain= () 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 = + */ +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 diff --git a/g10/ChangeLog b/g10/ChangeLog index e73bae4c1..537b48ede 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,16 @@ +Mon Jan 24 22:24:38 CET 2000 Werner Koch + + * 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 * misc.c (mpi_print): Use gcry_mpi_aprint. diff --git a/g10/encode.c b/g10/encode.c index e4d701e30..736eba6f6 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -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) ); diff --git a/g10/g10.c b/g10/g10.c index 192ac4ae4..b619a2dcc 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -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; diff --git a/g10/keygen.c b/g10/keygen.c index 805160696..70590bc89 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -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; diff --git a/g10/misc.c b/g10/misc.c index 1c311a6c0..d3c01f4ef 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -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 ); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index dffb874b0..71fa19ed5 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -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); diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 925b5a4d0..70e4bc6c1 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -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 ) ) diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index 10f7092d2..88ec69389 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -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 ) diff --git a/mpi/ChangeLog b/mpi/ChangeLog index 2d2ec8bdb..9465aa513 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -1,3 +1,7 @@ +Mon Jan 24 22:24:38 CET 2000 Werner Koch + + * mpicoder.c (gcry_mpi_aprint): Now really returns the length. + Mon Jan 24 13:04:28 CET 2000 Werner Koch * mpiutil.c: Removed all memory debugging code. diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c index ca805f28b..bd79aca5d 100644 --- a/mpi/mpicoder.c +++ b/mpi/mpicoder.c @@ -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; }