summaryrefslogtreecommitdiffstats
path: root/g10/seckey-cert.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2003-06-18 21:56:13 +0200
committerWerner Koch <wk@gnupg.org>2003-06-18 21:56:13 +0200
commitc0c2c58054923d506f61ce9a71d509b48a381211 (patch)
treea8f82bffb44eb68eb726ff6db41fa715bcd29193 /g10/seckey-cert.c
parentA small step for GnuPG but a huge leap for error codes. (diff)
downloadgnupg2-c0c2c58054923d506f61ce9a71d509b48a381211.tar.xz
gnupg2-c0c2c58054923d506f61ce9a71d509b48a381211.zip
Finished the bulk of changes for gnupg 1.9. This included switching
to libgcrypt functions, using shared error codes from libgpg-error, replacing the old functions we used to have in ../util by those in ../jnlib and ../common, renaming the malloc functions and a couple of types. Note, that not all changes are listed below becuause they are too similar and done at far too many places. As of today the code builds using the current libgcrypt from CVS but it is very unlikely that it actually works.
Diffstat (limited to 'g10/seckey-cert.c')
-rw-r--r--g10/seckey-cert.c209
1 files changed, 129 insertions, 80 deletions
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 76f0ee28d..573c78f7a 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -1,5 +1,6 @@
/* seckey-cert.c - secret key certificate packet handling
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -23,6 +24,8 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+
+#include "gpg.h"
#include "util.h"
#include "memory.h"
#include "packet.h"
@@ -33,7 +36,7 @@
#include "options.h"
#include "i18n.h"
#include "status.h"
-
+#include "pkglue.h"
static int
do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
@@ -43,6 +46,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
u16 csum=0;
int i, res;
unsigned nbytes;
+ gpg_error_t rc;
if( sk->is_protected ) { /* remove the protection */
DEK *dek = NULL;
@@ -52,11 +56,11 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
if( sk->protect.s2k.mode == 1001 ) {
log_info(_("secret key parts are not available\n"));
- return G10ERR_GENERAL;
+ return GPG_ERR_GENERAL;
}
if( sk->protect.algo == CIPHER_ALGO_NONE )
BUG();
- if( check_cipher_algo( sk->protect.algo ) ) {
+ if( openpgp_cipher_test_algo( sk->protect.algo ) ) {
log_info(_("protection algorithm %d%s is not supported\n"),
sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" );
if (sk->protect.algo==CIPHER_ALGO_IDEA)
@@ -64,7 +68,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
write_status (STATUS_RSA_OR_IDEA);
idea_cipher_warn (0);
}
- return G10ERR_CIPHER_ALGO;
+ return GPG_ERR_CIPHER_ALGO;
}
keyid_from_sk( sk, keyid );
keyid[2] = keyid[3] = 0;
@@ -76,28 +80,39 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
&sk->protect.s2k, mode,
tryagain_text, canceled );
if (!dek && canceled && *canceled)
- return G10ERR_GENERAL;
+ return GPG_ERR_GENERAL;
+
+ rc = gcry_cipher_open (&cipher_hd, sk->protect.algo,
+ GCRY_CIPHER_MODE_CFB,
+ GCRY_CIPHER_SECURE
+ | (sk->protect.algo >= 100 ?
+ 0 : GCRY_CIPHER_ENABLE_SYNC));
+ if (rc)
+ log_fatal ("cipher open failed: %s\n", gpg_strerror (rc) );
+
+ rc = gcry_cipher_setkey (cipher_hd, dek->key, dek->keylen);
+ if (rc)
+ log_fatal ("set key failed: %s\n", gpg_strerror (rc) );
- cipher_hd = cipher_open( sk->protect.algo,
- CIPHER_MODE_AUTO_CFB, 1);
- cipher_setkey( cipher_hd, dek->key, dek->keylen );
- m_free(dek);
+ xfree (dek);
save_sk = copy_secret_key( NULL, sk );
- cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
+ gcry_cipher_setiv (cipher_hd, sk->protect.iv, sk->protect.ivlen);
csum = 0;
if( sk->version >= 4 ) {
int ndata;
+ unsigned int ndatabits;
byte *p, *data;
u16 csumc = 0;
i = pubkey_get_npkey(sk->pubkey_algo);
- assert( mpi_is_opaque( sk->skey[i] ) );
- p = mpi_get_opaque( sk->skey[i], &ndata );
+ assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE ));
+ p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits );
+ ndata = (ndatabits+7)/8;
if ( ndata > 1 )
csumc = p[ndata-2] << 8 | p[ndata-1];
- data = m_alloc_secure( ndata );
- cipher_decrypt( cipher_hd, data, p, ndata );
- mpi_free( sk->skey[i] ); sk->skey[i] = NULL ;
+ data = gcry_xmalloc_secure ( ndata );
+ gcry_cipher_decrypt( cipher_hd, data, ndata, p, ndata );
+ gcry_mpi_release ( sk->skey[i] ); sk->skey[i] = NULL ;
p = data;
if (sk->protect.sha1chk) {
/* This is the new SHA1 checksum method to detect
@@ -108,12 +123,13 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
if( ndata < 20 )
log_error("not enough bytes for SHA-1 checksum\n");
else {
- MD_HANDLE h = md_open (DIGEST_ALGO_SHA1, 1);
- if (!h)
+ gcry_md_hd_t h;
+
+ if ( gcry_md_open (&h, DIGEST_ALGO_SHA1, 1))
BUG(); /* algo not available */
- md_write (h, data, ndata - 20);
- md_final (h);
- if (!memcmp (md_read (h, DIGEST_ALGO_SHA1),
+ gcry_md_write (h, data, ndata - 20);
+ gcry_md_final (h);
+ if (!memcmp (gcry_md_read (h, DIGEST_ALGO_SHA1),
data + ndata - 20, 20) ) {
/* digest does match. We have to keep the old
style checksum in sk->csum, so that the
@@ -122,7 +138,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
keys. */
sk->csum = csum = checksum (data, ndata-20);
}
- md_close (h);
+ gcry_md_close (h);
}
}
else {
@@ -146,56 +162,68 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
if( sk->csum == csum ) {
for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
nbytes = ndata;
- sk->skey[i] = mpi_read_from_buffer(p, &nbytes, 1 );
+ assert( gcry_is_secure( p ) );
+ res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
+ p, &nbytes);
+ if( res )
+ log_bug ("gcry_mpi_scan failed in do_check: %s\n",
+ gpg_strerror (res));
ndata -= nbytes;
p += nbytes;
}
/* Note: at this point ndata should be 2 for a simple
checksum or 20 for the sha1 digest */
}
- m_free(data);
+ xfree (data);
}
else {
for(i=pubkey_get_npkey(sk->pubkey_algo);
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
byte *p;
int ndata;
- unsigned int dummy;
+ unsigned int ndatabits;
- assert (mpi_is_opaque (sk->skey[i]));
- p = mpi_get_opaque (sk->skey[i], &ndata);
+ assert( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
+ p = gcry_mpi_get_opaque( sk->skey[i], &ndatabits );
+ ndata = (ndatabits+7)/8;
assert (ndata >= 2);
assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2);
- buffer = m_alloc_secure (ndata);
- cipher_sync (cipher_hd);
+ buffer = gcry_xmalloc_secure (ndata);
+ gcry_cipher_sync (cipher_hd);
buffer[0] = p[0];
buffer[1] = p[1];
- cipher_decrypt (cipher_hd, buffer+2, p+2, ndata-2);
+ gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2,
+ p+2, ndata-2);
csum += checksum (buffer, ndata);
- mpi_free (sk->skey[i]);
- dummy = ndata;
- sk->skey[i] = mpi_read_from_buffer (buffer, &dummy, 1);
+ gcry_mpi_release (sk->skey[i]);
+ res = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_USG,
+ buffer, &ndata );
+ if( res )
+ log_bug ("gcry_mpi_scan failed in do_check: %s\n",
+ gpg_strerror (res));
+
assert (sk->skey[i]);
- m_free (buffer);
+ xfree (buffer);
/* csum += checksum_mpi (sk->skey[i]); */
}
}
- cipher_close( cipher_hd );
+ gcry_cipher_close (cipher_hd);
/* now let's see whether we have used the right passphrase */
if( csum != sk->csum ) {
copy_secret_key( sk, save_sk );
passphrase_clear_cache ( keyid, sk->pubkey_algo );
free_secret_key( save_sk );
- return G10ERR_BAD_PASS;
+ return gpg_error (GPG_ERR_BAD_PASSPHRASE);
}
/* the checksum may fail, so we also check the key itself */
- res = pubkey_check_secret_key( sk->pubkey_algo, sk->skey );
- if( res ) {
- copy_secret_key( sk, save_sk );
- passphrase_clear_cache ( keyid, sk->pubkey_algo );
- free_secret_key( save_sk );
- return G10ERR_BAD_PASS;
- }
+#warning fixme - we need to reenable this
+/* res = pubkey_check_secret_key( sk->pubkey_algo, sk->skey ); */
+/* if( res ) { */
+/* copy_secret_key( sk, save_sk ); */
+/* passphrase_clear_cache ( keyid, sk->pubkey_algo ); */
+/* free_secret_key( save_sk ); */
+/* return gpg_error (GPG_ERR_BAD_PASSPHRASE); */
+/* } */
free_secret_key( save_sk );
sk->is_protected = 0;
}
@@ -206,7 +234,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
csum += checksum_mpi( sk->skey[i] );
}
if( csum != sk->csum )
- return G10ERR_CHECKSUM;
+ return GPG_ERR_CHECKSUM;
}
return 0;
@@ -222,7 +250,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
int
check_secret_key( PKT_secret_key *sk, int n )
{
- int rc = G10ERR_BAD_PASS;
+ int rc = gpg_error (GPG_ERR_BAD_PASSPHRASE);
int i,mode;
if(n<0)
@@ -236,7 +264,7 @@ check_secret_key( PKT_secret_key *sk, int n )
if( n < 1 )
n = (opt.batch && !opt.use_agent)? 1 : 3; /* use the default value */
- for(i=0; i < n && rc == G10ERR_BAD_PASS; i++ ) {
+ for(i=0; i < n && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE; i++ ) {
int canceled = 0;
const char *tryagain = NULL;
if (i) {
@@ -244,7 +272,8 @@ check_secret_key( PKT_secret_key *sk, int n )
log_info (_("%s ...\n"), _(tryagain));
}
rc = do_check( sk, tryagain, mode, &canceled );
- if( rc == G10ERR_BAD_PASS && is_status_enabled() ) {
+ if( gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
+ && is_status_enabled() ) {
u32 kid[2];
char buf[50];
@@ -291,21 +320,31 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
if( !sk->is_protected ) { /* okay, apply the protection */
CIPHER_HANDLE cipher_hd=NULL;
- if( check_cipher_algo( sk->protect.algo ) )
- rc = G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */
+ if( openpgp_cipher_test_algo( sk->protect.algo ) )
+ {
+ rc = gpg_error (GPG_ERR_CIPHER_ALGO); /* unsupport
+ protection
+ algorithm */
+ }
else {
print_cipher_algo_note( sk->protect.algo );
- cipher_hd = cipher_open( sk->protect.algo,
- CIPHER_MODE_AUTO_CFB, 1 );
- if( cipher_setkey( cipher_hd, dek->key, dek->keylen ) )
+ rc = gcry_cipher_open (&cipher_hd, sk->protect.algo,
+ GCRY_CIPHER_MODE_CFB,
+ GCRY_CIPHER_SECURE
+ | (sk->protect.algo >= 100 ?
+ 0 : GCRY_CIPHER_ENABLE_SYNC) );
+ if (rc)
+ BUG();
+ if( gcry_cipher_setkey( cipher_hd, dek->key, dek->keylen ) )
log_info(_("WARNING: Weak key detected"
" - please change passphrase again.\n"));
- sk->protect.ivlen = cipher_get_blocksize( sk->protect.algo );
+ sk->protect.ivlen = gcry_cipher_get_algo_blklen(sk->protect.algo);
assert( sk->protect.ivlen <= DIM(sk->protect.iv) );
if( sk->protect.ivlen != 8 && sk->protect.ivlen != 16 )
BUG(); /* yes, we are very careful */
- randomize_buffer(sk->protect.iv, sk->protect.ivlen, 1);
- cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
+ gcry_randomize (sk->protect.iv, sk->protect.ivlen,
+ GCRY_STRONG_RANDOM);
+ gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
if( sk->version >= 4 ) {
byte *bufarr[PUBKEY_MAX_NSKEY];
unsigned narr[PUBKEY_MAX_NSKEY];
@@ -315,16 +354,21 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
for(j=0, i = pubkey_get_npkey(sk->pubkey_algo);
i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ ) {
- assert( !mpi_is_opaque( sk->skey[i] ) );
- bufarr[j] = mpi_get_buffer( sk->skey[i], &narr[j], NULL );
- nbits[j] = mpi_get_nbits( sk->skey[i] );
+ assert( !gcry_mpi_get_flag( sk->skey[i],
+ GCRYMPI_FLAG_OPAQUE ));
+
+ if( gcry_mpi_aprint( GCRYMPI_FMT_USG, (void**)bufarr+j,
+ narr+j, sk->skey[i]))
+ BUG();
+
+ nbits[j] = gcry_mpi_get_nbits( sk->skey[i] );
ndata += narr[j] + 2;
}
for( ; j < PUBKEY_MAX_NSKEY; j++ )
bufarr[j] = NULL;
ndata += opt.simple_sk_checksum? 2 : 20; /* for checksum */
- data = m_alloc_secure( ndata );
+ data = xmalloc_secure ( ndata );
p = data;
for(j=0; j < PUBKEY_MAX_NSKEY && bufarr[j]; j++ ) {
p[0] = nbits[j] >> 8 ;
@@ -332,7 +376,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
p += 2;
memcpy(p, bufarr[j], narr[j] );
p += narr[j];
- m_free(bufarr[j]);
+ xfree (bufarr[j]);
}
if (opt.simple_sk_checksum) {
@@ -345,27 +389,28 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
sk->protect.sha1chk = 0;
}
else {
- MD_HANDLE h = md_open (DIGEST_ALGO_SHA1, 1);
- if (!h)
+ gcry_md_hd_t h;
+
+ if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
BUG(); /* algo not available */
- md_write (h, data, ndata - 20);
- md_final (h);
- memcpy (p, md_read (h, DIGEST_ALGO_SHA1), 20);
+ gcry_md_write (h, data, ndata - 20);
+ gcry_md_final (h);
+ memcpy (p, gcry_md_read (h, GCRY_MD_SHA1), 20);
p += 20;
- md_close (h);
+ gcry_md_close (h);
sk->csum = csum = 0;
sk->protect.sha1chk = 1;
}
assert( p == data+ndata );
- cipher_encrypt( cipher_hd, data, data, ndata );
+ gcry_cipher_encrypt( cipher_hd, data, ndata, NULL, 0 );
for(i = pubkey_get_npkey(sk->pubkey_algo);
i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
- mpi_free( sk->skey[i] );
+ gcry_mpi_release ( sk->skey[i] );
sk->skey[i] = NULL;
}
i = pubkey_get_npkey(sk->pubkey_algo);
- sk->skey[i] = mpi_set_opaque(NULL, data, ndata );
+ sk->skey[i] = gcry_mpi_set_opaque(NULL, data, ndata*8);
}
else {
csum = 0;
@@ -375,26 +420,30 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
unsigned int nbits;
csum += checksum_mpi (sk->skey[i]);
- buffer = mpi_get_buffer( sk->skey[i], &nbytes, NULL );
- cipher_sync (cipher_hd);
- assert ( !mpi_is_opaque (sk->skey[i]) );
- data = m_alloc (nbytes+2);
- nbits = mpi_get_nbits (sk->skey[i]);
+ if( gcry_mpi_aprint( GCRYMPI_FMT_USG, &buffer,
+ &nbytes, sk->skey[i] ) )
+ BUG();
+ gcry_cipher_sync (cipher_hd);
+ assert (!gcry_mpi_get_flag( sk->skey[i],
+ GCRYMPI_FLAG_OPAQUE ));
+ data = xmalloc (nbytes+2);
+ nbits = gcry_mpi_get_nbits (sk->skey[i]);
assert (nbytes == (nbits + 7)/8);
data[0] = nbits >> 8;
data[1] = nbits;
- cipher_encrypt (cipher_hd, data+2, buffer, nbytes);
- m_free( buffer );
+ gcry_cipher_encrypt (cipher_hd, data+2, nbytes,
+ buffer, nbytes);
+ xfree ( buffer );
- mpi_free (sk->skey[i]);
- sk->skey[i] = mpi_set_opaque (NULL, data, nbytes+2);
+ gcry_mpi_release (sk->skey[i]);
+ sk->skey[i] = gcry_mpi_set_opaque (NULL, data,
+ (nbytes+2)*8);
}
sk->csum = csum;
}
sk->is_protected = 1;
- cipher_close( cipher_hd );
+ gcry_cipher_close( cipher_hd );
}
}
return rc;
}
-